summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-04-10 17:22:37 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2015-04-10 17:23:12 -0300
commitcdd597cb566aa5d1666c6485a3e78dce3c8f994a (patch)
treed5b248ec5fb749a7ca5ce3947d9cfc8c16395e5b
parent22cfae5b8c2af964a250f4ae9bc891777721d6da (diff)
eio-model: Fixed concurrent access to filter_cb and monitoring empty directories
Added a spinlock, since contetion should be non-existant. And removed wrong if.
-rw-r--r--src/lib/eio/eio_model.c35
-rw-r--r--src/lib/eio/eio_model_private.h1
2 files changed, 24 insertions, 12 deletions
diff --git a/src/lib/eio/eio_model.c b/src/lib/eio/eio_model.c
index 6abddb2..ad07a7c 100644
--- a/src/lib/eio/eio_model.c
+++ b/src/lib/eio/eio_model.c
@@ -148,19 +148,16 @@ _efl_model_evt_added_ecore_cb(void *data EINA_UNUSED, int type EINA_UNUSED, void
148 Efl_Model_Children_Event cevt; 148 Efl_Model_Children_Event cevt;
149 Eina_Value path; 149 Eina_Value path;
150 150
151 if (priv->children_list) 151 cevt.child = eo_add_ref(EIO_MODEL_CLASS, priv->obj, eio_model_path_set(evt->filename));
152 { 152 priv->children_list = eina_list_append(priv->children_list, cevt.child);
153 cevt.child = eo_add_ref(EIO_MODEL_CLASS, priv->obj, eio_model_path_set(evt->filename)); 153 cevt.index = eina_list_count(priv->children_list);
154 priv->children_list = eina_list_append(priv->children_list, cevt.child);
155 cevt.index = eina_list_count(priv->children_list);
156 154
157 eina_value_setup(&path, EINA_VALUE_TYPE_STRING); 155 eina_value_setup(&path, EINA_VALUE_TYPE_STRING);
158 eina_value_set(&path, evt->filename); 156 eina_value_set(&path, evt->filename);
159 eo_do(cevt.child, eio_model_children_filter_set(priv->filter_cb, priv->filter_userdata)); 157 eo_do(cevt.child, eio_model_children_filter_set(priv->filter_cb, priv->filter_userdata));
160 eina_value_flush(&path); 158 eina_value_flush(&path);
161 159
162 eo_do(priv->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_CHILD_ADDED, &cevt)); 160 eo_do(priv->obj, eo_event_callback_call(EFL_MODEL_BASE_EVENT_CHILD_ADDED, &cevt));
163 }
164 161
165 return EINA_TRUE; 162 return EINA_TRUE;
166} 163}
@@ -391,10 +388,15 @@ _eio_filter_children_load_cb(void *data, Eio_File *handler, const Eina_File_Dire
391 Eio_Model_Data *priv = data; 388 Eio_Model_Data *priv = data;
392 EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE); 389 EINA_SAFETY_ON_NULL_RETURN_VAL(priv, EINA_FALSE);
393 390
391 eina_spinlock_take(&priv->filter_lock);
394 if (priv->filter_cb) 392 if (priv->filter_cb)
395 { 393 {
396 return priv->filter_cb(priv->filter_userdata, handler, info); 394 Eina_Bool r = priv->filter_cb(priv->filter_userdata, handler, info);
395 eina_spinlock_release(&priv->filter_lock);
396 return r;
397 } 397 }
398 else
399 eina_spinlock_release(&priv->filter_lock);
398 400
399 return EINA_TRUE; 401 return EINA_TRUE;
400} 402}
@@ -407,8 +409,10 @@ _eio_main_children_load_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina
407 EINA_SAFETY_ON_NULL_RETURN(priv); 409 EINA_SAFETY_ON_NULL_RETURN(priv);
408 410
409 child = eo_add(MY_CLASS, NULL, eio_model_path_set(info->path)); 411 child = eo_add(MY_CLASS, NULL, eio_model_path_set(info->path));
412 eina_spinlock_take(&priv->filter_lock);
410 if (priv->filter_cb) 413 if (priv->filter_cb)
411 eo_do(child, eio_model_children_filter_set(priv->filter_cb, priv->filter_userdata)); 414 eo_do(child, eio_model_children_filter_set(priv->filter_cb, priv->filter_userdata));
415 eina_spinlock_release(&priv->filter_lock);
412 416
413 priv->children_list = eina_list_append(priv->children_list, child); 417 priv->children_list = eina_list_append(priv->children_list, child);
414} 418}
@@ -506,8 +510,12 @@ _eio_model_efl_model_base_unload(Eo *obj EINA_UNUSED, Eio_Model_Data *priv)
506static void 510static void
507_eio_model_children_filter_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eio_Filter_Direct_Cb filter_cb, void *data) 511_eio_model_children_filter_set(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eio_Filter_Direct_Cb filter_cb, void *data)
508{ 512{
513 eina_spinlock_take(&priv->filter_lock);
514
509 priv->filter_cb = filter_cb; 515 priv->filter_cb = filter_cb;
510 priv->filter_userdata = data; 516 priv->filter_userdata = data;
517
518 eina_spinlock_release(&priv->filter_lock);
511} 519}
512 520
513/** 521/**
@@ -637,6 +645,7 @@ _eio_model_eo_base_constructor(Eo *obj, Eio_Model_Data *priv)
637 645
638 priv->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED; 646 priv->load.status = EFL_MODEL_LOAD_STATUS_UNLOADED;
639 priv->monitor = NULL; 647 priv->monitor = NULL;
648 eina_spinlock_new(&priv->filter_lock);
640} 649}
641 650
642static void 651static void
@@ -660,6 +669,8 @@ _eio_model_eo_base_destructor(Eo *obj , Eio_Model_Data *priv)
660 if (priv->monitor) 669 if (priv->monitor)
661 eio_monitor_del(priv->monitor); 670 eio_monitor_del(priv->monitor);
662 671
672 eina_spinlock_free(&priv->filter_lock);
673
663 if (priv->properties_name) 674 if (priv->properties_name)
664 eina_array_free(priv->properties_name); 675 eina_array_free(priv->properties_name);
665 676
diff --git a/src/lib/eio/eio_model_private.h b/src/lib/eio/eio_model_private.h
index 0aed0d6..adeb9cf 100644
--- a/src/lib/eio/eio_model_private.h
+++ b/src/lib/eio/eio_model_private.h
@@ -52,6 +52,7 @@ struct _Eio_Model_Data
52 int cb_count_child_del; /**< monitor reference counter for child del event*/ 52 int cb_count_child_del; /**< monitor reference counter for child del event*/
53 Eio_Filter_Direct_Cb filter_cb; 53 Eio_Filter_Direct_Cb filter_cb;
54 void *filter_userdata; 54 void *filter_userdata;
55 Eina_Spinlock filter_lock; /**< filter callback is called from another thread */
55}; 56};
56 57
57#endif 58#endif