summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Foreman <derekf@osg.samsung.com>2018-07-10 09:43:55 -0400
committerMike Blumenkrantz <zmike@samsung.com>2018-07-10 09:43:55 -0400
commit35210b553dce1f2fda7090025318e34919c47712 (patch)
tree67d0576ef72693894c13f407c659b364360c8d53
parentb27ecc58ddd05465b441682e2a20fd06f66a6c48 (diff)
downloadefl-35210b553dce1f2fda7090025318e34919c47712.tar.gz
eio_model: Fix deleting files that don't have assigned types yet
Summary: Trying to delete a file from a creation notification callback can fail. Sometimes the eio model test would sit forever in select() waiting for events that will never occur because of this. This happens since d84a268a71b09d585f1672b44ade698d7babe28d broke deleting of files that haven't yet been assigned a type. Before this commit a delete_me flag would be set before attempting to build a stat buf asynchronously, and then on completion the file would be deleted. I think this was changed because that could potentially race with other async calls and delete the file sooner than expected. So instead of reverting I've made a special delete path that shouldn't race with non-delete paths. Reviewers: devilhorns, zmike Reviewed By: zmike Subscribers: cedric, #committers, zmike Tags: #efl Differential Revision: https://phab.enlightenment.org/D6543
-rw-r--r--src/lib/eio/eio_model.c42
-rw-r--r--src/lib/eio/eio_model_private.h1
2 files changed, 40 insertions, 3 deletions
diff --git a/src/lib/eio/eio_model.c b/src/lib/eio/eio_model.c
index 9baec99117..3b3c2bea3d 100644
--- a/src/lib/eio/eio_model.c
+++ b/src/lib/eio/eio_model.c
@@ -331,6 +331,19 @@ _eio_build_st_done(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *s
}
static void
+_eio_build_st_done_clobber(void *data, Eio_File *handler, const Eina_Stat *stat)
+{
+ Eio_Model *model = data;
+ Eio_Model *parent;
+
+ efl_ref(model);
+ _eio_build_st_done(data, handler, stat);
+ parent = efl_parent_get(model);
+ efl_model_child_del(parent, model);
+ efl_unref(model);
+}
+
+static void
_eio_build_st_error(void *data, Eio_File *handler EINA_UNUSED, int error)
{
Eio_Model *model = data;
@@ -345,6 +358,19 @@ _eio_build_st_error(void *data, Eio_File *handler EINA_UNUSED, int error)
}
static void
+_eio_build_st_error_clobber(void *data, Eio_File *handler, int error)
+{
+ Eio_Model *model = data;
+ Eio_Model *parent;
+
+ efl_ref(model);
+ _eio_build_st_error(data, handler, error);
+ parent = efl_parent_get(model);
+ efl_model_child_del(parent, model);
+ efl_unref(model);
+}
+
+static void
_eio_build_st(const Eio_Model *model, Eio_Model_Data *pd)
{
if (pd->st) return ;
@@ -354,6 +380,19 @@ _eio_build_st(const Eio_Model *model, Eio_Model_Data *pd)
pd->request.stat = eio_file_direct_stat(pd->path, _eio_build_st_done, _eio_build_st_error, efl_ref(model));
}
+static void
+_eio_build_st_then_clobber(const Eio_Model *model, Eio_Model_Data *pd)
+{
+ if (pd->st) return ;
+ if (pd->request.stat) return ;
+ if (pd->error) return ;
+
+ pd->request.stat = eio_file_direct_stat(pd->path,
+ _eio_build_st_done_clobber,
+ _eio_build_st_error_clobber,
+ efl_ref(model));
+}
+
static Eina_List *delayed_queue = NULL;
static void
@@ -853,8 +892,7 @@ _eio_model_efl_model_child_del(Eo *obj EINA_UNUSED,
if (type == EINA_FILE_UNKNOWN)
{
- child_pd->delete_me = EINA_TRUE;
- _eio_build_st(child, child_pd);
+ _eio_build_st_then_clobber(child, child_pd);
return ;
}
diff --git a/src/lib/eio/eio_model_private.h b/src/lib/eio/eio_model_private.h
index c0ac50a8d5..bf1344a4c6 100644
--- a/src/lib/eio/eio_model_private.h
+++ b/src/lib/eio/eio_model_private.h
@@ -68,7 +68,6 @@ struct _Eio_Model_Data
Eina_Error error;
Eina_Bool listed : 1;
- Eina_Bool delete_me : 1;
};
#endif