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