zmike pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=0b8605c35d89e54428b96ff04ff759208b896d7c

commit 0b8605c35d89e54428b96ff04ff759208b896d7c
Author: Mike Blumenkrantz <zm...@samsung.com>
Date:   Fri Aug 23 13:21:58 2019 -0400

    efl/io: fix race condition with child model deletion
    
    Summary:
    if an event is emitted for a child that is added to the model during a
    call to _efl_io_model_children_list(), it's possible that this child
    will never be detected by the model's monitor/sentry if it is deleted
    before the monitor can detect it, which means there will never be a
    corresponding eio event emitted
    
    in this case, ensure that we manually remove this child from the model
    since we know we've just deleted it
    
    this fixes reliability issues with efl io model monitor unit test
    
    @fix
    
    Reviewers: cedric
    
    Reviewed By: cedric
    
    Subscribers: #reviewers, #committers
    
    Tags: #efl
    
    Differential Revision: https://phab.enlightenment.org/D9708
---
 src/lib/eio/efl_io_model.c | 43 +++++++++++++++++++++++++------------------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/src/lib/eio/efl_io_model.c b/src/lib/eio/efl_io_model.c
index 824a27c8a8..e6b6149288 100644
--- a/src/lib/eio/efl_io_model.c
+++ b/src/lib/eio/efl_io_model.c
@@ -154,37 +154,25 @@ _efl_model_evt_added_ecore_cb(void *data, int type, void 
*event)
    return EINA_TRUE;
 }
 
-static Eina_Bool
-_efl_model_evt_deleted_ecore_cb(void *data, int type, void *event)
+static void
+_model_child_remove(Efl_Io_Model_Data *pd, Eina_Stringshare *path)
 {
    Efl_Io_Model_Info *mi;
    Eina_List *l;
-   Eio_Monitor_Event *ev = event;
-   Efl_Io_Model *obj;
-   Efl_Io_Model_Data *pd = data;
-   Eina_Stringshare *spath = NULL;
+   Efl_Io_Model *obj = pd->self;
    Efl_Model_Children_Event cevt = { 0 };
    unsigned int i = 0;
 
-   if (type != EIO_MONITOR_DIRECTORY_DELETED && type != 
EIO_MONITOR_FILE_DELETED)
-     return EINA_TRUE;
-
-   if (ev->monitor != pd->monitor) return EINA_TRUE;
-
-   obj = pd->self;
-
-   spath = eina_stringshare_add(ev->filename);
-
    // FIXME: Linear search is pretty slow
    EINA_LIST_FOREACH(pd->files, l, mi)
      {
-        if (mi->path == spath)
+        if (mi->path == path)
           break ;
         ++i;
      }
 
    if (i >= eina_list_count(pd->files))
-     goto end;
+     return;
 
    cevt.index = i;
    cevt.child = mi->object;
@@ -197,8 +185,22 @@ _efl_model_evt_deleted_ecore_cb(void *data, int type, void 
*event)
 
    // This will only trigger the data destruction if no object is referencing 
them.
    _efl_io_model_info_free(mi, EINA_FALSE);
+}
 
- end:
+static Eina_Bool
+_efl_model_evt_deleted_ecore_cb(void *data, int type, void *event)
+{
+   Eio_Monitor_Event *ev = event;
+   Efl_Io_Model_Data *pd = data;
+   Eina_Stringshare *spath = NULL;
+
+   if (type != EIO_MONITOR_DIRECTORY_DELETED && type != 
EIO_MONITOR_FILE_DELETED)
+     return EINA_TRUE;
+
+   if (ev->monitor != pd->monitor) return EINA_TRUE;
+
+   spath = eina_stringshare_add(ev->filename);
+   _model_child_remove(pd, spath);
    eina_stringshare_del(spath);
 
    return EINA_TRUE;
@@ -221,7 +223,12 @@ static void
 _eio_done_unlink_cb(void *data, Eio_File *handler EINA_UNUSED)
 {
    Efl_Io_Model *child = data;
+   Efl_Io_Model_Data *child_pd, *pd;
+
+   child_pd = efl_data_scope_get(child, MY_CLASS);
+   pd = efl_data_scope_get(efl_parent_get(child), MY_CLASS);
 
+   _model_child_remove(pd, child_pd->path);
    _eio_del_cleanup(child);
 }
 

-- 


Reply via email to