From: Sung-jae Park Date: Fri, 5 Dec 2014 10:39:11 +0000 (+0900) Subject: Fix the unexpected slave object deleteing. X-Git-Tag: submit/tizen_mobile/20150527.071719~2^2~48^2~13^2~2^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=c5e12269e1b8a6524588712c2f2bba7446f48013;p=platform%2Fcore%2Fappfw%2Fdata-provider-master.git Fix the unexpected slave object deleteing. 1. slave_deactivate function should not release the slave object directly even though it has ZERO instances. 2. slave_deactivate function is changed to static one. It only used in slave_life.c file. so I specify its scope to slave_life.c file. 3. Do not deactivate the slave again if it is already deactivated. So before call the deactivate function, check its states whether it is activated or not [model] Redwood,Kiran,B3(Wearable) [binary_type] AP [customer] Docomo/Orange/ATT/Open [issue#] N/A [problem] [cause] [solution] [team] HomeTF [request] [horizontal_expansion] Change-Id: I6fa8025201a7e9e141a8a3a9e81148122c65682c --- diff --git a/include/slave_life.h b/include/slave_life.h index cdc80fd..e28aea6 100644 --- a/include/slave_life.h +++ b/include/slave_life.h @@ -113,12 +113,6 @@ extern void slave_destroy(struct slave_node *slave); extern int slave_activate(struct slave_node *slave); /*! - * \brief After this function call, the slave object can be deleted - * \param[in] slave - */ -extern struct slave_node *slave_deactivate(struct slave_node *slave, int direct) __attribute__((warn_unused_result)); - -/*! * To check the slave's activation state */ extern const int const slave_is_activated(struct slave_node *slave); diff --git a/src/slave_life.c b/src/slave_life.c index 26b0220..c16d329 100644 --- a/src/slave_life.c +++ b/src/slave_life.c @@ -132,6 +132,93 @@ static struct { .deactivate_all_refcnt = 0, }; +static Eina_Bool terminate_timer_cb(void *data) +{ + struct slave_node *slave = data; + int ret; + + /*! + * \todo + * check the return value of the aul_terminate_pid + */ + slave->state = SLAVE_REQUEST_TO_TERMINATE; + slave->terminate_timer = NULL; + + DbgPrint("Terminate slave: %d (%s)\n", slave_pid(slave), slave_name(slave)); + ret = aul_terminate_pid_async(slave->pid); + if (ret < 0) { + ErrPrint("Terminate slave(%s) failed. pid %d (%d)\n", slave_name(slave), slave_pid(slave), ret); + slave = slave_deactivated(slave); + if (slave == NULL) { + DbgPrint("Slave is deleted\n"); + } + } + + return ECORE_CALLBACK_CANCEL; +} + +static struct slave_node *slave_deactivate(struct slave_node *slave, int no_timer) +{ + int ret; + + if (slave_pid(slave) <= 0) { + return slave; + } + + if ((slave->ctrl_option & PROVIDER_CTRL_MANUAL_TERMINATION) == PROVIDER_CTRL_MANUAL_TERMINATION) { + /*! + * \note + * In this case, + * The provider requests MANUAL TERMINATION control option. + * Master will not send terminate request in this case, the provider should be terminated by itself. + */ + DbgPrint("Manual termination is turned on\n"); + slave->state = SLAVE_REQUEST_TO_DISCONNECT; + (void)slave_rpc_disconnect(slave); + } else if (slave->terminate_timer) { + ErrPrint("Terminate timer is already fired (%d)\n", slave->pid); + } else if (!no_timer && !slave->secured) { + DbgPrint("Fire the terminate timer: %d\n", slave->pid); + slave->terminate_timer = ecore_timer_add(DYNAMICBOX_CONF_SLAVE_ACTIVATE_TIME, terminate_timer_cb, slave); + if (!slave->terminate_timer) { + /*! + * \note + * Normally, Call the terminate_timer_cb directly from here + * But in this case. if the aul_terminate_pid failed, Call the slave_deactivated function directly. + * Then the "slave" pointer can be changed. To trace it, Copy the body of terminate_timer_cb to here. + */ + ErrPrint("Failed to add a new timer for terminating\n"); + DbgPrint("Terminate slave: %d (%s)\n", slave_pid(slave), slave_name(slave)); + /*! + * \todo + * check the return value of the aul_terminate_pid + */ + slave->state = SLAVE_REQUEST_TO_TERMINATE; + + ret = aul_terminate_pid_async(slave->pid); + if (ret < 0) { + ErrPrint("Terminate slave(%s) failed. pid %d (%d)\n", slave_name(slave), slave_pid(slave), ret); + slave = slave_deactivated(slave); + } + } + } else { + /*! + * \todo + * check the return value of the aul_terminate_pid + */ + slave->state = SLAVE_REQUEST_TO_TERMINATE; + + DbgPrint("Terminate slave: %d (%s)\n", slave_pid(slave), slave_name(slave)); + ret = aul_terminate_pid_async(slave->pid); + if (ret < 0) { + ErrPrint("Terminate slave(%s) failed. pid %d (%d)\n", slave_name(slave), slave_pid(slave), ret); + slave = slave_deactivated(slave); + } + } + + return slave; +} + static Eina_Bool slave_ttl_cb(void *data) { struct pkg_info *info; @@ -163,12 +250,14 @@ static Eina_Bool slave_ttl_cb(void *data) */ slave->ttl_timer = NULL; - slave_set_reactivation(slave, 0); - slave_set_reactivate_instances(slave, 1); + if (slave_is_activated(slave)) { + slave_set_reactivation(slave, 0); + slave_set_reactivate_instances(slave, 1); - slave = slave_deactivate(slave, 1); - if (!slave) { - DbgPrint("Slave is deleted\n"); + slave = slave_deactivate(slave, 1); + if (!slave) { + DbgPrint("Slave is deleted\n"); + } } /*! To recover all instances state it is activated again */ @@ -806,106 +895,6 @@ static inline int invoke_deactivate_cb(struct slave_node *slave) return reactivate; } -static Eina_Bool terminate_timer_cb(void *data) -{ - struct slave_node *slave = data; - int ret; - - /*! - * \todo - * check the return value of the aul_terminate_pid - */ - slave->state = SLAVE_REQUEST_TO_TERMINATE; - slave->terminate_timer = NULL; - - DbgPrint("Terminate slave: %d (%s)\n", slave_pid(slave), slave_name(slave)); - ret = aul_terminate_pid_async(slave->pid); - if (ret < 0) { - ErrPrint("Terminate slave(%s) failed. pid %d (%d)\n", slave_name(slave), slave_pid(slave), ret); - slave = slave_deactivated(slave); - if (slave == NULL) { - DbgPrint("Slave is deleted\n"); - } - } - - return ECORE_CALLBACK_CANCEL; -} - -HAPI struct slave_node *slave_deactivate(struct slave_node *slave, int no_timer) -{ - int ret; - - if (!slave_is_activated(slave)) { - ErrPrint("Slave is already deactivated\n"); - if (slave_loaded_instance(slave) == 0) { - /*! - * \note - * If a slave has no more instances, - * Destroy it - */ - slave = slave_unref(slave); - } - return slave; - } - - if (slave_pid(slave) <= 0) { - return slave; - } - - if ((slave->ctrl_option & PROVIDER_CTRL_MANUAL_TERMINATION) == PROVIDER_CTRL_MANUAL_TERMINATION) { - /*! - * \note - * In this case, - * The provider requests MANUAL TERMINATION control option. - * Master will not send terminate request in this case, the provider should be terminated by itself. - */ - DbgPrint("Manual termination is turned on\n"); - slave->state = SLAVE_REQUEST_TO_DISCONNECT; - (void)slave_rpc_disconnect(slave); - } else if (slave->terminate_timer) { - ErrPrint("Terminate timer is already fired (%d)\n", slave->pid); - } else if (!no_timer && !slave->secured) { - DbgPrint("Fire the terminate timer: %d\n", slave->pid); - slave->terminate_timer = ecore_timer_add(DYNAMICBOX_CONF_SLAVE_ACTIVATE_TIME, terminate_timer_cb, slave); - if (!slave->terminate_timer) { - /*! - * \note - * Normally, Call the terminate_timer_cb directly from here - * But in this case. if the aul_terminate_pid failed, Call the slave_deactivated function directly. - * Then the "slave" pointer can be changed. To trace it, Copy the body of terminate_timer_cb to here. - */ - ErrPrint("Failed to add a new timer for terminating\n"); - DbgPrint("Terminate slave: %d (%s)\n", slave_pid(slave), slave_name(slave)); - /*! - * \todo - * check the return value of the aul_terminate_pid - */ - slave->state = SLAVE_REQUEST_TO_TERMINATE; - - ret = aul_terminate_pid_async(slave->pid); - if (ret < 0) { - ErrPrint("Terminate slave(%s) failed. pid %d (%d)\n", slave_name(slave), slave_pid(slave), ret); - slave = slave_deactivated(slave); - } - } - } else { - /*! - * \todo - * check the return value of the aul_terminate_pid - */ - slave->state = SLAVE_REQUEST_TO_TERMINATE; - - DbgPrint("Terminate slave: %d (%s)\n", slave_pid(slave), slave_name(slave)); - ret = aul_terminate_pid_async(slave->pid); - if (ret < 0) { - ErrPrint("Terminate slave(%s) failed. pid %d (%d)\n", slave_name(slave), slave_pid(slave), ret); - slave = slave_deactivated(slave); - } - } - - return slave; -} - HAPI struct slave_node *slave_deactivated(struct slave_node *slave) { int reactivate; @@ -1774,14 +1763,16 @@ HAPI int slave_deactivate_all(int reactivate, int reactivate_instances, int no_t DbgPrint("Deactivate all\n"); EINA_LIST_FOREACH_SAFE(s_info.slave_list, l, n, slave) { - slave_set_reactivate_instances(slave, reactivate_instances); - slave_set_reactivation(slave, reactivate); + if (slave_is_activated(slave)) { + slave_set_reactivate_instances(slave, reactivate_instances); + slave_set_reactivation(slave, reactivate); - if (!slave_deactivate(slave, no_timer)) { - s_info.slave_list = eina_list_remove(s_info.slave_list, slave); + if (!slave_deactivate(slave, no_timer)) { + s_info.slave_list = eina_list_remove(s_info.slave_list, slave); + } } - cnt++; + cnt++; } return cnt;