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