ecore: refactor promise propagation code.

This commit is contained in:
Cedric BAIL 2016-12-16 10:19:37 -08:00
parent c11b66434f
commit 5882c30a98
1 changed files with 27 additions and 41 deletions

View File

@ -552,39 +552,22 @@ _efl_promise_message_new(Efl_Promise_Data *pd)
} }
static void static void
_efl_promise_value_set(Eo *obj, Efl_Promise_Data *pd, void *v, Eina_Free_Cb free_cb) _efl_promise_propagate(Eo *obj, Efl_Promise_Data *pd)
{ {
Efl_Promise_Msg *message;
Efl_Loop_Future_Data *f; Efl_Loop_Future_Data *f;
Eina_List *l, *ln; Eina_List *l, *ln;
if (pd->message)
{
ERR("This promise has already been fulfilled. You can can't set a value twice nor can you set a value after it has been cancelled.");
return ;
}
// By triggering this message, we are likely going to kill all future // By triggering this message, we are likely going to kill all future
// And a user of the promise may want to attach an event handler on the promise // And a user of the promise may want to attach an event handler on the promise
// and destroy it, so delay that to after the loop is done. // and destroy it, so delay that to after the loop is done.
efl_ref(obj); efl_ref(obj);
// Create a refcounted structure where refcount == number of future + one
message = _efl_promise_message_new(pd);
if (!message) return ;
message->value = v;
message->free_cb = free_cb;
EINA_REFCOUNT_INIT(message);
pd->message = message;
// Send it to all futures // Send it to all futures
pd->propagating++; pd->propagating++;
EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f) EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
{ {
EINA_REFCOUNT_REF(message); EINA_REFCOUNT_REF(pd->message);
f->message = message; f->message = pd->message;
// Trigger the callback // Trigger the callback
_efl_loop_future_propagate(f->self, f); _efl_loop_future_propagate(f->self, f);
@ -596,11 +579,9 @@ _efl_promise_value_set(Eo *obj, Efl_Promise_Data *pd, void *v, Eina_Free_Cb free
} }
static void static void
_efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err) _efl_promise_value_set(Eo *obj, Efl_Promise_Data *pd, void *v, Eina_Free_Cb free_cb)
{ {
Efl_Promise_Msg *message; Efl_Promise_Msg *message;
Efl_Loop_Future_Data *f;
Eina_List *l, *ln;
if (pd->message) if (pd->message)
{ {
@ -608,11 +589,29 @@ _efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err)
return ; return ;
} }
// By triggering this message, we are likely going to kill all future // Create a refcounted structure where refcount == number of future + one
// And a user of the promise may want to attach an event handler on the promise message = _efl_promise_message_new(pd);
// and destroy it, so delay that to after the loop is done. if (!message) return ;
efl_ref(obj);
message->value = v;
message->free_cb = free_cb;
EINA_REFCOUNT_INIT(message);
pd->message = message;
_efl_promise_propagate(obj, pd);
}
static void
_efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err)
{
Efl_Promise_Msg *message;
if (pd->message)
{
ERR("This promise has already been fulfilled. You can can't set a value twice nor can you set a value after it has been cancelled.");
return ;
}
// Create a refcounted structure where refcount == number of future + one // Create a refcounted structure where refcount == number of future + one
message = _efl_promise_message_new(pd); message = _efl_promise_message_new(pd);
if (!message) return ; if (!message) return ;
@ -622,20 +621,7 @@ _efl_promise_failed_set(Eo *obj, Efl_Promise_Data *pd, Eina_Error err)
EINA_REFCOUNT_INIT(message); EINA_REFCOUNT_INIT(message);
pd->message = message; pd->message = message;
// Send it to each future _efl_promise_propagate(obj, pd);
pd->propagating++;
EINA_LIST_FOREACH_SAFE(pd->futures, l, ln, f)
{
EINA_REFCOUNT_REF(message);
f->message = message;
// Trigger the callback
_efl_loop_future_propagate(f->self, f);
}
pd->propagating--;
// Now, we may die.
efl_unref(obj);
} }
static void static void