forked from enlightenment/efl
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
This commit is contained in:
parent
3e9f619b1d
commit
1eb24301fd
|
@ -1257,6 +1257,24 @@ EAPI const char *eio_monitor_path_get(Eio_Monitor *monitor);
|
|||
* @beta
|
||||
*/
|
||||
EAPI Eina_Bool eio_monitor_fallback_check(const Eio_Monitor *monitor);
|
||||
|
||||
/**
|
||||
* @brief Check if a monitor has the context about a file or not
|
||||
* @param monitor The Eio_Monitor to check
|
||||
* @param path The path to check
|
||||
* @return EINA_TRUE if there is context, EINA_FALSE otherwise.
|
||||
*
|
||||
* There are Monitors that need context about a file before they can monitor the file correctly.
|
||||
* As an example: If you publish a file in your API before the monitor has this file in his context,
|
||||
* and the file gets deleted as a reaction to this, the monitor will not be able to emit the correct DELETE
|
||||
* event even if the file is in the monitors path.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* @since 1.23
|
||||
* @beta
|
||||
*/
|
||||
EAPI Eina_Bool eio_monitor_has_context(const Eio_Monitor *monitor, const char *path);
|
||||
#endif
|
||||
/**
|
||||
* @}
|
||||
|
|
|
@ -762,6 +762,12 @@ _efl_io_model_efl_model_property_set(Eo *obj,
|
|||
return efl_loop_future_rejected(obj, err);
|
||||
}
|
||||
|
||||
static Eina_Bool
|
||||
_monitor_has_context(Efl_Io_Model_Data *pd, const char *path)
|
||||
{
|
||||
return eio_monitor_has_context(pd->monitor, path);
|
||||
}
|
||||
|
||||
static void
|
||||
_efl_io_model_children_list(void *data, Eina_Array *entries)
|
||||
{
|
||||
|
@ -779,6 +785,7 @@ _efl_io_model_children_list(void *data, Eina_Array *entries)
|
|||
{
|
||||
Efl_Io_Model_Info *mi;
|
||||
|
||||
if (!_monitor_has_context(pd, info->path)) continue;
|
||||
if (_already_added(pd, info->path)) continue;
|
||||
|
||||
if (pd->filter.cb)
|
||||
|
|
|
@ -411,3 +411,17 @@ eio_monitor_path_get(Eio_Monitor *monitor)
|
|||
EINA_SAFETY_ON_NULL_RETURN_VAL(monitor, NULL);
|
||||
return monitor->path;
|
||||
}
|
||||
|
||||
|
||||
EAPI Eina_Bool
|
||||
eio_monitor_has_context(const Eio_Monitor *monitor, const char *path)
|
||||
{
|
||||
if (monitor->fallback)
|
||||
{
|
||||
return eio_monitor_fallback_context_check(monitor, path);
|
||||
}
|
||||
else
|
||||
{
|
||||
return eio_monitor_context_check(monitor, path);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -403,6 +403,10 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
|
|||
eina_hash_del(_fsevent_monitors, monitor->path, backend);
|
||||
}
|
||||
|
||||
Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
/*============================================================================*
|
||||
* API *
|
||||
|
|
|
@ -290,6 +290,11 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
|
|||
eina_hash_del(_inotify_monitors, &backend->hwnd, backend);
|
||||
}
|
||||
|
||||
Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor EINA_UNUSED, const char *path EINA_UNUSED)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/*============================================================================*
|
||||
* API *
|
||||
|
|
|
@ -299,13 +299,30 @@ error:
|
|||
void eio_monitor_backend_del(Eio_Monitor *monitor)
|
||||
{
|
||||
Eio_Monitor_Backend *backend;
|
||||
|
||||
|
||||
backend = monitor->backend;
|
||||
monitor->backend = NULL;
|
||||
|
||||
eina_hash_del(_kevent_monitors, &backend->fd, backend);
|
||||
}
|
||||
|
||||
Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path)
|
||||
{
|
||||
Eio_Monitor_Backend *backend = monitor->backend;
|
||||
Eina_List *l;
|
||||
Eio_File_Info *file;
|
||||
|
||||
EINA_LIST_FOREACH(backend->prev_list, l, file)
|
||||
{
|
||||
if (eina_streq(file->path, path))
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
}
|
||||
return EINA_FALSE;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/*============================================================================*
|
||||
* API *
|
||||
|
|
|
@ -315,6 +315,12 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
|
|||
{
|
||||
eio_monitor_fallback_del(monitor);
|
||||
}
|
||||
|
||||
Eina_Bool eio_monitor_content_check(const Eio_Monitor *monitor, const char *path)
|
||||
{
|
||||
return eio_monitor_fallback_content_check(monitor, path);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void
|
||||
|
@ -330,6 +336,15 @@ eio_monitor_fallback_shutdown(void)
|
|||
timer_hash = NULL;
|
||||
}
|
||||
|
||||
Eina_Bool
|
||||
eio_monitor_fallback_context_check(const Eio_Monitor *monitor, const char *path)
|
||||
{
|
||||
Eio_Monitor_Backend *backend;
|
||||
EINA_SAFETY_ON_FALSE_RETURN_VAL(monitor->fallback, EINA_TRUE);
|
||||
backend = monitor->backend;
|
||||
return !!eina_hash_find(backend->children, path);
|
||||
}
|
||||
|
||||
void
|
||||
eio_monitor_fallback_add(Eio_Monitor *monitor)
|
||||
{
|
||||
|
|
|
@ -423,6 +423,11 @@ void eio_monitor_backend_del(Eio_Monitor *monitor)
|
|||
monitor->backend = NULL;
|
||||
}
|
||||
|
||||
Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path)
|
||||
{
|
||||
return EINA_TRUE;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @endcond
|
||||
|
|
|
@ -486,7 +486,9 @@ void eio_monitor_shutdown(void);
|
|||
void eio_monitor_backend_shutdown(void);
|
||||
void eio_monitor_fallback_shutdown(void);
|
||||
void eio_monitor_backend_add(Eio_Monitor *monitor);
|
||||
Eina_Bool eio_monitor_context_check(const Eio_Monitor *monitor, const char *path);
|
||||
void eio_monitor_fallback_add(Eio_Monitor *monitor);
|
||||
Eina_Bool eio_monitor_fallback_context_check(const Eio_Monitor *monitor, const char *path);
|
||||
|
||||
void eio_monitor_backend_del(Eio_Monitor *monitor);
|
||||
void eio_monitor_fallback_del(Eio_Monitor *monitor);
|
||||
|
|
Loading…
Reference in New Issue