From 826cd7cb5e6e6a0a53dbe1c687de072dd8fd2f6c Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Thu, 1 Dec 2016 16:12:37 -0200 Subject: [PATCH 1/4] Efl.Input: Reset the Efl.Input object as soon as possible. By doing this the pd->device reference is unrefed and deleted if no one else is holding a reference to it. --- src/lib/evas/canvas/efl_input_focus.c | 2 +- src/lib/evas/canvas/efl_input_key.c | 2 +- src/lib/evas/canvas/efl_input_pointer.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/lib/evas/canvas/efl_input_focus.c b/src/lib/evas/canvas/efl_input_focus.c index 0bf4912364..da2aba6474 100644 --- a/src/lib/evas/canvas/efl_input_focus.c +++ b/src/lib/evas/canvas/efl_input_focus.c @@ -25,6 +25,7 @@ _del_hook(Eo *evt) } efl_reuse(evt); s_cached_event = evt; + efl_input_reset(s_cached_event); } else { @@ -136,7 +137,6 @@ _efl_input_focus_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd E { evt = s_cached_event; s_cached_event = NULL; - efl_input_reset(evt); efl_parent_set(evt, owner); } else diff --git a/src/lib/evas/canvas/efl_input_key.c b/src/lib/evas/canvas/efl_input_key.c index 685b6b3b12..869b5597dc 100644 --- a/src/lib/evas/canvas/efl_input_key.c +++ b/src/lib/evas/canvas/efl_input_key.c @@ -25,6 +25,7 @@ _del_hook(Eo *evt) } efl_reuse(evt); s_cached_event = evt; + efl_input_reset(s_cached_event); } else { @@ -44,7 +45,6 @@ _efl_input_key_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd EIN { evt = s_cached_event; s_cached_event = NULL; - efl_input_reset(evt); efl_parent_set(evt, owner); } else diff --git a/src/lib/evas/canvas/efl_input_pointer.c b/src/lib/evas/canvas/efl_input_pointer.c index 4ec9af04e7..109906e570 100644 --- a/src/lib/evas/canvas/efl_input_pointer.c +++ b/src/lib/evas/canvas/efl_input_pointer.c @@ -36,6 +36,7 @@ _del_hook(Eo *evt) } efl_reuse(evt); s_cached_event = evt; + efl_input_reset(s_cached_event); } else { @@ -55,7 +56,6 @@ _efl_input_pointer_efl_input_event_instance_get(Eo *klass EINA_UNUSED, void *_pd { evt = s_cached_event; s_cached_event = NULL; - efl_input_reset(evt); efl_parent_set(evt, owner); } else From 81782414dfba9a8a69ea42a4dd5b01fc19170d88 Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Fri, 2 Dec 2016 11:16:33 -0200 Subject: [PATCH 2/4] Eo: Add efl_replace() function. This new function adds a new way to safely replace Eo pointer values. --- src/lib/eo/Eo.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h index 8c815447c3..244478b0ae 100644 --- a/src/lib/eo/Eo.h +++ b/src/lib/eo/Eo.h @@ -1333,6 +1333,28 @@ EAPI int efl_callbacks_cmp(const Efl_Callback_Array_Item *a, const Efl_Callback_ efl_event_callback_array_priority_add(obj, array, \ EFL_CALLBACK_PRIORITY_DEFAULT, data) +/** + * @def Replace the previously Eo pointer with new content. + * + * @param storage The object to replace the old reference. It can not be @c NULL. + * @param new_obj The new object. It may be @c NULL. + * + * The string pointed by @c storage must be previously an Eo or + * @c NULL and it will be efl_unref(). The @a new_obj will be passed + * to efl_ref() and then assigned to @c *storage. + * + * @see efl_ref() + * @see efl_unref() + */ +static inline void +efl_replace(Eo **storage, Eo *new_obj) +{ + if (!storage || *storage == new_obj) return; + efl_ref(new_obj); + efl_unref(*storage); + *storage = new_obj; +} + /** * @} */ From 345fec274730ff8b14f41009fba89767d17f38fa Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Thu, 1 Dec 2016 16:13:11 -0200 Subject: [PATCH 3/4] Efl.Input: Properly unref the device if a new device is set. The old device must be unrefed, otherwise it will leak. --- src/lib/evas/canvas/efl_input_focus.c | 2 +- src/lib/evas/canvas/efl_input_hold.c | 2 +- src/lib/evas/canvas/efl_input_key.c | 2 +- src/lib/evas/canvas/efl_input_pointer.c | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/evas/canvas/efl_input_focus.c b/src/lib/evas/canvas/efl_input_focus.c index da2aba6474..b76a83660e 100644 --- a/src/lib/evas/canvas/efl_input_focus.c +++ b/src/lib/evas/canvas/efl_input_focus.c @@ -83,7 +83,7 @@ _efl_input_focus_efl_input_event_device_set(Eo *obj EINA_UNUSED, Efl_Input_Focus_Data *pd, Efl_Input_Device *device) { - pd->device = efl_ref(device); + efl_replace(&pd->device, device); } EOLIAN static Efl_Input_Device * diff --git a/src/lib/evas/canvas/efl_input_hold.c b/src/lib/evas/canvas/efl_input_hold.c index 774af38ed6..ac3dfbf8b0 100644 --- a/src/lib/evas/canvas/efl_input_hold.c +++ b/src/lib/evas/canvas/efl_input_hold.c @@ -26,7 +26,7 @@ _efl_input_hold_hold_get(Eo *obj EINA_UNUSED, Efl_Input_Hold_Data *pd) EOLIAN static void _efl_input_hold_efl_input_event_device_set(Eo *obj EINA_UNUSED, Efl_Input_Hold_Data *pd, Efl_Input_Device *dev) { - pd->device = efl_ref(dev); + efl_replace(&pd->device, dev); } EOLIAN static Efl_Input_Device * diff --git a/src/lib/evas/canvas/efl_input_key.c b/src/lib/evas/canvas/efl_input_key.c index 869b5597dc..984d82caaa 100644 --- a/src/lib/evas/canvas/efl_input_key.c +++ b/src/lib/evas/canvas/efl_input_key.c @@ -230,7 +230,7 @@ _efl_input_key_efl_input_event_event_flags_get(Eo *obj EINA_UNUSED, Efl_Input_Ke EOLIAN static void _efl_input_key_efl_input_event_device_set(Eo *obj EINA_UNUSED, Efl_Input_Key_Data *pd, Efl_Input_Device *dev) { - pd->device = efl_ref(dev); + efl_replace(&pd->device, dev); } EOLIAN static Efl_Input_Device * diff --git a/src/lib/evas/canvas/efl_input_pointer.c b/src/lib/evas/canvas/efl_input_pointer.c index 109906e570..397beef3ae 100644 --- a/src/lib/evas/canvas/efl_input_pointer.c +++ b/src/lib/evas/canvas/efl_input_pointer.c @@ -224,7 +224,7 @@ _efl_input_pointer_delta_get(Eo *obj EINA_UNUSED, Efl_Input_Pointer_Data *pd, in EOLIAN static void _efl_input_pointer_efl_input_event_device_set(Eo *obj EINA_UNUSED, Efl_Input_Pointer_Data *pd, Efl_Input_Device *dev) { - pd->device = efl_ref(dev); + efl_replace(&pd->device, dev); } EOLIAN static Efl_Input_Device * From e0af7384a2edf4d6ebb33bec88dc72c672b84150 Mon Sep 17 00:00:00 2001 From: Guilherme Iscaro Date: Thu, 1 Dec 2016 16:14:11 -0200 Subject: [PATCH 4/4] Efl.Input.Device: Do not ref/unref devices children devices. When a mouse/keyboard is removed from its seat under the Wayland backend, it was not immediately deleted from EFL, because its parent was keeping a reference to it. Since the mouse/keyboard is no longer present in the system there's no reason the keep them around. To prevent this delayed deletion do not ref/unref them when the parent is set. --- src/lib/efl/interfaces/efl_input_device.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/lib/efl/interfaces/efl_input_device.c b/src/lib/efl/interfaces/efl_input_device.c index bb59fc6447..f20063fda2 100644 --- a/src/lib/efl/interfaces/efl_input_device.c +++ b/src/lib/efl/interfaces/efl_input_device.c @@ -28,7 +28,11 @@ _efl_input_device_efl_object_destructor(Eo *obj, Efl_Input_Device_Data *pd) { Efl_Input_Device_Data *child = efl_data_scope_get(eo_child, EFL_INPUT_DEVICE_CLASS); child->parent = NULL; - efl_unref(eo_child); + } + if (pd->parent) + { + Efl_Input_Device_Data *p = efl_data_scope_get(pd->parent, EFL_INPUT_DEVICE_CLASS); + p->children = eina_list_remove(p->children, obj); } efl_unref(pd->source); @@ -128,14 +132,12 @@ _efl_input_device_parent_set(Eo *obj, Efl_Input_Device_Data *pd, Efl_Input_Devic { Efl_Input_Device_Data *p = efl_data_scope_get(pd->parent, EFL_INPUT_DEVICE_CLASS); p->children = eina_list_remove(p->children, obj); - efl_unref(obj); } pd->parent = parent; if (parent) { Efl_Input_Device_Data *p = efl_data_scope_get(parent, EFL_INPUT_DEVICE_CLASS); p->children = eina_list_append(p->children, obj); - efl_ref(obj); } }