summaryrefslogtreecommitdiff
path: root/src/lib/eio
diff options
context:
space:
mode:
authorMike Blumenkrantz <zmike@samsung.com>2019-08-23 13:21:58 -0400
committerMike Blumenkrantz <zmike@samsung.com>2019-08-23 13:38:32 -0400
commit0b8605c35d89e54428b96ff04ff759208b896d7c (patch)
treefd1a781c062aef252c914af46a73af8fbb3133d6 /src/lib/eio
parent6b3d430f1262f563d940aea52cd7de613a7127c1 (diff)
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
Diffstat (limited to 'src/lib/eio')
-rw-r--r--src/lib/eio/efl_io_model.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/src/lib/eio/efl_io_model.c b/src/lib/eio/efl_io_model.c
index 824a27c..e6b6149 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)
154 return EINA_TRUE; 154 return EINA_TRUE;
155} 155}
156 156
157static Eina_Bool 157static void
158_efl_model_evt_deleted_ecore_cb(void *data, int type, void *event) 158_model_child_remove(Efl_Io_Model_Data *pd, Eina_Stringshare *path)
159{ 159{
160 Efl_Io_Model_Info *mi; 160 Efl_Io_Model_Info *mi;
161 Eina_List *l; 161 Eina_List *l;
162 Eio_Monitor_Event *ev = event; 162 Efl_Io_Model *obj = pd->self;
163 Efl_Io_Model *obj;
164 Efl_Io_Model_Data *pd = data;
165 Eina_Stringshare *spath = NULL;
166 Efl_Model_Children_Event cevt = { 0 }; 163 Efl_Model_Children_Event cevt = { 0 };
167 unsigned int i = 0; 164 unsigned int i = 0;
168 165
169 if (type != EIO_MONITOR_DIRECTORY_DELETED && type != EIO_MONITOR_FILE_DELETED)
170 return EINA_TRUE;
171
172 if (ev->monitor != pd->monitor) return EINA_TRUE;
173
174 obj = pd->self;
175
176 spath = eina_stringshare_add(ev->filename);
177
178 // FIXME: Linear search is pretty slow 166 // FIXME: Linear search is pretty slow
179 EINA_LIST_FOREACH(pd->files, l, mi) 167 EINA_LIST_FOREACH(pd->files, l, mi)
180 { 168 {
181 if (mi->path == spath) 169 if (mi->path == path)
182 break ; 170 break ;
183 ++i; 171 ++i;
184 } 172 }
185 173
186 if (i >= eina_list_count(pd->files)) 174 if (i >= eina_list_count(pd->files))
187 goto end; 175 return;
188 176
189 cevt.index = i; 177 cevt.index = i;
190 cevt.child = mi->object; 178 cevt.child = mi->object;
@@ -197,8 +185,22 @@ _efl_model_evt_deleted_ecore_cb(void *data, int type, void *event)
197 185
198 // This will only trigger the data destruction if no object is referencing them. 186 // This will only trigger the data destruction if no object is referencing them.
199 _efl_io_model_info_free(mi, EINA_FALSE); 187 _efl_io_model_info_free(mi, EINA_FALSE);
188}
200 189
201 end: 190static Eina_Bool
191_efl_model_evt_deleted_ecore_cb(void *data, int type, void *event)
192{
193 Eio_Monitor_Event *ev = event;
194 Efl_Io_Model_Data *pd = data;
195 Eina_Stringshare *spath = NULL;
196
197 if (type != EIO_MONITOR_DIRECTORY_DELETED && type != EIO_MONITOR_FILE_DELETED)
198 return EINA_TRUE;
199
200 if (ev->monitor != pd->monitor) return EINA_TRUE;
201
202 spath = eina_stringshare_add(ev->filename);
203 _model_child_remove(pd, spath);
202 eina_stringshare_del(spath); 204 eina_stringshare_del(spath);
203 205
204 return EINA_TRUE; 206 return EINA_TRUE;
@@ -221,7 +223,12 @@ static void
221_eio_done_unlink_cb(void *data, Eio_File *handler EINA_UNUSED) 223_eio_done_unlink_cb(void *data, Eio_File *handler EINA_UNUSED)
222{ 224{
223 Efl_Io_Model *child = data; 225 Efl_Io_Model *child = data;
226 Efl_Io_Model_Data *child_pd, *pd;
227
228 child_pd = efl_data_scope_get(child, MY_CLASS);
229 pd = efl_data_scope_get(efl_parent_get(child), MY_CLASS);
224 230
231 _model_child_remove(pd, child_pd->path);
225 _eio_del_cleanup(child); 232 _eio_del_cleanup(child);
226} 233}
227 234