> +EOLIAN static void
> +_efl_observable_observer_del(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, 
> const char *key, Efl_Observer *obs)
> +{
> +   Eina_Hash *observers;
> +   Efl_Observer_Refcount *or;
> +
> +   if (!key) return;
> +
> +   observers = eina_hash_find(pd->observers, key);
> +   if (!observers) return;
> +
> +   or = eina_hash_find(observers, &obs);
> +   if (!or) return;
> +
> +   EINA_REFCOUNT_UNREF(or)
> +     {
> +        eina_hash_del(observers, &or->o, or);
> +
> +        if (eina_hash_population(observers) == 0)
> +          {
> +             eina_hash_del(pd->observers, key, observers);
> +          }
> +     }

this will lead to problems if user deletes the observe when being
updated, something like "great, I got what I need, so stop observing".

Then you need some kind of "walking" counter on pd, if walking, do not
delete immediately, just mark as deleted, add to a "pending deletion"
queue and once walking counter drops to zero, then you walk the
pending list and do the actual deletion.

boring I know :-/


> +}
> +
> +EOLIAN static void
> +_efl_observable_observer_clean(Eo *obj EINA_UNUSED, Efl_Observable_Data *pd, 
> Efl_Observer *obs)
> +{
> +   Eina_Iterator *it;
> +   Eina_Hash *observers;
> +
> +   it = eina_hash_iterator_data_new(pd->observers);
> +   EINA_ITERATOR_FOREACH(it, observers)
> +     {
> +        Efl_Observer_Refcount *or;
> +
> +        or = eina_hash_find(observers, &obs);
> +        if (!or) continue;
> +
> +        EINA_REFCOUNT_UNREF(or)
> +          {
> +             eina_hash_del(observers, &obs, or);
> +          }
> +     }
> +   eina_iterator_free(it);
> +}

Like for _efl_observable_observer_del, if called when walking the hash... booom


> +EOLIAN static void
> +_efl_observable_observers_update(Eo *obj, Efl_Observable_Data *pd 
> EINA_UNUSED, const char *key, void *data)
> +{
> +   Eina_Iterator *it;
> +   Efl_Observer *o;
> +
> +   it = efl_observable_observers_iterator_new(obj, key);
> +   if (!it) return;
> +

as said above, here you should pd->walking++

> +   EINA_ITERATOR_FOREACH(it, o)
> +     {
> +        efl_observer_update(o, obj, key, data);
> +     }

here you would:

pd->walking--;
if (pd->walking == 0)
 {
    struct pending_del *pend;
    EINA_LIST_FREE(pd->pending_deletion, pend)
      {
         _efl_observable_observer_del(o, pd, pend->key, pend->obs);
         free(pend);
      }
 }





-- 
Gustavo Sverzut Barbieri
--------------------------------------
Mobile: +55 (16) 99354-9890

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi
_______________________________________________
enlightenment-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/enlightenment-devel

Reply via email to