eio/poll: avoid ever dereferencing the backend's parent in a thread

Summary:
when a monitor is destroyed, it unconditionally and immediately deletes
the monitor struct. this means that as soon as the monitor is dead, the
backend must never access the parent pointer again if its lifetime exceeds
the lifetime of the monitor (such as in threads)

the only member of the monitor data used by the fallback monitor is the
monitor path, so we can just copy it to the fallback data to avoid ever
needing to dereference this pointer

fixes reliability issues with efl sentry unit tests

@fix

Depends on D9708

Reviewers: cedric

Reviewed By: cedric

Subscribers: #reviewers, #committers

Tags: #efl

Differential Revision: https://phab.enlightenment.org/D9709
This commit is contained in:
Mike Blumenkrantz 2019-08-23 13:22:04 -04:00
parent 0b8605c35d
commit 42704eccc7
1 changed files with 8 additions and 8 deletions

View File

@ -39,6 +39,7 @@ struct _Eio_Monitor_Stat
struct _Eio_Monitor_Backend
{
Eio_Monitor *parent;
Eina_Stringshare *path;
Eina_Stat self;
Eina_Hash *children;
@ -74,17 +75,14 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
else
est = alloca(sizeof (Eina_Stat));
if (!backend->parent)
return;
if (_eio_stat(backend->parent->path, &st))
if (_eio_stat(backend->path, &st))
{
if (backend->initialised && !backend->destroyed)
{
ecore_thread_main_loop_begin();
deleted = backend->delete_me;
if (!deleted)
_eio_monitor_send(backend->parent, backend->parent->path, EIO_MONITOR_SELF_DELETED);
_eio_monitor_send(backend->parent, backend->path, EIO_MONITOR_SELF_DELETED);
ecore_thread_main_loop_end();
backend->destroyed = EINA_TRUE;
}
@ -137,12 +135,12 @@ _eio_monitor_fallback_heavy_cb(void *data, Ecore_Thread *thread)
ecore_thread_main_loop_begin();
deleted = backend->delete_me;
if (!deleted)
_eio_monitor_send(backend->parent, backend->parent->path, event);
_eio_monitor_send(backend->parent, backend->path, event);
ecore_thread_main_loop_end();
if (deleted) return;
}
it = eina_file_direct_ls(backend->parent->path);
it = eina_file_direct_ls(backend->path);
EINA_ITERATOR_FOREACH(it, info)
{
Eio_Monitor_Stat *cmp;
@ -344,6 +342,7 @@ eio_monitor_fallback_add(Eio_Monitor *monitor)
backend->children = eina_hash_string_superfast_new(free);
backend->parent = monitor;
backend->path = eina_stringshare_ref(monitor->path);
monitor->backend = backend;
monitor->fallback = EINA_TRUE;
@ -370,6 +369,7 @@ eio_monitor_fallback_del(Eio_Monitor *monitor)
if (backend->timer) ecore_timer_del(backend->timer);
eina_hash_set(timer_hash, &backend, NULL);
backend->timer = NULL;
backend->parent = NULL;
if (backend->work)
{
@ -377,7 +377,7 @@ eio_monitor_fallback_del(Eio_Monitor *monitor)
return;
}
backend->parent = NULL;
eina_stringshare_del(backend->path);
eina_hash_free(backend->children);
free(backend);
}