From: Sung-jae Park Date: Thu, 11 Dec 2014 03:22:49 +0000 (+0900) Subject: Try to protect from unexpected slave deleting while processing event callback. X-Git-Tag: submit/tizen_mobile/20150527.071719~2^2~48^2~13^2^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=ca5bd97e7a77b0df12200bdc0fec3fd300152418;p=platform%2Fcore%2Fappfw%2Fdata-provider-master.git Try to protect from unexpected slave deleting while processing event callback. [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: I2fc7fd426c69f7a179dba7f83264e55e73908625 --- diff --git a/include/slave_life.h b/include/slave_life.h index e28aea6..07e8130 100644 --- a/include/slave_life.h +++ b/include/slave_life.h @@ -23,7 +23,8 @@ struct slave_node; enum slave_event { SLAVE_EVENT_ACTIVATE, SLAVE_EVENT_DEACTIVATE, /* deactivate callback, can return REACTIVATE, DEFAULT */ - SLAVE_EVENT_DELETE, + SLAVE_EVENT_DELETE, /* Callbacks for this event type, must has not to do something with slave object. + use this only for just notice the state of slave */ SLAVE_EVENT_FAULT, /* Critical fault */ SLAVE_EVENT_PAUSE, diff --git a/src/slave_life.c b/src/slave_life.c index 1952182..ba645c9 100644 --- a/src/slave_life.c +++ b/src/slave_life.c @@ -470,13 +470,13 @@ HAPI struct slave_node *slave_unref(struct slave_node *slave) } if (slave->refcnt == 0) { - ErrPrint("Slave refcnt is not valid\n"); + ErrPrint("Slave refcnt is not valid\n"); return NULL; } slave->refcnt--; if (slave->refcnt == 0) { - destroy_slave_node(slave); + destroy_slave_node(slave); slave = NULL; } @@ -521,12 +521,13 @@ HAPI void slave_destroy(struct slave_node *slave) slave_unref(slave); } -static inline void invoke_fault_cb(struct slave_node *slave) +static inline struct slave_node *invoke_fault_cb(struct slave_node *slave) { Eina_List *l; Eina_List *n; struct event *event; + slave_ref(slave); slave->in_event_process |= SLAVE_EVENT_PROCESS_FAULT; EINA_LIST_FOREACH_SAFE(slave->event_fault_list, l, n, event) { if (event->deleted || event->evt_cb(event->slave, event->cbdata) < 0 || event->deleted) { @@ -535,6 +536,9 @@ static inline void invoke_fault_cb(struct slave_node *slave) } } slave->in_event_process &= ~SLAVE_EVENT_PROCESS_FAULT; + slave = slave_unref(slave); + + return slave; } static inline void invoke_activate_cb(struct slave_node *slave) @@ -563,7 +567,11 @@ static Eina_Bool activate_timer_cb(void *data) } slave->fault_count++; - invoke_fault_cb(slave); + + if (invoke_fault_cb(slave) == NULL) { + ErrPrint("Slave is deleted while processing fault handler\n"); + return ECORE_CALLBACK_CANCEL; + } slave_set_reactivation(slave, 0); slave_set_reactivate_instances(slave, 0); @@ -586,7 +594,10 @@ static Eina_Bool activate_timer_cb(void *data) static inline void invoke_slave_fault_handler(struct slave_node *slave) { slave->fault_count++; - invoke_fault_cb(slave); + if (invoke_fault_cb(slave) == NULL) { + ErrPrint("Slave is deleted while processing fault handler\n"); + return; + } slave_set_reactivation(slave, 0); slave_set_reactivate_instances(slave, 0); @@ -938,7 +949,24 @@ HAPI struct slave_node *slave_deactivated(struct slave_node *slave) slave->terminate_timer = NULL; } + /** + * @note + * FOR SAFETY + * If the deactivated event callback is called for package.c + * It can delete the instance if it has fault information + * then it also try to delete the slave object again. + * To prevent from unexpected slave object deletetion while handling callback, + * increase the refcnt of slave + * when it get back from callback, try to decrease the refcnt of slave + * At that time, we can delete slave safely. + */ + slave_ref(slave); reactivate = invoke_deactivate_cb(slave); + slave = slave_unref(slave); + if (!slave) { + ErrPrint("Slave object is deleted\n"); + return slave; + } slave = slave_unref(slave); if (!slave) { @@ -1023,7 +1051,10 @@ HAPI struct slave_node *slave_deactivated_by_fault(struct slave_node *slave) * \note * Fault callback can access the slave information. */ - invoke_fault_cb(slave); + if (invoke_fault_cb(slave) == NULL) { + ErrPrint("Slave is deleted while processing fault handler\n"); + return NULL; + } } else { slave->critical_fault_count = 0; } @@ -1046,7 +1077,10 @@ HAPI struct slave_node *slave_deactivated_by_fault(struct slave_node *slave) * \note * Fault callback can access the slave information. */ - invoke_fault_cb(slave); + if (invoke_fault_cb(slave) == NULL) { + ErrPrint("Slave is deleted while processing fault handler\n"); + return NULL; + } } } else { slave->critical_fault_count = 0;