2 * Copyright 2012 Samsung Electronics Co., Ltd
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
8 * http://www.tizenopensource.org/license
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.
18 #include <string.h> /* strerror */
19 #include <errno.h> /* errno */
20 #include <unistd.h> /* pid_t */
21 #include <stdlib.h> /* free */
29 #include <aul.h> /* aul_launch_app */
35 #include "slave_life.h"
36 #include "slave_rpc.h"
37 #include "client_life.h"
38 #include "fault_manager.h"
52 int secured; /* Only A package(livebox) is loaded for security requirements */
55 int critical_fault_count;
56 enum slave_state state;
61 int reactivate_instances;
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;
75 Ecore_Timer *ttl_timer; /* Time to live */
76 Ecore_Timer *activate_timer; /* Waiting hello packet for this time */
78 struct timeval activated_at;
82 struct slave_node *slave;
84 int (*evt_cb)(struct slave_node *, void *);
94 Eina_List *slave_list;
99 static Eina_Bool slave_ttl_cb(void *data)
101 struct slave_node *slave = (struct slave_node *)data;
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.
108 slave->ttl_timer = NULL;
110 slave_set_reactivation(slave, 0);
111 slave_set_reactivate_instances(slave, 1);
113 slave = slave_deactivate(slave);
114 DbgPrint("Slave is deactivated(%p)\n", slave);
116 /*! To recover all instances state it is activated again */
117 return ECORE_CALLBACK_CANCEL;
120 static inline int xmonitor_pause_cb(void *data)
126 static inline int xmonitor_resume_cb(void *data)
132 static inline struct slave_node *create_slave_node(const char *name, int is_secured, const char *abi, const char *pkgname)
134 struct slave_node *slave;
136 slave = calloc(1, sizeof(*slave));
138 ErrPrint("Heap: %s\n", strerror(errno));
142 slave->name = strdup(name);
144 ErrPrint("Heap: %s\n", strerror(errno));
149 slave->abi = strdup(abi);
151 ErrPrint("Heap: %s\n", strerror(errno));
152 DbgFree(slave->name);
157 slave->pkgname = strdup(pkgname);
158 if (!slave->pkgname) {
159 ErrPrint("Heap: %s\n", strerror(errno));
161 DbgFree(slave->name);
166 slave->secured = is_secured;
167 slave->pid = (pid_t)-1;
168 slave->state = SLAVE_TERMINATED;
170 xmonitor_add_event_callback(XMONITOR_PAUSED, xmonitor_pause_cb, slave);
171 xmonitor_add_event_callback(XMONITOR_RESUMED, xmonitor_resume_cb, slave);
173 s_info.slave_list = eina_list_append(s_info.slave_list, slave);
174 DbgPrint("slave data is created %p\n", slave);
178 static inline void invoke_delete_cb(struct slave_node *slave)
185 EINA_LIST_FOREACH_SAFE(slave->event_delete_list, l, n, event) {
186 ret = event->evt_cb(event->slave, event->cbdata);
188 if (eina_list_data_find(slave->event_delete_list, event)) {
189 slave->event_delete_list = eina_list_remove(slave->event_delete_list, event);
196 static inline void destroy_slave_node(struct slave_node *slave)
199 struct priv_data *priv;
201 if (slave->pid != (pid_t)-1) {
202 ErrPrint("Slave is not deactivated\n");
206 DbgPrint("Slave data is destroyed %p\n", slave);
208 xmonitor_del_event_callback(XMONITOR_PAUSED, xmonitor_pause_cb, slave);
209 xmonitor_del_event_callback(XMONITOR_RESUMED, xmonitor_resume_cb, slave);
211 invoke_delete_cb(slave);
212 slave_rpc_fini(slave); /*!< Finalize the RPC after handling all delete callbacks */
214 EINA_LIST_FREE(slave->event_delete_list, event) {
218 EINA_LIST_FREE(slave->event_activate_list, event) {
222 EINA_LIST_FREE(slave->event_deactivate_list, event) {
226 EINA_LIST_FREE(slave->event_fault_list, event) {
230 EINA_LIST_FREE(slave->data_list, priv) {
235 s_info.slave_list = eina_list_remove(s_info.slave_list, slave);
237 if (slave->ttl_timer)
238 ecore_timer_del(slave->ttl_timer);
240 if (slave->activate_timer)
241 ecore_timer_del(slave->activate_timer);
244 DbgFree(slave->name);
245 DbgFree(slave->pkgname);
250 static inline struct slave_node *find_slave(const char *name)
252 struct slave_node *slave;
255 EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
256 if (!strcmp(slave->name, name))
263 HAPI int slave_expired_ttl(struct slave_node *slave)
271 return !!slave->ttl_timer;
274 HAPI struct slave_node *slave_ref(struct slave_node *slave)
283 HAPI struct slave_node *slave_unref(struct slave_node *slave)
288 if (slave->refcnt == 0) {
289 ErrPrint("Slave refcnt is not valid\n");
294 if (slave->refcnt == 0) {
295 destroy_slave_node(slave);
302 HAPI const int const slave_refcnt(struct slave_node *slave)
304 return slave->refcnt;
307 HAPI struct slave_node *slave_create(const char *name, int is_secured, const char *abi, const char *pkgname)
309 struct slave_node *slave;
311 slave = find_slave(name);
313 if (slave->secured != is_secured)
314 ErrPrint("Exists slave and creating slave's security flag is not matched\n");
318 slave = create_slave_node(name, is_secured, abi, pkgname);
323 slave_rpc_init(slave);
330 * Before destroying slave object,
331 * you should check the RPC(slave_async_XXX) state and Private data field (slave_set_data)
333 HAPI void slave_destroy(struct slave_node *slave)
338 static inline void invoke_fault_cb(struct slave_node *slave)
345 EINA_LIST_FOREACH_SAFE(slave->event_fault_list, l, n, event) {
346 ret = event->evt_cb(event->slave, event->cbdata);
348 if (eina_list_data_find(slave->event_fault_list, event)) {
349 slave->event_fault_list = eina_list_remove(slave->event_fault_list, event);
356 static inline void invoke_activate_cb(struct slave_node *slave)
363 EINA_LIST_FOREACH_SAFE(slave->event_activate_list, l, n, event) {
364 ret = event->evt_cb(event->slave, event->cbdata);
366 if (eina_list_data_find(slave->event_activate_list, event)) {
367 slave->event_activate_list = eina_list_remove(slave->event_activate_list, event);
374 static Eina_Bool activate_timer_cb(void *data)
376 struct slave_node *slave = data;
378 slave->fault_count++;
379 invoke_fault_cb(slave);
381 slave_set_reactivation(slave, 0);
382 slave_set_reactivate_instances(slave, 0);
384 slave->activate_timer = NULL;
385 if (slave->pid > 0) {
387 DbgPrint("Try to terminate PID: %d\n", slave->pid);
388 ret = aul_terminate_pid(slave->pid);
390 ErrPrint("Terminate failed, pid %d\n", slave->pid);
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;
397 HAPI int slave_activate(struct slave_node *slave)
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.
409 if (slave->pid != (pid_t)-1)
413 DbgPrint("Debug Mode enabled. name[%s] secured[%d] abi[%s]\n", slave->name, slave->secured, slave->abi);
416 param = bundle_create();
418 ErrPrint("Failed to create a bundle\n");
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);
426 DbgPrint("Launch the slave package: %s\n", slave->pkgname);
427 slave->pid = (pid_t)aul_launch_app(slave->pkgname, param);
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;
436 DbgPrint("Slave launched %d for %s\n", slave->pid, slave->name);
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");
443 slave->state = SLAVE_REQUEST_TO_LAUNCH;
446 * Increase the refcnt of a slave,
447 * To prevent from making an orphan(slave).
454 HAPI int slave_give_more_ttl(struct slave_node *slave)
458 if (!slave->secured || !slave->ttl_timer)
461 delay = SLAVE_TTL - ecore_timer_pending_get(slave->ttl_timer);
462 ecore_timer_delay(slave->ttl_timer, delay);
466 HAPI int slave_freeze_ttl(struct slave_node *slave)
468 if (!slave->secured || !slave->ttl_timer)
471 ecore_timer_freeze(slave->ttl_timer);
475 HAPI int slave_thaw_ttl(struct slave_node *slave)
479 if (!slave->secured || !slave->ttl_timer)
482 ecore_timer_thaw(slave->ttl_timer);
484 delay = SLAVE_TTL - ecore_timer_pending_get(slave->ttl_timer);
485 ecore_timer_delay(slave->ttl_timer, delay);
489 HAPI int slave_activated(struct slave_node *slave)
491 slave->state = SLAVE_RESUMED;
493 if (xmonitor_is_paused())
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");
503 invoke_activate_cb(slave);
505 slave_set_reactivation(slave, 0);
506 slave_set_reactivate_instances(slave, 0);
508 if (gettimeofday(&slave->activated_at, NULL) < 0)
509 ErrPrint("Failed to get time of day: %s\n", strerror(errno));
511 if (slave->activate_timer) {
512 ecore_timer_del(slave->activate_timer);
513 slave->activate_timer = NULL;
519 static inline int invoke_deactivate_cb(struct slave_node *slave)
527 EINA_LIST_FOREACH_SAFE(slave->event_deactivate_list, l, n, event) {
528 ret = event->evt_cb(event->slave, event->cbdata);
530 if (eina_list_data_find(slave->event_deactivate_list, event)) {
531 slave->event_deactivate_list = eina_list_remove(slave->event_deactivate_list, event);
534 } else if (ret == SLAVE_NEED_TO_REACTIVATE) {
542 HAPI struct slave_node *slave_deactivate(struct slave_node *slave)
546 if (!slave_is_activated(slave)) {
547 ErrPrint("Slave is already deactivated\n");
548 if (slave_loaded_instance(slave) == 0) {
551 * If a slave has no more instances,
554 slave = slave_unref(slave);
559 DbgPrint("Deactivate a slave: %d\n", slave->pid);
562 * check the return value of the aul_terminate_pid
564 slave->state = SLAVE_REQUEST_TO_TERMINATE;
566 DbgPrint("Terminate PID: %d\n", slave->pid);
567 if (slave->pid > 0) {
568 ret = aul_terminate_pid(slave->pid);
570 ErrPrint("Terminate failed. pid %d (%d)\n", slave->pid, ret);
571 slave = slave_deactivated(slave);
578 HAPI struct slave_node *slave_deactivated(struct slave_node *slave)
582 slave->pid = (pid_t)-1;
583 slave->state = SLAVE_TERMINATED;
585 if (slave->ttl_timer) {
586 ecore_timer_del(slave->ttl_timer);
587 slave->ttl_timer = NULL;
590 if (slave->activate_timer) {
591 ecore_timer_del(slave->activate_timer);
592 slave->activate_timer = NULL;
595 reactivate = invoke_deactivate_cb(slave);
597 slave = slave_unref(slave);
599 DbgPrint("SLAVE object is destroyed\n");
603 if (reactivate && slave_need_to_reactivate(slave)) {
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) {
613 * If a slave has no more instances,
616 slave = slave_unref(slave);
622 HAPI struct slave_node *slave_deactivated_by_fault(struct slave_node *slave)
625 struct timeval faulted_at;
627 int reactivate_instances = 1;
629 if (!slave_is_activated(slave)) {
630 DbgPrint("Deactivating in progress\n");
631 if (slave_loaded_instance(slave) == 0)
632 slave = slave_unref(slave);
637 slave->fault_count++;
639 (void)fault_check_pkgs(slave);
641 if (slave->pid > 0) {
642 DbgPrint("Try to terminate PID: %d\n", slave->pid);
643 ret = aul_terminate_pid(slave->pid);
645 ErrPrint("Terminate failed, pid %d\n", slave->pid);
649 if (gettimeofday(&faulted_at, NULL) == 0) {
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");
658 reactivate_instances = 0;
659 slave->critical_fault_count = 0;
662 * Fault callback can access the slave information.
664 invoke_fault_cb(slave);
667 slave->critical_fault_count = 0;
670 ErrPrint("Failed to get time of day: %s\n", strerror(errno));
673 slave_set_reactivation(slave, reactivate);
674 slave_set_reactivate_instances(slave, reactivate_instances);
676 slave = slave_deactivated(slave);
680 HAPI const int const slave_is_activated(struct slave_node *slave)
682 switch (slave->state) {
683 case SLAVE_REQUEST_TO_TERMINATE:
684 case SLAVE_TERMINATED:
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:
694 return slave->pid != (pid_t)-1;
697 /* Could not be reach to here */
701 HAPI int slave_event_callback_add(struct slave_node *slave, enum slave_event event, int (*cb)(struct slave_node *, void *), void *data)
705 ev = calloc(1, sizeof(*ev));
707 ErrPrint("Heap: %s\n", strerror(errno));
717 * Use the eina_list_prepend API.
718 * To keep the sequence of a callback invocation.
720 * Here is an example sequence.
722 * slave_event_callback_add(CALLBACK_01);
723 * slave_event_callback_add(CALLBACK_02);
724 * slave_event_callback_add(CALLBACK_03);
726 * Then the invoke_event_callback function will call the CALLBACKS as below sequence
734 case SLAVE_EVENT_ACTIVATE:
735 slave->event_activate_list = eina_list_prepend(slave->event_activate_list, ev);
737 case SLAVE_EVENT_DELETE:
738 slave->event_delete_list = eina_list_prepend(slave->event_delete_list, ev);
740 case SLAVE_EVENT_DEACTIVATE:
741 slave->event_deactivate_list = eina_list_prepend(slave->event_deactivate_list, ev);
743 case SLAVE_EVENT_PAUSE:
744 slave->event_pause_list = eina_list_prepend(slave->event_pause_list, ev);
746 case SLAVE_EVENT_RESUME:
747 slave->event_resume_list = eina_list_prepend(slave->event_resume_list, ev);
749 case SLAVE_EVENT_FAULT:
750 slave->event_fault_list = eina_list_prepend(slave->event_fault_list, ev);
760 HAPI int slave_event_callback_del(struct slave_node *slave, enum slave_event event, int (*cb)(struct slave_node *, void *), void *data)
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);
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);
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);
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);
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);
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);
828 HAPI int slave_set_data(struct slave_node *slave, const char *tag, void *data)
830 struct priv_data *priv;
832 priv = calloc(1, sizeof(*priv));
834 ErrPrint("Heap: %s\n", strerror(errno));
838 priv->tag = strdup(tag);
840 ErrPrint("Heap: %s\n", strerror(errno));
846 slave->data_list = eina_list_append(slave->data_list, priv);
850 HAPI void *slave_del_data(struct slave_node *slave, const char *tag)
852 struct priv_data *priv;
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);
871 HAPI void *slave_data(struct slave_node *slave, const char *tag)
873 struct priv_data *priv;
876 EINA_LIST_FOREACH(slave->data_list, l, priv) {
877 if (!strcmp(priv->tag, tag))
884 HAPI struct slave_node *slave_find_by_pid(pid_t pid)
887 struct slave_node *slave;
889 EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
890 if (slave->pid == pid)
897 HAPI struct slave_node *slave_find_by_name(const char *name)
900 struct slave_node *slave;
902 EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
903 if (!strcmp(slave->name, name))
910 HAPI struct slave_node *slave_find_available(const char *abi, int secured)
913 struct slave_node *slave;
915 EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
916 if (slave->secured != secured)
919 if (slave->state == SLAVE_REQUEST_TO_TERMINATE && slave->loaded_instance == 0) {
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.
927 * This object is not usable.
932 if (strcasecmp(slave->abi, abi))
935 if (slave->secured) {
936 DbgPrint("Found secured slave - has no instances (%s)\n", slave_name(slave));
937 if (slave->loaded_package == 0)
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)
953 HAPI struct slave_node *slave_find_by_pkgname(const char *pkgname)
956 struct slave_node *slave;
958 EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
959 if (!strcmp(slave->pkgname, pkgname)) {
960 if (slave->pid == (pid_t)-1) {
969 HAPI struct slave_node *slave_find_by_rpc_handle(int handle)
972 struct slave_node *slave;
975 ErrPrint("Invalid RPC handle: %d\n", handle);
979 EINA_LIST_FOREACH(s_info.slave_list, l, slave) {
980 if (slave_rpc_handle(slave) == handle)
988 HAPI void slave_load_package(struct slave_node *slave)
990 slave->loaded_package++;
993 HAPI void slave_unload_package(struct slave_node *slave)
995 if (!slave || slave->loaded_package == 0) {
996 ErrPrint("Slave loaded package is not correct\n");
1000 slave->loaded_package--;
1003 HAPI void slave_load_instance(struct slave_node *slave)
1005 slave->loaded_instance++;
1006 DbgPrint("Instance: (%d)%d\n", slave->pid, slave->loaded_instance);
1009 HAPI int const slave_loaded_instance(struct slave_node *slave)
1011 return slave->loaded_instance;
1014 HAPI int const slave_loaded_package(struct slave_node *slave)
1016 return slave->loaded_package;
1019 HAPI struct slave_node *slave_unload_instance(struct slave_node *slave)
1021 if (!slave || slave->loaded_instance == 0) {
1022 ErrPrint("Slave loaded instance is not correct\n");
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);
1032 slave = slave_deactivate(slave);
1038 HAPI const int const slave_is_secured(const struct slave_node *slave)
1040 return slave->secured;
1043 HAPI const char * const slave_name(const struct slave_node *slave)
1048 HAPI const char * const slave_abi(const struct slave_node *slave)
1053 HAPI const pid_t const slave_pid(const struct slave_node *slave)
1058 HAPI int slave_set_pid(struct slave_node *slave, pid_t pid)
1063 DbgPrint("Slave PID is updated to %d from %d\n", pid, slave->pid);
1069 static inline void invoke_resumed_cb(struct slave_node *slave)
1073 struct event *event;
1076 EINA_LIST_FOREACH_SAFE(slave->event_resume_list, l, n, event) {
1077 ret = event->evt_cb(event->slave, event->cbdata);
1079 if (eina_list_data_find(slave->event_resume_list, event)) {
1080 slave->event_resume_list = eina_list_remove(slave->event_resume_list, event);
1087 static void resume_cb(struct slave_node *slave, const struct packet *packet, void *data)
1091 if (slave->state == SLAVE_REQUEST_TO_TERMINATE) {
1092 DbgPrint("Slave is terminating now. ignore resume result\n");
1097 ErrPrint("Failed to change the state of the slave\n");
1098 slave->state = SLAVE_PAUSED;
1102 if (packet_get(packet, "i", &ret) != 1) {
1103 ErrPrint("Invalid parameter\n");
1108 slave->state = SLAVE_RESUMED;
1109 slave_rpc_ping_thaw(slave);
1110 invoke_resumed_cb(slave);
1114 static inline void invoke_paused_cb(struct slave_node *slave)
1118 struct event *event;
1121 EINA_LIST_FOREACH_SAFE(slave->event_pause_list, l, n, event) {
1122 ret = event->evt_cb(event->slave, event->cbdata);
1124 if (eina_list_data_find(slave->event_pause_list, event)) {
1125 slave->event_pause_list = eina_list_remove(slave->event_pause_list, event);
1132 static void pause_cb(struct slave_node *slave, const struct packet *packet, void *data)
1136 if (slave->state == SLAVE_REQUEST_TO_TERMINATE) {
1137 DbgPrint("Slave is terminating now. ignore pause result\n");
1142 ErrPrint("Failed to change the state of the slave\n");
1143 slave->state = SLAVE_RESUMED;
1147 if (packet_get(packet, "i", &ret) != 1) {
1148 ErrPrint("Invalid parameter\n");
1153 slave->state = SLAVE_PAUSED;
1154 slave_rpc_ping_freeze(slave);
1155 invoke_paused_cb(slave);
1159 HAPI int slave_resume(struct slave_node *slave)
1162 struct packet *packet;
1164 switch (slave->state) {
1165 case SLAVE_REQUEST_TO_LAUNCH:
1166 case SLAVE_REQUEST_TO_TERMINATE:
1167 case SLAVE_TERMINATED:
1170 case SLAVE_REQUEST_TO_RESUME:
1176 timestamp = util_timestamp();
1178 packet = packet_create("resume", "d", timestamp);
1180 ErrPrint("Failed to prepare param\n");
1184 slave->state = SLAVE_REQUEST_TO_RESUME;
1185 return slave_rpc_async_request(slave, NULL, packet, resume_cb, NULL, 0);
1188 HAPI int slave_pause(struct slave_node *slave)
1191 struct packet *packet;
1193 switch (slave->state) {
1194 case SLAVE_REQUEST_TO_LAUNCH:
1195 case SLAVE_REQUEST_TO_TERMINATE:
1196 case SLAVE_TERMINATED:
1199 case SLAVE_REQUEST_TO_PAUSE:
1205 timestamp = util_timestamp();
1207 packet = packet_create("pause", "d", timestamp);
1209 ErrPrint("Failed to prepare param\n");
1213 slave->state = SLAVE_REQUEST_TO_PAUSE;
1214 return slave_rpc_async_request(slave, NULL, packet, pause_cb, NULL, 0);
1217 HAPI const char *slave_pkgname(const struct slave_node *slave)
1219 return slave ? slave->pkgname : NULL;
1222 HAPI enum slave_state slave_state(const struct slave_node *slave)
1224 return slave ? slave->state : SLAVE_ERROR;
1227 HAPI const char *slave_state_string(const struct slave_node *slave)
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";
1253 HAPI const void *slave_list(void)
1255 return s_info.slave_list;
1258 HAPI int const slave_fault_count(const struct slave_node *slave)
1260 return slave->fault_count;
1263 HAPI double const slave_ttl(const struct slave_node *slave)
1265 if (!slave->ttl_timer)
1268 return ecore_timer_pending_get(slave->ttl_timer);
1271 HAPI void slave_set_reactivate_instances(struct slave_node *slave, int reactivate)
1273 slave->reactivate_instances = reactivate;
1276 HAPI int slave_need_to_reactivate_instances(struct slave_node *slave)
1278 return slave->reactivate_instances;
1281 HAPI void slave_set_reactivation(struct slave_node *slave, int flag)
1283 slave->reactivate_slave = flag;
1286 HAPI int slave_need_to_reactivate(struct slave_node *slave)
1288 return slave->reactivate_slave;