summaryrefslogtreecommitdiff
path: root/src/lib/eio
diff options
context:
space:
mode:
authorMarcel Hollerbach <mail@marcel-hollerbach.de>2019-09-18 11:32:08 +0200
committerCedric Bail <cedric.bail@free.fr>2019-09-19 14:50:42 -0700
commit1eb24301fd517952e7e2c31a19c523bd4bf2e06e (patch)
treea92b6439937c74caaa42485fed69778f7f072303 /src/lib/eio
parent3e9f619b1d3fa3c66641292c11992e5730307b13 (diff)
efl_io_model: next try to fix this race condition
what is happening is that a file gets announced through eio_model listing code, at this point of time, the monitor does not yet know about the file. If the file now gets deleted between the annoncing and the learning of the file from the monitor, then the file got an ADD event, but no DEL event. Which is a bug. With this commit there is a new API which asks the monitor if the file already has the knowledge about the files existance, or not. A few monitors like win32 inotify or cocoa do not have context about the file directly, if the OS is now having the same bug, then we are again in trouble, however, we canot do anything about that. In the case of kevent or poll, this asks the context of the monitor if the file is already there. Reviewed-by: Cedric BAIL <cedric.bail@free.fr> Differential Revision: https://phab.enlightenment.org/D10006
Diffstat (limited to 'src/lib/eio')
-rw-r--r--src/lib/eio/Eio_Legacy.h18
-rw-r--r--src/lib/eio/efl_io_model.c7
-rw-r--r--src/lib/eio/eio_monitor.c14
-rw-r--r--src/lib/eio/eio_monitor_cocoa.c4
-rw-r--r--src/lib/eio/eio_monitor_inotify.c5
-rw-r--r--src/lib/eio/eio_monitor_kevent.c19
-rw-r--r--src/lib/eio/eio_monitor_poll.c15
-rw-r--r--src/lib/eio/eio_monitor_win32.c5
-rw-r--r--src/lib/eio/eio_private.h2
9 files changed, 88 insertions, 1 deletions
diff --git a/src/lib/eio/Eio_Legacy.h b/src/lib/eio/Eio_Legacy.h
index 50140ed..c44340c 100644
--- a/src/lib/eio/Eio_Legacy.h
+++ b/src/lib/eio/Eio_Legacy.h
@@ -1257,6 +1257,24 @@ EAPI const char *eio_monitor_path_get(Eio_Monitor *monitor);
1257 * @beta 1257 * @beta
1258 */ 1258 */
1259EAPI Eina_Bool eio_monitor_fallback_check(const Eio_Monitor *monitor); 1259EAPI Eina_Bool eio_monitor_fallback_check(const Eio_Monitor *monitor);
1260
1261/**
1262 * @brief Check if a monitor has the context about a file or not
1263 * @param monitor The Eio_Monitor to check
1264 * @param path The path to check
1265 * @return EINA_TRUE if there is context, EINA_FALSE otherwise.
1266 *
1267 * There are Monitors that need context about a file before they can monitor the file correctly.
1268 * As an example: If you publish a file in your API before the monitor has this file in his context,
1269 * and the file gets deleted as a reaction to this, the monitor will not be able to emit the correct DELETE
1270 * event even if the file is in the monitors path.
1271 *
1272 * In case the monitor does not yet have context, you can be sure that the monitor will bring up an FILE_ADD event about that file.
1273 *
1274 * @since 1.23
1275 * @beta
1276 */
1277EAPI Eina_Bool eio_monitor_has_context(const Eio_Monitor *monitor, const char *path);
1260#endif 1278#endif
1261/** 1279/**
1262 * @} 1280 * @}
diff --git a/src/lib/eio/efl_io_model.c b/src/lib/eio/efl_io_model.c
index e6b6149..88c32b1 100644
--- a/src/lib/eio/efl_io_model.c
+++ b/src/lib/eio/efl_io_model.c
@@ -762,6 +762,12 @@ _efl_io_model_efl_model_property_set(Eo *obj,
762 return efl_loop_future_rejected(obj, err); 762 return efl_loop_future_rejected(obj, err);
763} 763}
764 764
765static Eina_Bool
766_monitor_has_context(Efl_Io_Model_Data *pd, const char *path)
767{
768 return eio_monitor_has_context(pd->monitor, path);
769}
770
765static void 771static void
766_efl_io_model_children_list(void *data, Eina_Array *entries) 772_efl_io_model_children_list(void *data, Eina_Array *entries)
767{ 773{
@@ -779,6 +785,7 @@ _efl_io_model_children_list(void *data, Eina_Array *entries)
779 { 785 {
780 Efl_Io_Model_Info *mi; 786 Efl_Io_Model_Info *mi;
781 787
788 if (!_monitor_has_context(pd, info->path)) continue;
782 if (_already_added(pd, info->path)) continue; 789 if (_already_added(pd, info->path)) continue;
783 790
784 if (pd->filter.cb) 791 if (pd->filter.cb)
diff --git a/src/lib/eio/eio_monitor.c b/src/lib/eio/eio_monitor.c
index bc1ed07..64eab21 100644
--- a/src/lib/eio/eio_monitor.c
+++ b/src/lib/eio/eio_monitor.c
@@ -411,3 +411,17 @@ eio_monitor_path_get(Eio_Monitor *monitor)
411 EINA_SAFETY_ON_NULL_RETURN_VAL(monitor, NULL); 411 EINA_SAFETY_ON_NULL_RETURN_VAL(monitor, NULL);
412 return monitor->path; 412 return monitor->path;
413} 413}
414
415
416EAPI Eina_Bool
417eio_monitor_has_context(const Eio_Monitor *monitor, const char *path)
418{
419 if (monitor->fallback)
420 {
421 return eio_monitor_fallback_context_check(monitor, path);
422 }
423 else
424 {
425 return eio_monitor_context_check(monitor, path);
426 }
427}
diff --git a/src/lib/eio/eio_monitor_cocoa.c b/src/lib/eio/eio_monitor_cocoa.c
index d491de4..be35496 100644
--- a/src/lib/eio/eio_monitor_cocoa.c
+++ b/src/lib/eio/eio_monitor_cocoa.c
@@ -403,6 +403,10 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
403 eina_hash_del(_fsevent_monitors, monitor->path, backend); 403 eina_hash_del(_fsevent_monitors, monitor->path, backend);
404} 404}
405 405
406Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path)
407{
408 return EINA_TRUE;
409}
406 410
407/*============================================================================* 411/*============================================================================*
408 * API * 412 * API *
diff --git a/src/lib/eio/eio_monitor_inotify.c b/src/lib/eio/eio_monitor_inotify.c
index f3a83be..e266877 100644
--- a/src/lib/eio/eio_monitor_inotify.c
+++ b/src/lib/eio/eio_monitor_inotify.c
@@ -290,6 +290,11 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
290 eina_hash_del(_inotify_monitors, &backend->hwnd, backend); 290 eina_hash_del(_inotify_monitors, &backend->hwnd, backend);
291} 291}
292 292
293Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor EINA_UNUSED, const char *path EINA_UNUSED)
294{
295 return EINA_TRUE;
296}
297
293 298
294/*============================================================================* 299/*============================================================================*
295 * API * 300 * API *
diff --git a/src/lib/eio/eio_monitor_kevent.c b/src/lib/eio/eio_monitor_kevent.c
index 7a54f1d..b0ab7f7 100644
--- a/src/lib/eio/eio_monitor_kevent.c
+++ b/src/lib/eio/eio_monitor_kevent.c
@@ -299,13 +299,30 @@ error:
299void eio_monitor_backend_del(Eio_Monitor *monitor) 299void eio_monitor_backend_del(Eio_Monitor *monitor)
300{ 300{
301 Eio_Monitor_Backend *backend; 301 Eio_Monitor_Backend *backend;
302 302
303 backend = monitor->backend; 303 backend = monitor->backend;
304 monitor->backend = NULL; 304 monitor->backend = NULL;
305 305
306 eina_hash_del(_kevent_monitors, &backend->fd, backend); 306 eina_hash_del(_kevent_monitors, &backend->fd, backend);
307} 307}
308 308
309Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path)
310{
311 Eio_Monitor_Backend *backend = monitor->backend;
312 Eina_List *l;
313 Eio_File_Info *file;
314
315 EINA_LIST_FOREACH(backend->prev_list, l, file)
316 {
317 if (eina_streq(file->path, path))
318 {
319 return EINA_TRUE;
320 }
321 }
322 return EINA_FALSE;
323}
324
325
309 326
310/*============================================================================* 327/*============================================================================*
311 * API * 328 * API *
diff --git a/src/lib/eio/eio_monitor_poll.c b/src/lib/eio/eio_monitor_poll.c
index 2a35b6f..aae582f 100644
--- a/src/lib/eio/eio_monitor_poll.c
+++ b/src/lib/eio/eio_monitor_poll.c
@@ -315,6 +315,12 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
315{ 315{
316 eio_monitor_fallback_del(monitor); 316 eio_monitor_fallback_del(monitor);
317} 317}
318
319Eina_Bool eio_monitor_content_check(const Eio_Monitor *monitor, const char *path)
320{
321 return eio_monitor_fallback_content_check(monitor, path);
322}
323
318#endif 324#endif
319 325
320void 326void
@@ -330,6 +336,15 @@ eio_monitor_fallback_shutdown(void)
330 timer_hash = NULL; 336 timer_hash = NULL;
331} 337}
332 338
339Eina_Bool
340eio_monitor_fallback_context_check(const Eio_Monitor *monitor, const char *path)
341{
342 Eio_Monitor_Backend *backend;
343 EINA_SAFETY_ON_FALSE_RETURN_VAL(monitor->fallback, EINA_TRUE);
344 backend = monitor->backend;
345 return !!eina_hash_find(backend->children, path);
346}
347
333void 348void
334eio_monitor_fallback_add(Eio_Monitor *monitor) 349eio_monitor_fallback_add(Eio_Monitor *monitor)
335{ 350{
diff --git a/src/lib/eio/eio_monitor_win32.c b/src/lib/eio/eio_monitor_win32.c
index a2c45de..04d8534 100644
--- a/src/lib/eio/eio_monitor_win32.c
+++ b/src/lib/eio/eio_monitor_win32.c
@@ -423,6 +423,11 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
423 monitor->backend = NULL; 423 monitor->backend = NULL;
424} 424}
425 425
426Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path)
427{
428 return EINA_TRUE;
429}
430
426 431
427/** 432/**
428 * @endcond 433 * @endcond
diff --git a/src/lib/eio/eio_private.h b/src/lib/eio/eio_private.h
index aa75336..e8f9c85 100644
--- a/src/lib/eio/eio_private.h
+++ b/src/lib/eio/eio_private.h
@@ -486,7 +486,9 @@ void eio_monitor_shutdown(void);
486void eio_monitor_backend_shutdown(void); 486void eio_monitor_backend_shutdown(void);
487void eio_monitor_fallback_shutdown(void); 487void eio_monitor_fallback_shutdown(void);
488void eio_monitor_backend_add(Eio_Monitor *monitor); 488void eio_monitor_backend_add(Eio_Monitor *monitor);
489Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path);
489void eio_monitor_fallback_add(Eio_Monitor *monitor); 490void eio_monitor_fallback_add(Eio_Monitor *monitor);
491Eina_Bool eio_monitor_fallback_context_check(const Eio_Monitor *monitor, const char *path);
490 492
491void eio_monitor_backend_del(Eio_Monitor *monitor); 493void eio_monitor_backend_del(Eio_Monitor *monitor);
492void eio_monitor_fallback_del(Eio_Monitor *monitor); 494void eio_monitor_fallback_del(Eio_Monitor *monitor);