devilhorns pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=cd6b890c7322ec67d3c41281bda3b22d4a481775
commit cd6b890c7322ec67d3c41281bda3b22d4a481775 Author: Mike Blumenkrantz <[email protected]> Date: Wed Jun 13 11:33:21 2018 -0400 evas: handle event COW modification when COW is already active Summary: enabling write on a COW which is already writing is a user error, which can occur during object invalidate due to reuse of a helper function. by adding an extra param containing the COW data, this scenario can be avoided fix T7005 Reviewers: bu5hm4n, segfaultxavi, devilhorns Subscribers: cedric, #committers Tags: #efl Maniphest Tasks: T7005 Differential Revision: https://phab.enlightenment.org/D6273 --- src/lib/evas/canvas/evas_object_main.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/src/lib/evas/canvas/evas_object_main.c b/src/lib/evas/canvas/evas_object_main.c index e0856b7561..6b8d4cc66d 100644 --- a/src/lib/evas/canvas/evas_object_main.c +++ b/src/lib/evas/canvas/evas_object_main.c @@ -97,7 +97,7 @@ _evas_object_pointer_data_find(Evas_Object_Protected_Data *obj, } static void -_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Data *pdata); +_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Data *pdata, Evas_Object_Events_Data *ev); static void _evas_device_del_cb(void *data, const Efl_Event *ev) @@ -109,12 +109,11 @@ _evas_device_del_cb(void *data, const Efl_Event *ev) EINA_SAFETY_ON_NULL_RETURN(obj); pdata = _evas_object_pointer_data_find(obj, ev->object); if (!pdata) return; - _evas_object_pointer_grab_del(obj, pdata); + _evas_object_pointer_grab_del(obj, pdata, NULL); } static void -_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, - Evas_Object_Pointer_Data *pdata) +_evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, Evas_Object_Pointer_Data *pdata, Evas_Object_Events_Data *ev) { if ((pdata->mouse_grabbed > 0) && (obj->layer) && (obj->layer->evas)) pdata->evas_pdata->seat->mouse_grabbed -= pdata->mouse_grabbed; @@ -123,9 +122,15 @@ _evas_object_pointer_grab_del(Evas_Object_Protected_Data *obj, pdata->evas_pdata->seat->object.in = eina_list_remove(pdata->evas_pdata->seat->object.in, obj->object); efl_event_callback_del(pdata->evas_pdata->pointer, EFL_EVENT_DEL, _evas_device_del_cb, obj->object); - EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events) - events->pointer_grabs = eina_inlist_remove(events->pointer_grabs, EINA_INLIST_GET(pdata)); - EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events); + /* COW may already be writing */ + if (ev) + ev->pointer_grabs = eina_inlist_remove(ev->pointer_grabs, EINA_INLIST_GET(pdata)); + else + { + EINA_COW_WRITE_BEGIN(evas_object_events_cow, obj->events, Evas_Object_Events_Data, events) + events->pointer_grabs = eina_inlist_remove(events->pointer_grabs, EINA_INLIST_GET(pdata)); + EINA_COW_WRITE_END(evas_object_events_cow, obj->events, events); + } free(pdata); } @@ -1271,7 +1276,7 @@ _efl_canvas_object_efl_object_invalidate(Eo *eo_obj, Evas_Object_Protected_Data _evas_post_event_callback_call(obj->layer->evas->evas, obj->layer->evas, event_id); } EINA_INLIST_FREE(events->pointer_grabs, pdata) - _evas_object_pointer_grab_del(obj, pdata); + _evas_object_pointer_grab_del(obj, pdata, events); EINA_LIST_FREE(events->events_whitelist, dev) efl_event_callback_del(dev, EFL_EVENT_DEL, _whitelist_events_device_remove_cb, obj); } --
