Update SMACK, Fix a crash of terminating sequence, etc, ...
[apps/livebox/data-provider-master.git] / src / slave_life.c
1 /*
2  * Copyright 2013  Samsung Electronics Co., Ltd
3  *
4  * Licensed under the Flora License, Version 1.1 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://floralicense.org/license/
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <stdio.h>
18 #include <string.h> /* strerror */
19 #include <errno.h> /* errno */
20 #include <unistd.h> /* pid_t */
21 #include <stdlib.h> /* free */
22 #include <pthread.h>
23 #include <malloc.h>
24 #include <sys/time.h>
25
26 #include <Eina.h>
27 #include <Ecore.h>
28
29 #include <aul.h> /* aul_launch_app */
30 #include <dlog.h>
31 #include <bundle.h>
32
33 #include <packet.h>
34 #include <livebox-errno.h>
35
36 #include "critical_log.h"
37 #include "slave_life.h"
38 #include "slave_rpc.h"
39 #include "client_life.h"
40 #include "fault_manager.h"
41 #include "debug.h"
42 #include "conf.h"
43 #include "setting.h"
44 #include "util.h"
45 #include "abi.h"
46 #include "xmonitor.h"
47
48 int errno;
49
50 struct slave_node {
51         char *name;
52         char *abi;
53         char *pkgname;
54         int secured;    /* Only A package(livebox) is loaded for security requirements */
55         int refcnt;
56         int fault_count;
57         int critical_fault_count;
58         enum slave_state state;
59         int network;
60
61         int loaded_instance;
62         int loaded_package;
63
64         int reactivate_instances;
65         int reactivate_slave;
66
67         pid_t pid;
68
69         Eina_List *event_activate_list;
70         Eina_List *event_deactivate_list;
71         Eina_List *event_delete_list;
72         Eina_List *event_fault_list;
73         Eina_List *event_pause_list;
74         Eina_List *event_resume_list;
75
76         Eina_List *data_list;
77
78         Ecore_Timer *ttl_timer; /* Time to live */
79         Ecore_Timer *activate_timer; /* Waiting hello packet for this time */
80
81         struct timeval activated_at;
82 };
83
84 struct event {
85         struct slave_node *slave;
86
87         int (*evt_cb)(struct slave_node *, void *);
88         void *cbdata;
89 };
90
91 struct priv_data {
92         char *tag;
93         void *data;
94 };
95
96 static struct {
97         Eina_List *slave_list;
98 } s_info = {
99         .slave_list = NULL,
100 };
101
102 static Eina_Bool slave_ttl_cb(void *data)
103 {
104         struct slave_node *slave = (struct slave_node *)data;
105
106         /*!
107          * \note
108          * ttl_timer must has to be set to NULL before deactivate the slave
109          * It will be used for making decision of the expired TTL timer or the fault of a livebox.
110          */
111         slave->ttl_timer = NULL;
112
113         slave_set_reactivation(slave, 0);
114         slave_set_reactivate_instances(slave, 1);
115
116         slave = slave_deactivate(slave);
117         DbgPrint("Slave is deactivated(%p)\n", slave);
118
119         /*! To recover all instances state it is activated again */
120         return ECORE_CALLBACK_CANCEL;
121 }
122
123 static inline int xmonitor_pause_cb(void *data)
124 {
125         slave_pause(data);
126         return LB_STATUS_SUCCESS;
127 }
128
129 static inline int xmonitor_resume_cb(void *data)
130 {
131         slave_resume(data);
132         return LB_STATUS_SUCCESS;
133 }
134
135 static inline struct slave_node *create_slave_node(const char *name, int is_secured, const char *abi, const char *pkgname, int network)
136 {
137         struct slave_node *slave;
138
139         slave = calloc(1, sizeof(*slave));
140         if (!slave) {
141                 ErrPrint("Heap: %s\n", strerror(errno));
142                 return NULL;
143         }
144
145         slave->name = strdup(name);
146         if (!slave->name) {
147                 ErrPrint("Heap: %s\n", strerror(errno));
148                 DbgFree(slave);
149                 return NULL;
150         }
151
152         slave->abi = strdup(abi);
153         if (!slave->abi) {
154                 ErrPrint("Heap: %s\n", strerror(errno));
155                 DbgFree(slave->name);
156                 DbgFree(slave);
157                 return NULL;
158         }
159
160         slave->pkgname = strdup(pkgname);
161         if (!slave->pkgname) {
162                 ErrPrint("Heap: %s\n", strerror(errno));
163                 DbgFree(slave->abi);
164                 DbgFree(slave->name);
165                 DbgFree(slave);
166                 return NULL;
167         }
168
169         slave->secured = is_secured;
170         slave->pid = (pid_t)-1;
171         slave->state = SLAVE_TERMINATED;
172         slave->network = network;
173
174         xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_pause_cb, slave);
175         xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resume_cb, slave);
176
177         s_info.slave_list = eina_list_append(s_info.slave_list, slave);
178         return slave;
179 }
180
181 static inline void invoke_delete_cb(struct slave_node *slave)
182 {
183         Eina_List *l;
184         Eina_List *n;
185         struct event *event;
186         int ret;
187
188         EINA_LIST_FOREACH_SAFE(slave->event_delete_list, l, n, event) {
189                 ret = event->evt_cb(event->slave, event->cbdata);
190                 if (ret < 0) {
191                         if (eina_list_data_find(slave->event_delete_list, event)) {
192                                 slave->event_delete_list = eina_list_remove(slave->event_delete_list, event);
193                                 DbgFree(event);
194                         }
195                 }
196         }
197 }
198
199 static inline void destroy_slave_node(struct slave_node *slave)
200 {
201         struct event *event;
202         struct priv_data *priv;
203
204         if (slave_pid(slave) != (pid_t)-1) {
205                 ErrPrint("Slave is not deactivated\n");
206                 return;
207         }
208
209         xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_pause_cb, slave);
210         xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resume_cb, slave);
211
212         invoke_delete_cb(slave);
213         slave_rpc_fini(slave); /*!< Finalize the RPC after handling all delete callbacks */
214
215         EINA_LIST_FREE(slave->event_delete_list, event) {
216                 DbgFree(event);
217         }
218
219         EINA_LIST_FREE(slave->event_activate_list, event) {
220                 DbgFree(event);
221         }
222
223         EINA_LIST_FREE(slave->event_deactivate_list, event) {
224                 DbgFree(event);
225         }
226
227         EINA_LIST_FREE(slave->event_fault_list, event) {
228                 DbgFree(event);
229         }
230
231         EINA_LIST_FREE(slave->data_list, priv) {
232                 DbgFree(priv->tag);
233                 DbgFree(priv);
234         }
235
236         s_info.slave_list = eina_list_remove(s_info.slave_list, slave);
237
238         if (slave->ttl_timer)
239                 ecore_timer_del(slave->ttl_timer);
240
241         if (slave->activate_timer)
242                 ecore_timer_del(slave->activate_timer);
243
244         DbgFree(slave->abi);
245         DbgFree(slave->name);
246         DbgFree(slave->pkgname);
247         DbgFree(slave);
248         return;
249 }
250
251 static inline struct slave_node *find_slave(const char *name)
252 {
253         struct slave_node *slave;
254         Eina_List *l;
255
256         EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
257                 if (!strcmp(slave->name, name))
258                         return slave;
259         }
260         
261         return NULL;
262 }
263
264 HAPI int slave_expired_ttl(struct slave_node *slave)
265 {
266         if (!slave)
267                 return 0;
268
269         if (!slave->secured)
270                 return 0;
271
272         return !!slave->ttl_timer;
273 }
274
275 HAPI struct slave_node *slave_ref(struct slave_node *slave)
276 {
277         if (!slave)
278                 return NULL;
279
280         slave->refcnt++;
281         return slave;
282 }
283
284 HAPI struct slave_node *slave_unref(struct slave_node *slave)
285 {
286         if (!slave)
287                 return NULL;
288
289         if (slave->refcnt == 0) {
290                 ErrPrint("Slave refcnt is not valid\n");
291                 return NULL;
292         }
293
294         slave->refcnt--;
295         if (slave->refcnt == 0) {
296                 destroy_slave_node(slave);
297                 slave = NULL;
298         }
299
300         return slave;
301 }
302
303 HAPI const int const slave_refcnt(struct slave_node *slave)
304 {
305         return slave->refcnt;
306 }
307
308 HAPI struct slave_node *slave_create(const char *name, int is_secured, const char *abi, const char *pkgname, int network)
309 {
310         struct slave_node *slave;
311
312         slave = find_slave(name);
313         if (slave) {
314                 if (slave->secured != is_secured)
315                         ErrPrint("Exists slave and creating slave's security flag is not matched\n");
316                 return slave;
317         }
318
319         slave = create_slave_node(name, is_secured, abi, pkgname, network);
320         if (!slave)
321                 return NULL;
322
323         slave_ref(slave);
324         slave_rpc_init(slave);
325
326         return slave;
327 }
328
329 /*!
330  * \note
331  * Before destroying slave object,
332  * you should check the RPC(slave_async_XXX) state and Private data field (slave_set_data)
333  */
334 HAPI void slave_destroy(struct slave_node *slave)
335 {
336         slave_unref(slave);
337 }
338
339 static inline void invoke_fault_cb(struct slave_node *slave)
340 {
341         Eina_List *l;
342         Eina_List *n;
343         struct event *event;
344         int ret;
345
346         EINA_LIST_FOREACH_SAFE(slave->event_fault_list, l, n, event) {
347                 ret = event->evt_cb(event->slave, event->cbdata);
348                 if (ret < 0) {
349                         if (eina_list_data_find(slave->event_fault_list, event)) {
350                                 slave->event_fault_list = eina_list_remove(slave->event_fault_list, event);
351                                 DbgFree(event);
352                         }
353                 }
354         }
355 }
356
357 static inline void invoke_activate_cb(struct slave_node *slave)
358 {
359         Eina_List *l;
360         Eina_List *n;
361         struct event *event;
362         int ret;
363
364         EINA_LIST_FOREACH_SAFE(slave->event_activate_list, l, n, event) {
365                 ret = event->evt_cb(event->slave, event->cbdata);
366                 if (ret < 0) {
367                         if (eina_list_data_find(slave->event_activate_list, event)) {
368                                 slave->event_activate_list = eina_list_remove(slave->event_activate_list, event);
369                                 DbgFree(event);
370                         }
371                 }
372         }
373 }
374
375 static Eina_Bool activate_timer_cb(void *data)
376 {
377         struct slave_node *slave = data;
378
379         slave->fault_count++;
380         invoke_fault_cb(slave);
381
382         slave_set_reactivation(slave, 0);
383         slave_set_reactivate_instances(slave, 0);
384
385         slave->activate_timer = NULL;
386         if (slave_pid(slave) > 0) {
387                 int ret;
388                 DbgPrint("Try to terminate PID: %d\n", slave_pid(slave));
389                 ret = aul_terminate_pid(slave_pid(slave));
390                 if (ret < 0)
391                         ErrPrint("Terminate failed, pid %d (reason: %d)\n", slave_pid(slave), ret);
392         }
393
394         CRITICAL_LOG("Slave is not activated in %lf sec (slave: %s)\n", SLAVE_ACTIVATE_TIME, slave_name(slave));
395         slave = slave_deactivated(slave);
396         return ECORE_CALLBACK_CANCEL;
397 }
398
399 HAPI int slave_activate(struct slave_node *slave)
400 {
401         /*!
402          * \note
403          * This check code can be replaced with the slave->state check code
404          * If the slave data has the PID, it means, it is activated
405          * Even if it is in the termiating sequence, it will have the PID
406          * before terminated at last.
407          * So we can use this simple code for checking the slave's last state.
408          * about it is alive? or not.
409          */
410         if (slave_pid(slave) != (pid_t)-1) {
411                 if (slave_state(slave) == SLAVE_REQUEST_TO_TERMINATE)
412                         slave_set_reactivation(slave, 1);
413                 return LB_STATUS_ERROR_ALREADY;
414         } else if (slave_state(slave) == SLAVE_REQUEST_TO_LAUNCH) {
415                 DbgPrint("Slave is already launched: but the AUL is timed out\n");
416                 return LB_STATUS_ERROR_ALREADY;
417         }
418
419         if (DEBUG_MODE) {
420                 DbgPrint("Debug Mode enabled. name[%s] secured[%d] abi[%s]\n", slave_name(slave), slave->secured, slave->abi);
421         } else {
422                 bundle *param;
423
424                 param = bundle_create();
425                 if (!param) {
426                         ErrPrint("Failed to create a bundle\n");
427                         return LB_STATUS_ERROR_FAULT;
428                 }
429
430                 bundle_add(param, BUNDLE_SLAVE_NAME, slave_name(slave));
431                 bundle_add(param, BUNDLE_SLAVE_SECURED, slave->secured ? "true" : "false");
432                 bundle_add(param, BUNDLE_SLAVE_ABI, slave->abi);
433
434                 slave->pid = (pid_t)aul_launch_app(slave_pkgname(slave), param);
435
436                 bundle_free(param);
437
438                 if (slave->pid < 0) {
439                         CRITICAL_LOG("Failed to launch a new slave %s (%d)\n", slave_name(slave), slave->pid);
440                         if (slave->pid != AUL_R_ETIMEOUT && slave->pid != AUL_R_ECOMM) {
441                                 ErrPrint("failed, because of %d\n", slave->pid);
442                                 slave->pid = (pid_t)-1;
443                                 return LB_STATUS_ERROR_FAULT;
444                         } else {
445                                 ErrPrint("But waiting \"hello\"\n");
446                                 slave->pid = (pid_t)-1;
447                         }
448                 }
449                 DbgPrint("Slave %s is launched with %d as %s\n", slave_pkgname(slave), slave->pid, slave_name(slave));
450
451                 slave->activate_timer = ecore_timer_add(SLAVE_ACTIVATE_TIME, activate_timer_cb, slave);
452                 if (!slave->activate_timer)
453                         ErrPrint("Failed to register an activate timer\n");
454         }
455
456         slave->state = SLAVE_REQUEST_TO_LAUNCH;
457         /*!
458          * \note
459          * Increase the refcnt of a slave,
460          * To prevent from making an orphan(slave).
461          */
462         (void)slave_ref(slave);
463
464         return LB_STATUS_SUCCESS;
465 }
466
467 HAPI int slave_give_more_ttl(struct slave_node *slave)
468 {
469         double delay;
470
471         if (!slave->secured || !slave->ttl_timer)
472                 return LB_STATUS_ERROR_INVALID;
473
474         delay = SLAVE_TTL - ecore_timer_pending_get(slave->ttl_timer);
475         ecore_timer_delay(slave->ttl_timer, delay);
476         return LB_STATUS_SUCCESS;
477 }
478
479 HAPI int slave_freeze_ttl(struct slave_node *slave)
480 {
481         if (!slave->secured || !slave->ttl_timer)
482                 return LB_STATUS_ERROR_INVALID;
483
484         ecore_timer_freeze(slave->ttl_timer);
485         return LB_STATUS_SUCCESS;
486 }
487
488 HAPI int slave_thaw_ttl(struct slave_node *slave)
489 {
490         double delay;
491
492         if (!slave->secured || !slave->ttl_timer)
493                 return LB_STATUS_ERROR_INVALID;
494
495         ecore_timer_thaw(slave->ttl_timer);
496
497         delay = SLAVE_TTL - ecore_timer_pending_get(slave->ttl_timer);
498         ecore_timer_delay(slave->ttl_timer, delay);
499         return LB_STATUS_SUCCESS;
500 }
501
502 HAPI int slave_activated(struct slave_node *slave)
503 {
504         slave->state = SLAVE_RESUMED;
505
506         if (xmonitor_is_paused())
507                 slave_pause(slave);
508
509         if (slave->secured == 1) {
510                 DbgPrint("Slave deactivation timer is added (%s - %lf)\n", slave_name(slave), SLAVE_TTL);
511                 slave->ttl_timer = ecore_timer_add(SLAVE_TTL, slave_ttl_cb, slave);
512                 if (!slave->ttl_timer)
513                         ErrPrint("Failed to create a TTL timer\n");
514         }
515
516         invoke_activate_cb(slave);
517
518         slave_set_reactivation(slave, 0);
519         slave_set_reactivate_instances(slave, 0);
520
521         if (gettimeofday(&slave->activated_at, NULL) < 0) {
522                 ErrPrint("Failed to get time of day: %s\n", strerror(errno));
523                 slave->activated_at.tv_sec = 0;
524                 slave->activated_at.tv_usec = 0;
525         }
526
527         if (slave->activate_timer) {
528                 ecore_timer_del(slave->activate_timer);
529                 slave->activate_timer = NULL;
530         }
531
532         return LB_STATUS_SUCCESS;
533 }
534
535 static inline int invoke_deactivate_cb(struct slave_node *slave)
536 {
537         Eina_List *l;
538         Eina_List *n;
539         struct event *event;
540         int ret;
541         int reactivate = 0;
542
543         EINA_LIST_FOREACH_SAFE(slave->event_deactivate_list, l, n, event) {
544                 ret = event->evt_cb(event->slave, event->cbdata);
545                 if (ret < 0) {
546                         if (eina_list_data_find(slave->event_deactivate_list, event)) {
547                                 slave->event_deactivate_list = eina_list_remove(slave->event_deactivate_list, event);
548                                 DbgFree(event);
549                         }
550                 } else if (ret == SLAVE_NEED_TO_REACTIVATE) {
551                         reactivate++;
552                 }
553         }
554
555         return reactivate;
556 }
557
558 HAPI struct slave_node *slave_deactivate(struct slave_node *slave)
559 {
560         int ret;
561
562         if (!slave_is_activated(slave)) {
563                 ErrPrint("Slave is already deactivated\n");
564                 if (slave_loaded_instance(slave) == 0) {
565                         /*!
566                          * \note
567                          * If a slave has no more instances,
568                          * Destroy it
569                          */
570                         slave = slave_unref(slave);
571                 }
572                 return slave;
573         }
574
575         /*!
576          * \todo
577          * check the return value of the aul_terminate_pid
578          */
579         slave->state = SLAVE_REQUEST_TO_TERMINATE;
580
581         if (slave_pid(slave) > 0) {
582                 DbgPrint("Terminate slave: %d (%s)\n", slave_pid(slave), slave_name(slave));
583                 ret = aul_terminate_pid(slave->pid);
584                 if (ret < 0) {
585                         ErrPrint("Terminate slave(%s) failed. pid %d (%d)\n", slave_name(slave), slave_pid(slave), ret);
586                         slave = slave_deactivated(slave);
587                 }
588         }
589
590         return slave;
591 }
592
593 HAPI struct slave_node *slave_deactivated(struct slave_node *slave)
594 {
595         int reactivate;
596
597         slave->pid = (pid_t)-1;
598         slave->state = SLAVE_TERMINATED;
599
600         if (slave->ttl_timer) {
601                 ecore_timer_del(slave->ttl_timer);
602                 slave->ttl_timer = NULL;
603         }
604
605         if (slave->activate_timer) {
606                 ecore_timer_del(slave->activate_timer);
607                 slave->activate_timer = NULL;
608         }
609
610         reactivate = invoke_deactivate_cb(slave);
611
612         slave = slave_unref(slave);
613         if (!slave) {
614                 DbgPrint("SLAVE object is destroyed\n");
615                 return slave;
616         }
617
618         if (reactivate && slave_need_to_reactivate(slave)) {
619                 int ret;
620
621                 DbgPrint("Need to reactivate a slave\n");
622                 ret = slave_activate(slave);
623                 if (ret < 0 && ret != LB_STATUS_ERROR_ALREADY)
624                         ErrPrint("Failed to reactivate a slave\n");
625         } else if (slave_loaded_instance(slave) == 0) {
626                 /*!
627                  * \note
628                  * If a slave has no more instances,
629                  * Destroy it
630                  */
631                 slave = slave_unref(slave);
632         }
633
634         return slave;
635 }
636
637 HAPI struct slave_node *slave_deactivated_by_fault(struct slave_node *slave)
638 {
639         int ret;
640         struct timeval faulted_at;
641         int reactivate = 1;
642         int reactivate_instances = 1;
643
644         if (!slave_is_activated(slave)) {
645                 DbgPrint("Deactivating in progress\n");
646                 if (slave_loaded_instance(slave) == 0)
647                         slave = slave_unref(slave);
648
649                 return slave;
650         }
651
652         slave->fault_count++;
653
654         (void)fault_check_pkgs(slave);
655
656         if (slave_pid(slave) > 0) {
657                 DbgPrint("Try to terminate PID: %d\n", slave_pid(slave));
658                 ret = aul_terminate_pid(slave_pid(slave));
659                 if (ret < 0) {
660                         ErrPrint("Terminate failed, pid %d\n", slave_pid(slave));
661                 }
662         }
663
664         if (gettimeofday(&faulted_at, NULL) == 0) {
665                 struct timeval rtv;
666
667                 timersub(&faulted_at, &slave->activated_at, &rtv);
668                 if (rtv.tv_sec < MINIMUM_REACTIVATION_TIME) {
669                         slave->critical_fault_count++;
670                         if (!slave_loaded_instance(slave) || slave->critical_fault_count >= SLAVE_MAX_LOAD) {
671                                 ErrPrint("Reactivation time is too fast and frequently occurred - Stop to auto reactivation\n");
672                                 reactivate = 0;
673                                 reactivate_instances = 0;
674                                 slave->critical_fault_count = 0;
675                                 /*!
676                                  * \note
677                                  * Fault callback can access the slave information.
678                                  */
679                                 invoke_fault_cb(slave);
680                         }
681                 } else {
682                         slave->critical_fault_count = 0;
683                 }
684         } else {
685                 ErrPrint("Failed to get time of day: %s\n", strerror(errno));
686         }
687
688         slave_set_reactivation(slave, reactivate);
689         slave_set_reactivate_instances(slave, reactivate_instances);
690
691         slave = slave_deactivated(slave);
692         return slave;
693 }
694
695 HAPI const int const slave_is_activated(struct slave_node *slave)
696 {
697         switch (slave->state) {
698         case SLAVE_REQUEST_TO_TERMINATE:
699         case SLAVE_TERMINATED:
700                 return 0;
701         case SLAVE_REQUEST_TO_LAUNCH:
702                  /* Not yet launched. but the slave incurred an unexpected error */
703         case SLAVE_REQUEST_TO_PAUSE:
704         case SLAVE_REQUEST_TO_RESUME:
705         case SLAVE_PAUSED:
706         case SLAVE_RESUMED:
707                 return 1;
708         default:
709                 return slave->pid != (pid_t)-1;
710         }
711
712         /* Could not be reach to here */
713         return 0;
714 }
715
716 HAPI int slave_event_callback_add(struct slave_node *slave, enum slave_event event, int (*cb)(struct slave_node *, void *), void *data)
717 {
718         struct event *ev;
719
720         ev = calloc(1, sizeof(*ev));
721         if (!ev) {
722                 ErrPrint("Heap: %s\n", strerror(errno));
723                 return LB_STATUS_ERROR_MEMORY;
724         }
725
726         ev->slave = slave;
727         ev->cbdata = data;
728         ev->evt_cb = cb;
729
730         /*!
731          * \note
732          * Use the eina_list_prepend API.
733          * To keep the sequence of a callback invocation.
734          *
735          * Here is an example sequence.
736          *
737          * slave_event_callback_add(CALLBACK_01);
738          * slave_event_callback_add(CALLBACK_02);
739          * slave_event_callback_add(CALLBACK_03);
740          *
741          * Then the invoke_event_callback function will call the CALLBACKS as below sequence
742          *
743          * invoke_CALLBACK_03
744          * invoke_CALLBACK_02
745          * invoke_CALLBACK_01
746          */
747
748         switch (event) {
749         case SLAVE_EVENT_ACTIVATE:
750                 slave->event_activate_list = eina_list_prepend(slave->event_activate_list, ev);
751                 break;
752         case SLAVE_EVENT_DELETE:
753                 slave->event_delete_list = eina_list_prepend(slave->event_delete_list, ev);
754                 break;
755         case SLAVE_EVENT_DEACTIVATE:
756                 slave->event_deactivate_list = eina_list_prepend(slave->event_deactivate_list, ev);
757                 break;
758         case SLAVE_EVENT_PAUSE:
759                 slave->event_pause_list = eina_list_prepend(slave->event_pause_list, ev);
760                 break;
761         case SLAVE_EVENT_RESUME:
762                 slave->event_resume_list = eina_list_prepend(slave->event_resume_list, ev);
763                 break;
764         case SLAVE_EVENT_FAULT:
765                 slave->event_fault_list = eina_list_prepend(slave->event_fault_list, ev);
766                 break;
767         default:
768                 DbgFree(ev);
769                 return LB_STATUS_ERROR_INVALID;
770         }
771
772         return LB_STATUS_SUCCESS;
773 }
774
775 HAPI int slave_event_callback_del(struct slave_node *slave, enum slave_event event, int (*cb)(struct slave_node *, void *), void *data)
776 {
777         struct event *ev;
778         Eina_List *l;
779         Eina_List *n;
780
781         switch (event) {
782         case SLAVE_EVENT_DEACTIVATE:
783                 EINA_LIST_FOREACH_SAFE(slave->event_deactivate_list, l, n, ev) {
784                         if (ev->evt_cb == cb && ev->cbdata == data) {
785                                 slave->event_deactivate_list = eina_list_remove(slave->event_deactivate_list, ev);
786                                 DbgFree(ev);
787                                 return LB_STATUS_SUCCESS;
788                         }
789                 }
790                 break;
791         case SLAVE_EVENT_DELETE:
792                 EINA_LIST_FOREACH_SAFE(slave->event_delete_list, l, n, ev) {
793                         if (ev->evt_cb == cb && ev->cbdata == data) {
794                                 slave->event_delete_list = eina_list_remove(slave->event_delete_list, ev);
795                                 DbgFree(ev);
796                                 return LB_STATUS_SUCCESS;
797                         }
798                 }
799                 break;
800         case SLAVE_EVENT_ACTIVATE:
801                 EINA_LIST_FOREACH_SAFE(slave->event_activate_list, l, n, ev) {
802                         if (ev->evt_cb == cb && ev->cbdata == data) {
803                                 slave->event_activate_list = eina_list_remove(slave->event_activate_list, ev);
804                                 DbgFree(ev);
805                                 return LB_STATUS_SUCCESS;
806                         }
807                 }
808                 break;
809         case SLAVE_EVENT_PAUSE:
810                 EINA_LIST_FOREACH_SAFE(slave->event_pause_list, l, n, ev) {
811                         if (ev->evt_cb == cb && ev->cbdata == data) {
812                                 slave->event_pause_list = eina_list_remove(slave->event_pause_list, ev);
813                                 DbgFree(ev);
814                                 return LB_STATUS_SUCCESS;
815                         }
816                 }
817                 break;
818         case SLAVE_EVENT_RESUME:
819                 EINA_LIST_FOREACH_SAFE(slave->event_resume_list, l, n, ev) {
820                         if (ev->evt_cb == cb && ev->cbdata == data) {
821                                 slave->event_resume_list = eina_list_remove(slave->event_resume_list, ev);
822                                 DbgFree(ev);
823                                 return LB_STATUS_SUCCESS;
824                         }
825                 }
826                 break;
827         case SLAVE_EVENT_FAULT:
828                 EINA_LIST_FOREACH_SAFE(slave->event_fault_list, l, n, ev) {
829                         if (ev->evt_cb == cb && ev->cbdata == data) {
830                                 slave->event_fault_list = eina_list_remove(slave->event_fault_list, ev);
831                                 DbgFree(ev);
832                                 return LB_STATUS_SUCCESS;
833                         }
834                 }
835                 break;
836         default:
837                 return LB_STATUS_ERROR_INVALID;
838         }
839
840         return LB_STATUS_ERROR_NOT_EXIST;
841 }
842
843 HAPI int slave_set_data(struct slave_node *slave, const char *tag, void *data)
844 {
845         struct priv_data *priv;
846
847         priv = calloc(1, sizeof(*priv));
848         if (!priv) {
849                 ErrPrint("Heap: %s\n", strerror(errno));
850                 return LB_STATUS_ERROR_MEMORY;
851         }
852
853         priv->tag = strdup(tag);
854         if (!priv->tag) {
855                 ErrPrint("Heap: %s\n", strerror(errno));
856                 DbgFree(priv);
857                 return LB_STATUS_ERROR_MEMORY;
858         }
859
860         priv->data = data;
861         slave->data_list = eina_list_append(slave->data_list, priv);
862         return LB_STATUS_SUCCESS;
863 }
864
865 HAPI void *slave_del_data(struct slave_node *slave, const char *tag)
866 {
867         struct priv_data *priv;
868         void *data;
869         Eina_List *l;
870         Eina_List *n;
871
872         EINA_LIST_FOREACH_SAFE(slave->data_list, l, n, priv) {
873                 if (!strcmp(priv->tag, tag)) {
874                         slave->data_list = eina_list_remove(slave->data_list, priv);
875
876                         data = priv->data;
877                         DbgFree(priv->tag);
878                         DbgFree(priv);
879                         return data;
880                 }
881         }
882
883         return NULL;
884 }
885
886 HAPI void *slave_data(struct slave_node *slave, const char *tag)
887 {
888         struct priv_data *priv;
889         Eina_List *l;
890
891         EINA_LIST_FOREACH(slave->data_list, l, priv) {
892                 if (!strcmp(priv->tag, tag))
893                         return priv->data;
894         }
895
896         return NULL;
897 }
898
899 HAPI struct slave_node *slave_find_by_pid(pid_t pid)
900 {
901         Eina_List *l;
902         struct slave_node *slave;
903
904         EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
905                 if (slave_pid(slave) == pid)
906                         return slave;
907         }
908
909         return NULL;
910 }
911
912 HAPI struct slave_node *slave_find_by_name(const char *name)
913 {
914         Eina_List *l;
915         struct slave_node *slave;
916
917         EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
918                 if (!strcmp(slave_name(slave), name))
919                         return slave;
920         }
921
922         return NULL;
923 }
924
925 HAPI struct slave_node *slave_find_available(const char *abi, int secured, int network)
926 {
927         Eina_List *l;
928         struct slave_node *slave;
929
930         EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
931                 if (slave->secured != secured)
932                         continue;
933
934                 if (slave->state == SLAVE_REQUEST_TO_TERMINATE && slave->loaded_instance == 0) {
935                         /*!
936                          * \note
937                          * If a slave is in request_to_terminate state,
938                          * and the slave object has no more intances,
939                          * the slave object will be deleted soon.
940                          * so we cannot reuse it.
941                          *
942                          * This object is not usable.
943                          */
944                         continue;
945                 }
946
947                 if (strcasecmp(slave->abi, abi))
948                         continue;
949
950                 if (slave->secured) {
951                         if (slave->loaded_package == 0) {
952                                 DbgPrint("Found secured slave - has no instances (%s)\n", slave_name(slave));
953                                 return slave;
954                         }
955                 } else if (slave->network == network) {
956                         DbgPrint("slave[%s] loaded_package[%d] net: [%d]\n", slave_name(slave), slave->loaded_package, slave->network);
957                         if (!strcasecmp(abi, DEFAULT_ABI)) {
958                                 if (slave->loaded_package < SLAVE_MAX_LOAD)
959                                         return slave;
960                         } else {
961                                 return slave;
962                         }
963                 }
964         }
965
966         return NULL;
967 }
968
969 HAPI struct slave_node *slave_find_by_pkgname(const char *pkgname)
970 {
971         Eina_List *l;
972         struct slave_node *slave;
973
974         EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
975                 if (!strcmp(slave_pkgname(slave), pkgname)) {
976                         if (slave_pid(slave) == (pid_t)-1) {
977                                 return slave;
978                         }
979                 }
980         }
981
982         return NULL;
983 }
984
985 HAPI struct slave_node *slave_find_by_rpc_handle(int handle)
986 {
987         Eina_List *l;
988         struct slave_node *slave;
989
990         if (handle <= 0) {
991                 ErrPrint("Invalid RPC handle: %d\n", handle);
992                 return NULL;
993         }
994
995         EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
996                 if (slave_rpc_handle(slave) == handle)
997                         return slave;
998         }
999
1000         /* Not found */
1001         return NULL;
1002 }
1003
1004 HAPI void slave_load_package(struct slave_node *slave)
1005 {
1006         slave->loaded_package++;
1007 }
1008
1009 HAPI void slave_unload_package(struct slave_node *slave)
1010 {
1011         if (!slave || slave->loaded_package == 0) {
1012                 ErrPrint("Slave loaded package is not correct\n");
1013                 return;
1014         }
1015                 
1016         slave->loaded_package--;
1017 }
1018
1019 HAPI void slave_load_instance(struct slave_node *slave)
1020 {
1021         slave->loaded_instance++;
1022         DbgPrint("Instance: (%d)%d\n", slave_pid(slave), slave->loaded_instance);
1023 }
1024
1025 HAPI int const slave_loaded_instance(struct slave_node *slave)
1026 {
1027         return slave->loaded_instance;
1028 }
1029
1030 HAPI int const slave_loaded_package(struct slave_node *slave)
1031 {
1032         return slave->loaded_package;
1033 }
1034
1035 HAPI struct slave_node *slave_unload_instance(struct slave_node *slave)
1036 {
1037         if (!slave || slave->loaded_instance == 0) {
1038                 ErrPrint("Slave loaded instance is not correct\n");
1039                 return slave;
1040         }
1041
1042         slave->loaded_instance--;
1043         DbgPrint("Instance: (%d)%d\n", slave_pid(slave), slave->loaded_instance);
1044         if (slave->loaded_instance == 0 && slave_is_activated(slave)) {
1045                 slave_set_reactivation(slave, 0);
1046                 slave_set_reactivate_instances(slave, 0);
1047
1048                 slave = slave_deactivate(slave);
1049         }
1050
1051         return slave;
1052 }
1053
1054 HAPI const int const slave_is_secured(const struct slave_node *slave)
1055 {
1056         return slave->secured;
1057 }
1058
1059 HAPI const char * const slave_name(const struct slave_node *slave)
1060 {
1061         return slave->name;
1062 }
1063
1064 HAPI const char * const slave_abi(const struct slave_node *slave)
1065 {
1066         return slave->abi;
1067 }
1068
1069 HAPI const pid_t const slave_pid(const struct slave_node *slave)
1070 {
1071         return slave->pid;
1072 }
1073
1074 HAPI int slave_set_pid(struct slave_node *slave, pid_t pid)
1075 {
1076         if (!slave)
1077                 return LB_STATUS_ERROR_INVALID;
1078
1079         DbgPrint("Slave PID is updated to %d from %d\n", pid, slave_pid(slave));
1080
1081         slave->pid = pid;
1082         return LB_STATUS_SUCCESS;
1083 }
1084
1085 static inline void invoke_resumed_cb(struct slave_node *slave)
1086 {
1087         Eina_List *l;
1088         Eina_List *n;
1089         struct event *event;
1090         int ret;
1091
1092         EINA_LIST_FOREACH_SAFE(slave->event_resume_list, l, n, event) {
1093                 ret = event->evt_cb(event->slave, event->cbdata);
1094                 if (ret < 0) {
1095                         if (eina_list_data_find(slave->event_resume_list, event)) {
1096                                 slave->event_resume_list = eina_list_remove(slave->event_resume_list, event);
1097                                 DbgFree(event);
1098                         }
1099                 }
1100         }
1101 }
1102
1103 static void resume_cb(struct slave_node *slave, const struct packet *packet, void *data)
1104 {
1105         int ret;
1106
1107         if (slave->state == SLAVE_REQUEST_TO_TERMINATE) {
1108                 DbgPrint("Slave is terminating now. ignore resume result\n");
1109                 return;
1110         }
1111
1112         if (!packet) {
1113                 ErrPrint("Failed to change the state of the slave\n");
1114                 slave->state = SLAVE_PAUSED;
1115                 return;
1116         }
1117
1118         if (packet_get(packet, "i", &ret) != 1) {
1119                 ErrPrint("Invalid parameter\n");
1120                 return;
1121         }
1122
1123         if (ret == 0) {
1124                 slave->state = SLAVE_RESUMED;
1125                 slave_rpc_ping_thaw(slave);
1126                 invoke_resumed_cb(slave);
1127         }
1128 }
1129
1130 static inline void invoke_paused_cb(struct slave_node *slave)
1131 {
1132         Eina_List *l;
1133         Eina_List *n;
1134         struct event *event;
1135         int ret;
1136
1137         EINA_LIST_FOREACH_SAFE(slave->event_pause_list, l, n, event) {
1138                 ret = event->evt_cb(event->slave, event->cbdata);
1139                 if (ret < 0) {
1140                         if (eina_list_data_find(slave->event_pause_list, event)) {
1141                                 slave->event_pause_list = eina_list_remove(slave->event_pause_list, event);
1142                                 DbgFree(event);
1143                         }
1144                 }
1145         }
1146 }
1147
1148 static void pause_cb(struct slave_node *slave, const struct packet *packet, void *data)
1149 {
1150         int ret;
1151
1152         if (slave->state == SLAVE_REQUEST_TO_TERMINATE) {
1153                 DbgPrint("Slave is terminating now. ignore pause result\n");
1154                 return;
1155         }
1156
1157         if (!packet) {
1158                 ErrPrint("Failed to change the state of the slave\n");
1159                 slave->state = SLAVE_RESUMED;
1160                 return;
1161         }
1162
1163         if (packet_get(packet, "i", &ret) != 1) {
1164                 ErrPrint("Invalid parameter\n");
1165                 return;
1166         }
1167
1168         if (ret == 0) {
1169                 slave->state = SLAVE_PAUSED;
1170                 slave_rpc_ping_freeze(slave);
1171                 invoke_paused_cb(slave);
1172         }
1173 }
1174
1175 HAPI int slave_resume(struct slave_node *slave)
1176 {
1177         double timestamp;
1178         struct packet *packet;
1179
1180         switch (slave->state) {
1181         case SLAVE_REQUEST_TO_LAUNCH:
1182         case SLAVE_REQUEST_TO_TERMINATE:
1183         case SLAVE_TERMINATED:
1184                 return LB_STATUS_ERROR_INVALID;
1185         case SLAVE_RESUMED:
1186         case SLAVE_REQUEST_TO_RESUME:
1187                 return LB_STATUS_SUCCESS;
1188         default:
1189                 break;
1190         }
1191
1192         timestamp = util_timestamp();
1193
1194         packet = packet_create("resume", "d", timestamp);
1195         if (!packet) {
1196                 ErrPrint("Failed to prepare param\n");
1197                 return LB_STATUS_ERROR_FAULT;
1198         }
1199
1200         slave->state = SLAVE_REQUEST_TO_RESUME;
1201         return slave_rpc_async_request(slave, NULL, packet, resume_cb, NULL, 0);
1202 }
1203
1204 HAPI int slave_pause(struct slave_node *slave)
1205 {
1206         double timestamp;
1207         struct packet *packet;
1208
1209         switch (slave->state) {
1210         case SLAVE_REQUEST_TO_LAUNCH:
1211         case SLAVE_REQUEST_TO_TERMINATE:
1212         case SLAVE_TERMINATED:
1213                 return LB_STATUS_ERROR_INVALID;
1214         case SLAVE_PAUSED:
1215         case SLAVE_REQUEST_TO_PAUSE:
1216                 return LB_STATUS_SUCCESS;
1217         default:
1218                 break;
1219         }
1220
1221         timestamp = util_timestamp();
1222
1223         packet = packet_create("pause", "d", timestamp);
1224         if (!packet) {
1225                 ErrPrint("Failed to prepare param\n");
1226                 return LB_STATUS_ERROR_FAULT;
1227         }
1228
1229         slave->state = SLAVE_REQUEST_TO_PAUSE;
1230         return slave_rpc_async_request(slave, NULL, packet, pause_cb, NULL, 0);
1231 }
1232
1233 HAPI const char *slave_pkgname(const struct slave_node *slave)
1234 {
1235         return slave ? slave->pkgname : NULL;
1236 }
1237
1238 HAPI enum slave_state slave_state(const struct slave_node *slave)
1239 {
1240         return slave ? slave->state : SLAVE_ERROR;
1241 }
1242
1243 HAPI const char *slave_state_string(const struct slave_node *slave)
1244 {
1245         switch (slave->state) {
1246         case SLAVE_REQUEST_TO_LAUNCH:
1247                 return "RequestToLaunch";
1248         case SLAVE_REQUEST_TO_TERMINATE:
1249                 return "RequestToTerminate";
1250         case SLAVE_TERMINATED:
1251                 return "Terminated";
1252         case SLAVE_REQUEST_TO_PAUSE:
1253                 return "RequestToPause";
1254         case SLAVE_REQUEST_TO_RESUME:
1255                 return "RequestToResume";
1256         case SLAVE_PAUSED:
1257                 return "Paused";
1258         case SLAVE_RESUMED:
1259                 return "Resumed";
1260         case SLAVE_ERROR:
1261                 return "Error";
1262         default:
1263                 break;
1264         }
1265
1266         return "Unknown";
1267 }
1268
1269 HAPI const void *slave_list(void)
1270 {
1271         return s_info.slave_list;
1272 }
1273
1274 HAPI int const slave_fault_count(const struct slave_node *slave)
1275 {
1276         return slave->fault_count;
1277 }
1278
1279 HAPI double const slave_ttl(const struct slave_node *slave)
1280 {
1281         if (!slave->ttl_timer)
1282                 return 0.0f;
1283
1284         return ecore_timer_pending_get(slave->ttl_timer);
1285 }
1286
1287 HAPI void slave_set_reactivate_instances(struct slave_node *slave, int reactivate)
1288 {
1289         slave->reactivate_instances = reactivate;
1290 }
1291
1292 HAPI int slave_need_to_reactivate_instances(struct slave_node *slave)
1293 {
1294         return slave->reactivate_instances;
1295 }
1296
1297 HAPI void slave_set_reactivation(struct slave_node *slave, int flag)
1298 {
1299         slave->reactivate_slave = flag;
1300 }
1301
1302 HAPI int slave_need_to_reactivate(struct slave_node *slave)
1303 {
1304         return slave->reactivate_slave;
1305 }
1306
1307 HAPI int slave_network(const struct slave_node *slave)
1308 {
1309         return slave->network;
1310 }
1311
1312 HAPI void slave_set_network(struct slave_node *slave, int network)
1313 {
1314         slave->network = network;
1315 }
1316
1317 HAPI int slave_deactivate_all(int reactivate, int reactivate_instances)
1318 {
1319         Eina_List *l;
1320         Eina_List *n;
1321         struct slave_node *slave;
1322         int cnt = 0;
1323
1324         EINA_LIST_FOREACH_SAFE(s_info.slave_list, l, n, slave) {
1325                 slave_set_reactivate_instances(slave, reactivate_instances);
1326                 slave_set_reactivation(slave, reactivate);
1327
1328                 if (!slave_deactivate(slave))
1329                         s_info.slave_list = eina_list_remove(s_info.slave_list, slave);
1330
1331                 cnt++;
1332         }
1333
1334         return cnt;
1335 }
1336
1337 HAPI int slave_activate_all(void)
1338 {
1339         Eina_List *l;
1340         struct slave_node *slave;
1341         int cnt = 0;
1342
1343         EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
1344                 slave_activate(slave);
1345                 cnt++;
1346         }
1347
1348         return cnt;
1349 }
1350
1351 /* End of a file */