summaryrefslogtreecommitdiff
path: root/src/lib/evas/canvas/evas_device.c
diff options
context:
space:
mode:
authorJean-Philippe Andre <jp.andre@samsung.com>2017-09-28 11:27:56 +0900
committerJean-Philippe Andre <jp.andre@samsung.com>2017-09-28 12:30:36 +0900
commit96d94e0076773d6b29107035dc61f5df01a3347f (patch)
treee5795f208a5dd9c7d04da8edfb3ae9e07730506b /src/lib/evas/canvas/evas_device.c
parent3dc140abfb30b94eae3093fd565f2f111c03be04 (diff)
evas: Fix dangling references with input devices
This solves issues with efl_input_dup() which didn't properly give a reference to the caller, resulting in dangling eo ids. Note: This may trigger leaks (instead of invalid refs), but this now actually reflects the meaning of @owned. This should work with bindings and C API users should know to call efl_unref(). This patch is the reason for the previous improvements on eo_debug. @fix
Diffstat (limited to 'src/lib/evas/canvas/evas_device.c')
-rw-r--r--src/lib/evas/canvas/evas_device.c23
1 files changed, 14 insertions, 9 deletions
diff --git a/src/lib/evas/canvas/evas_device.c b/src/lib/evas/canvas/evas_device.c
index 7f93b77..9c740c0 100644
--- a/src/lib/evas/canvas/evas_device.c
+++ b/src/lib/evas/canvas/evas_device.c
@@ -460,7 +460,7 @@ evas_device_seat_id_get(const Evas_Device *dev)
460void 460void
461_evas_device_cleanup(Evas *eo_e) 461_evas_device_cleanup(Evas *eo_e)
462{ 462{
463 Eina_List *cpy; 463 Eina_List *cpy, *deleted = NULL;
464 Evas_Device *dev; 464 Evas_Device *dev;
465 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS); 465 Evas_Public_Data *e = efl_data_scope_get(eo_e, EVAS_CANVAS_CLASS);
466 466
@@ -473,19 +473,26 @@ _evas_device_cleanup(Evas *eo_e)
473 } 473 }
474 474
475 /* If the device is deleted, _del_cb will remove the device 475 /* If the device is deleted, _del_cb will remove the device
476 from the devices list. */ 476 * from the devices list. Ensure we delete them only once, and only if this
477 * Evas is the owner, otherwise we would kill external references (eg.
478 * from efl_input_dup()). */
477again: 479again:
478 e->devices_modified = EINA_FALSE; 480 e->devices_modified = EINA_FALSE;
479 cpy = eina_list_clone(e->devices); 481 cpy = eina_list_clone(e->devices);
480 EINA_LIST_FREE(cpy, dev) 482 EINA_LIST_FREE(cpy, dev)
481 { 483 {
482 evas_device_del(dev); 484 if (!eina_list_data_find(deleted, dev) && (efl_parent_get(dev) == eo_e))
483 if (e->devices_modified)
484 { 485 {
485 eina_list_free(cpy); 486 evas_device_del(dev);
486 goto again; 487 deleted = eina_list_append(deleted, dev);
488 if (e->devices_modified)
489 {
490 eina_list_free(cpy);
491 goto again;
492 }
487 } 493 }
488 } 494 }
495 eina_list_free(deleted);
489 496
490 /* Not all devices were deleted. The user probably will unref them later. 497 /* Not all devices were deleted. The user probably will unref them later.
491 Since Evas will be deleted, remove the del callback from them and 498 Since Evas will be deleted, remove the del callback from them and
@@ -493,9 +500,7 @@ again:
493 */ 500 */
494 EINA_LIST_FREE(e->devices, dev) 501 EINA_LIST_FREE(e->devices, dev)
495 { 502 {
496 efl_event_callback_call(e->evas, 503 efl_event_callback_call(e->evas, EFL_CANVAS_EVENT_DEVICE_REMOVED, dev);
497 EFL_CANVAS_EVENT_DEVICE_REMOVED,
498 dev);
499 efl_event_callback_del(dev, EFL_EVENT_DEL, _del_cb, e); 504 efl_event_callback_del(dev, EFL_EVENT_DEL, _del_cb, e);
500 } 505 }
501} 506}