cedric pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=de131bf5d032eeb084a7bc90cef39b488e5820ba
commit de131bf5d032eeb084a7bc90cef39b488e5820ba Author: Cedric BAIL <ced...@osg.samsung.com> Date: Mon Nov 7 11:29:51 2016 -0800 eina: remove Eina_Promise. --- src/Makefile_Eina.am | 2 - src/lib/eina/Eina.h | 1 - src/lib/eina/eina_main.c | 2 - src/lib/eina/eina_promise.c | 999 -------------------------------------------- src/lib/eina/eina_promise.h | 515 ----------------------- 5 files changed, 1519 deletions(-) diff --git a/src/Makefile_Eina.am b/src/Makefile_Eina.am index ce04366..5ac7b15 100644 --- a/src/Makefile_Eina.am +++ b/src/Makefile_Eina.am @@ -96,7 +96,6 @@ lib/eina/eina_util.h \ lib/eina/eina_quaternion.h \ lib/eina/eina_vector.h \ lib/eina/eina_inline_vector.x \ -lib/eina/eina_promise.h \ lib/eina/eina_bezier.h \ lib/eina/eina_safepointer.h \ lib/eina/eina_inline_safepointer.x \ @@ -175,7 +174,6 @@ lib/eina/eina_private.h \ lib/eina/eina_share_common.h \ lib/eina/eina_strbuf_common.h \ lib/eina/eina_quaternion.c \ -lib/eina/eina_promise.c \ lib/eina/eina_bezier.c \ lib/eina/eina_safepointer.c \ lib/eina/eina_freeq.c diff --git a/src/lib/eina/Eina.h b/src/lib/eina/Eina.h index 4f1db07..16650e3 100644 --- a/src/lib/eina/Eina.h +++ b/src/lib/eina/Eina.h @@ -268,7 +268,6 @@ extern "C" { #include <eina_evlog.h> #include <eina_util.h> #include <eina_quaternion.h> -#include <eina_promise.h> #include <eina_bezier.h> #include <eina_safepointer.h> #include <eina_slice.h> diff --git a/src/lib/eina/eina_main.c b/src/lib/eina/eina_main.c index 70bd758..5124092 100644 --- a/src/lib/eina/eina_main.c +++ b/src/lib/eina/eina_main.c @@ -156,7 +156,6 @@ EAPI Eina_Inlist *_eina_tracking = NULL; S(rbtree); S(file); S(safepointer); - S(promise); /* no model for now S(model); */ @@ -205,7 +204,6 @@ static const struct eina_desc_setup _eina_desc_setup[] = { S(rbtree), S(file), S(safepointer), - S(promise) /* no model for now S(model) */ diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c deleted file mode 100644 index 31310c1..0000000 --- a/src/lib/eina/eina_promise.c +++ /dev/null @@ -1,999 +0,0 @@ -#ifdef HAVE_CONFIG_H -#include <config.h> -#endif - -#include <Eina.h> - -#include <eina_private.h> - -#include <assert.h> - -static int _eina_promise_log_dom = -1; - -#ifdef ERR -#undef ERR -#endif -#define ERR(...) EINA_LOG_DOM_ERR(_eina_promise_log_dom, __VA_ARGS__) - -#define _EINA_PROMISE_NULL_CHECK(promise, v) \ - if(!promise) \ - { \ - eina_error_set(EINA_ERROR_PROMISE_NULL); \ - return v; \ - } -#define EINA_MAGIC_CHECK_PROMISE(promise) \ - do if(!EINA_MAGIC_CHECK(promise, EINA_MAGIC_PROMISE)) \ - {EINA_MAGIC_FAIL(promise, EINA_MAGIC_PROMISE);} while(0) -#define EINA_MAGIC_CHECK_PROMISE_OWNER(promise) \ - do {if(!EINA_MAGIC_CHECK(promise, EINA_MAGIC_PROMISE_OWNER)) \ - {EINA_MAGIC_FAIL(promise, EINA_MAGIC_PROMISE_OWNER);} } while(0) -#define EINA_PROMISE_SAFE_GET_OR_RETURN(x, y, v) \ - x = eina_safepointer_get((Eina_Safepointer const*)y); \ - if(!x) return v - -typedef struct _Eina_Promise_Then_Cb _Eina_Promise_Then_Cb; -typedef struct _Eina_Promise_Progress_Cb _Eina_Promise_Progress_Cb; -typedef struct _Eina_Promise_Cancel_Cb _Eina_Promise_Cancel_Cb; -typedef struct _Eina_Promise_Owner_Progress_Notify_Data _Eina_Promise_Owner_Progress_Notify_Data; -typedef struct _Eina_Promise_Default _Eina_Promise_Default; -typedef struct _Eina_Promise_Default_Owner _Eina_Promise_Default_Owner; -typedef struct _Eina_Promise_Iterator _Eina_Promise_Iterator; -typedef struct _Eina_Promise_Success_Iterator _Eina_Promise_Success_Iterator; - -struct _Eina_Promise_Then_Cb -{ - EINA_INLIST; - - Eina_Promise_Cb callback; - Eina_Promise_Error_Cb error_cb; - void* data; -}; - -struct _Eina_Promise_Progress_Cb -{ - EINA_INLIST; - - Eina_Promise_Progress_Cb callback; - Eina_Promise_Free_Cb free; - void* data; -}; - -struct _Eina_Promise_Cancel_Cb -{ - EINA_INLIST; - - Eina_Promise_Default_Cancel_Cb callback; - Eina_Promise_Free_Cb free; - void* data; -}; - -struct _Eina_Promise_Owner_Progress_Notify_Data -{ - EINA_INLIST; - - Eina_Promise_Progress_Notify_Cb callback; - Eina_Promise_Free_Cb free_cb; - void* data; -}; - -struct _Eina_Promise_Default -{ - Eina_Promise_VTable vtable; - Eina_Error error; - size_t value_size; - - Eina_Inlist *then_callbacks; - Eina_Inlist *progress_callbacks; - Eina_Inlist *cancel_callbacks; - Eina_Inlist *progress_notify_callbacks; - Eina_Promise_Free_Cb value_free_cb; - Eina_Promise* promise_pointer; - - int ref; - - Eina_Bool has_finished : 1; - Eina_Bool has_errored : 1; - Eina_Bool can_be_deleted : 1; - Eina_Bool is_cancelled : 1; - Eina_Bool is_manual_then : 1; - Eina_Bool is_first_then : 1; -}; - -struct _Eina_Promise_Default_Owner -{ - Eina_Promise_Owner_VTable owner_vtable; - _Eina_Promise_Default promise; - Eina_Promise_Owner* owner_pointer; - void* pointer_value; -}; - -#define EINA_PROMISE_GET_OWNER(p) (_Eina_Promise_Default_Owner*)((unsigned char*)p - offsetof(struct _Eina_Promise_Default_Owner, promise)) - -struct _Eina_Promise_Iterator -{ - struct _Eina_Promise_Success_Iterator - { - Eina_Iterator success_iterator_impl; - unsigned int promise_index; - unsigned int num_promises; - unsigned int promises_finished; - Eina_Promise* promises[]; - } data; -}; - -typedef struct _Eina_Promise_Race _Eina_Promise_Race; -struct _Eina_Promise_Race -{ - _Eina_Promise_Default_Owner promise_default; - unsigned int num_promises; - struct _Eina_Promise_Race_Information - { - Eina_Promise* promise; - _Eina_Promise_Race* self; - } promises[]; -}; - -static void _eina_promise_free_progress_callback_node(void* node) -{ - _Eina_Promise_Progress_Cb *progress_cb = node; - if(progress_cb->free) - progress_cb->free(progress_cb->data); - free(progress_cb); -} - -static void _eina_promise_free_progress_notify_callback_node(void* node) -{ - _Eina_Promise_Owner_Progress_Notify_Data *progress_notify_cb = node; - if(progress_notify_cb->free_cb) - progress_notify_cb->free_cb(progress_notify_cb->data); - free(progress_notify_cb); -} - -static void _eina_promise_free_cancel_callback_node(void *node) -{ - _Eina_Promise_Cancel_Cb *cancel_cb = node; - if (cancel_cb->free) - cancel_cb->free(cancel_cb->data); - free(cancel_cb); -} - -static void _eina_promise_finish(_Eina_Promise_Default_Owner* promise); -static void _eina_promise_ref(_Eina_Promise_Default* promise); -static void _eina_promise_unref(_Eina_Promise_Default* promise); - -static void _eina_promise_iterator_setup(_Eina_Promise_Iterator* iterator, Eina_Array* promises); - -static void _eina_promise_free_callback_list(Eina_Inlist** list, void(*free_cb)(void* node)) -{ - struct node - { - EINA_INLIST; - } *node; - Eina_Inlist *list2; - - EINA_INLIST_FOREACH_SAFE(*list, list2, node) - { - free_cb(node); - } - *list = NULL; -} - -static void -_eina_promise_then_calls(_Eina_Promise_Default_Owner* promise) -{ - _Eina_Promise_Then_Cb* callback; - Eina_Bool error; - - _eina_promise_ref(&promise->promise); - error = promise->promise.has_errored; - - EINA_INLIST_FREE(promise->promise.then_callbacks, callback) - { - promise->promise.then_callbacks = eina_inlist_remove(promise->promise.then_callbacks, EINA_INLIST_GET(callback)); - if (error) - { - if (callback->error_cb) - (*callback->error_cb)(callback->data, promise->promise.error); - } - else if (callback->callback) - { - (*callback->callback)(callback->data, promise->pointer_value); - } - free(callback); - _eina_promise_unref(&promise->promise); - } - _eina_promise_unref(&promise->promise); -} - -static void -_eina_promise_cancel_calls(_Eina_Promise_Default_Owner* promise, Eina_Bool call_cancel EINA_UNUSED) -{ - _Eina_Promise_Cancel_Cb* callback; - - _eina_promise_ref(&promise->promise); - EINA_INLIST_FREE(promise->promise.cancel_callbacks, callback) - { - promise->promise.cancel_callbacks = eina_inlist_remove(promise->promise.cancel_callbacks, EINA_INLIST_GET(callback)); - if (callback->callback) - { - (*callback->callback)(callback->data, (Eina_Promise_Owner*)promise); - } - free(callback); - } - - if (!promise->promise.is_manual_then) - { - _eina_promise_then_calls(promise); - } - _eina_promise_unref(&promise->promise); -} - -static void -_eina_promise_del(_Eina_Promise_Default_Owner* promise) -{ - if (!promise->promise.has_finished) - { - ERR("Promise is being deleted, despite not being finished yet. This will cause intermitent crashes"); - } - - if (promise->promise.value_free_cb) - { - promise->promise.value_free_cb(promise->pointer_value); - } - - _eina_promise_free_callback_list(&promise->promise.progress_callbacks, - &_eina_promise_free_progress_callback_node); - _eina_promise_free_callback_list(&promise->promise.progress_notify_callbacks, - &_eina_promise_free_progress_notify_callback_node); - _eina_promise_free_callback_list(&promise->promise.cancel_callbacks, - &_eina_promise_free_cancel_callback_node); - - eina_safepointer_unregister((Eina_Safepointer const*)promise->owner_pointer); - eina_safepointer_unregister((Eina_Safepointer const*)promise->promise.promise_pointer); - - EINA_MAGIC_SET(&promise->owner_vtable, 0xdeadbeef); - EINA_MAGIC_SET(&promise->promise.vtable, 0xbeefdead); - free(promise); -} - -static void * -_eina_promise_value_get(_Eina_Promise_Default const* p) -{ - _Eina_Promise_Default_Owner const* promise = EINA_PROMISE_GET_OWNER(p); - if (p->has_finished && !p->has_errored) - { - return promise->pointer_value; - } - else - { - return NULL; - } -} - -static void -_eina_promise_owner_value_set(_Eina_Promise_Default_Owner* promise, const void* data, Eina_Promise_Free_Cb free) -{ - promise->pointer_value = (void*)data; - promise->promise.value_free_cb = free; - _eina_promise_finish(promise); -} - -static void -_eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback, - Eina_Promise_Error_Cb error_cb, void* data) -{ - _Eina_Promise_Default_Owner* promise; - _Eina_Promise_Then_Cb* cb; - _Eina_Promise_Owner_Progress_Notify_Data* notify_data; - - promise = EINA_PROMISE_GET_OWNER(p); - - cb = malloc(sizeof(struct _Eina_Promise_Then_Cb)); - - cb->callback = callback; - cb->error_cb = error_cb; - cb->data = data; - promise->promise.then_callbacks = eina_inlist_append(promise->promise.then_callbacks, EINA_INLIST_GET(cb)); - - EINA_INLIST_FOREACH(promise->promise.progress_notify_callbacks, notify_data) - { - (*notify_data->callback)(notify_data->data, promise->owner_pointer); - } - _eina_promise_free_callback_list(&promise->promise.progress_notify_callbacks, &free); - - if (!promise->promise.is_first_then) - { - _eina_promise_ref(p); - } - else - promise->promise.is_first_then = EINA_FALSE; - if (promise->promise.has_finished) - { - _eina_promise_then_calls(promise); - } -} - -static void -_eina_promise_owner_error_set(_Eina_Promise_Default_Owner* promise, Eina_Error error) -{ - promise->promise.error = error; - promise->promise.has_errored = EINA_TRUE; - - _eina_promise_finish(promise); -} - -static void -_eina_promise_finish(_Eina_Promise_Default_Owner* promise) -{ - promise->promise.has_finished = EINA_TRUE; - promise->promise.can_be_deleted = EINA_TRUE; - if (!promise->promise.is_manual_then) - { - _eina_promise_then_calls(promise); - } -} - -static Eina_Error -_eina_promise_error_get(_Eina_Promise_Default const* promise) -{ - if (promise->has_errored) - { - return promise->error; - } - else - { - return 0; - } -} - -static Eina_Bool -_eina_promise_pending_is(_Eina_Promise_Default const* promise) -{ - return !promise->has_finished; -} - -static Eina_Bool -_eina_promise_owner_pending_is(_Eina_Promise_Default_Owner const* promise) -{ - return !promise->promise.has_finished; -} - -static Eina_Bool -_eina_promise_owner_cancelled_is(_Eina_Promise_Default_Owner const* promise) -{ - return promise->promise.is_cancelled; -} - -static void -_eina_promise_progress_cb_add(_Eina_Promise_Default* promise, Eina_Promise_Progress_Cb callback, void* data, - Eina_Promise_Free_Cb free_cb) -{ - _Eina_Promise_Progress_Cb* cb; - _Eina_Promise_Owner_Progress_Notify_Data* notify_data; - _Eina_Promise_Default_Owner* owner = EINA_PROMISE_GET_OWNER(promise); - - cb = malloc(sizeof(struct _Eina_Promise_Progress_Cb)); - cb->callback = callback; - cb->data = data; - cb->free = free_cb; - promise->progress_callbacks = eina_inlist_append(promise->progress_callbacks, EINA_INLIST_GET(cb)); - EINA_INLIST_FOREACH(owner->promise.progress_notify_callbacks, notify_data) - { - (*notify_data->callback)(notify_data->data, owner->owner_pointer); - } - _eina_promise_free_callback_list(&owner->promise.progress_notify_callbacks, - &_eina_promise_free_progress_notify_callback_node); -} - -static void -_eina_promise_cancel(_Eina_Promise_Default* promise) -{ - _Eina_Promise_Default_Owner* owner = EINA_PROMISE_GET_OWNER(promise); - - if (!owner->promise.is_cancelled && !owner->promise.has_finished) - { - owner->promise.is_cancelled = EINA_TRUE; - owner->promise.has_finished = EINA_TRUE; - owner->promise.has_errored = EINA_TRUE; - owner->promise.error = EINA_ERROR_PROMISE_CANCEL; - _eina_promise_cancel_calls(owner, EINA_TRUE); - } -} - -static void -_eina_promise_ref(_Eina_Promise_Default* p) -{ - ++p->ref; -} - -static void -_eina_promise_unref(_Eina_Promise_Default* p) -{ - if (--p->ref <= 0 && p->has_finished && p->can_be_deleted) - { - _eina_promise_del(EINA_PROMISE_GET_OWNER(p)); - } -} - -static int -_eina_promise_ref_get(_Eina_Promise_Default* p) -{ - return p->ref; -} - -static Eina_Promise * -_eina_promise_owner_promise_get(_Eina_Promise_Default_Owner* p) -{ - return p->promise.promise_pointer; -} - -EAPI void -eina_promise_owner_default_cancel_cb_add(Eina_Promise_Owner* p, - Eina_Promise_Default_Cancel_Cb callback, void* data, - Eina_Promise_Free_Cb free_cb) -{ - _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, p, ); - _Eina_Promise_Cancel_Cb *cb; - - cb = malloc(sizeof(struct _Eina_Promise_Cancel_Cb)); - - cb->callback = callback; - cb->free = free_cb; - cb->data = data; - promise->promise.cancel_callbacks = eina_inlist_append(promise->promise.cancel_callbacks, EINA_INLIST_GET(cb)); - - if (promise->promise.is_cancelled) - { - _eina_promise_cancel_calls(promise, EINA_TRUE); - } -} - -static void -_eina_promise_owner_progress(_Eina_Promise_Default_Owner* promise, void* data) -{ - _Eina_Promise_Progress_Cb* callback; - Eina_Inlist* list2; - - EINA_INLIST_FOREACH_SAFE(promise->promise.progress_callbacks, list2, callback) - { - if(callback->callback) - (*callback->callback)(callback->data, data); - } -} - -static void -_eina_promise_owner_progress_notify(_Eina_Promise_Default_Owner* promise, Eina_Promise_Progress_Notify_Cb notify, - void* data, Eina_Promise_Free_Cb free_cb) -{ - _Eina_Promise_Owner_Progress_Notify_Data* cb - = malloc(sizeof(struct _Eina_Promise_Owner_Progress_Notify_Data)); - - cb->callback = notify; - cb->free_cb = free_cb; - cb->data = data; - promise->promise.progress_notify_callbacks = - eina_inlist_append(promise->promise.progress_notify_callbacks, EINA_INLIST_GET(cb)); -} - -static void eina_promise_add_internal(_Eina_Promise_Default_Owner* p) -{ - p->promise.vtable.version = EINA_PROMISE_VERSION; - p->promise.vtable.then = EINA_FUNC_PROMISE_THEN(_eina_promise_then); - p->promise.vtable.value_get = EINA_FUNC_PROMISE_VALUE_GET(_eina_promise_value_get); - p->promise.vtable.error_get = EINA_FUNC_PROMISE_ERROR_GET(_eina_promise_error_get); - p->promise.vtable.pending_is = EINA_FUNC_PROMISE_PENDING_IS(_eina_promise_pending_is); - p->promise.vtable.progress_cb_add = EINA_FUNC_PROMISE_PROGRESS_CB_ADD(_eina_promise_progress_cb_add); - p->promise.vtable.cancel = EINA_FUNC_PROMISE_CANCEL(_eina_promise_cancel); - p->promise.vtable.ref = EINA_FUNC_PROMISE_REF(_eina_promise_ref); - p->promise.vtable.unref = EINA_FUNC_PROMISE_UNREF(_eina_promise_unref); - p->promise.vtable.ref_get = EINA_FUNC_PROMISE_REF_GET(_eina_promise_ref_get); - EINA_MAGIC_SET(&p->promise.vtable, EINA_MAGIC_PROMISE); - - p->promise.is_first_then = EINA_TRUE; - p->promise.ref = 1; - p->promise.promise_pointer = eina_promise_override(&p->promise.vtable); - - p->owner_vtable.version = EINA_PROMISE_VERSION; - p->owner_vtable.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(_eina_promise_owner_value_set); - p->owner_vtable.error_set = EINA_FUNC_PROMISE_OWNER_ERROR_SET(_eina_promise_owner_error_set); - p->owner_vtable.promise_get = EINA_FUNC_PROMISE_OWNER_PROMISE_GET(_eina_promise_owner_promise_get); - p->owner_vtable.pending_is = EINA_FUNC_PROMISE_OWNER_PENDING_IS(_eina_promise_owner_pending_is); - p->owner_vtable.cancelled_is = EINA_FUNC_PROMISE_OWNER_CANCELLED_IS(_eina_promise_owner_cancelled_is); - p->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(_eina_promise_owner_progress); - p->owner_vtable.progress_notify = EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(_eina_promise_owner_progress_notify); - EINA_MAGIC_SET(&p->owner_vtable, EINA_MAGIC_PROMISE_OWNER); - p->owner_pointer = eina_promise_owner_override(&p->owner_vtable); -} - -EAPI Eina_Promise_Owner * -eina_promise_add() -{ - _Eina_Promise_Default_Owner* p; - p = calloc(sizeof(_Eina_Promise_Default_Owner), 1); - eina_promise_add_internal(p); - return p->owner_pointer; -} - -EAPI void -eina_promise_owner_default_manual_then_set(Eina_Promise_Owner* owner, Eina_Bool is_manual) -{ - _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(p, owner, ); - EINA_MAGIC_CHECK_PROMISE_OWNER(&p->owner_vtable); - - p->promise.is_manual_then = is_manual; -} - -EAPI void -eina_promise_owner_default_call_then(Eina_Promise_Owner* owner) -{ - _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(p, owner, ); - EINA_MAGIC_CHECK_PROMISE_OWNER(&p->owner_vtable); - - _eina_promise_then_calls(p); -} - -// eina_promise_all implementation -static void -_eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED) -{ - _Eina_Promise_Default_Owner* promise = data; - _Eina_Promise_Iterator* iterator; - EINA_MAGIC_CHECK_PROMISE_OWNER(&promise->owner_vtable); - - if (!promise->promise.has_finished) - { - iterator = promise->pointer_value; - if (++(iterator->data.promises_finished) == iterator->data.num_promises) - { - _eina_promise_finish(promise); - } - } - eina_promise_unref(promise->promise.promise_pointer); -} - -static void -_eina_promise_all_compose_error_then_cb(void *data, Eina_Error error) -{ - _Eina_Promise_Default_Owner* promise = data; - EINA_MAGIC_CHECK_PROMISE_OWNER(&promise->owner_vtable); - - if (!promise->promise.has_finished) - { - promise->promise.has_finished = promise->promise.has_errored = EINA_TRUE; - promise->promise.error = error; - _eina_promise_finish(promise); - } - eina_promise_unref(promise->promise.promise_pointer); -} - -static void -_eina_promise_all_free(_Eina_Promise_Iterator* value) -{ - unsigned i = 0; - - for (;i != value->data.num_promises; ++i) - { - eina_promise_unref(value->data.promises[i]); - } - - free(value); -} - -Eina_Promise * -eina_promise_all(Eina_Iterator* it) -{ - Eina_Promise_Owner *safe_promise; - _Eina_Promise_Default_Owner *promise; - Eina_Promise* current; - Eina_Array* promises; - Eina_Promise **cur_promise, **last; - _Eina_Promise_Iterator* internal_it; - - EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); - - promises = eina_array_new(20); - - EINA_ITERATOR_FOREACH(it, current) - { - eina_array_push(promises, current); - } - - eina_iterator_free(it); - - promise = eina_safepointer_get((Eina_Safepointer*)(safe_promise = eina_promise_add())); - if (!promise) - { - eina_array_free(promises); - return NULL; - } - - internal_it = promise->pointer_value = malloc(sizeof(_Eina_Promise_Iterator) + - sizeof(_Eina_Promise_Default_Owner*) * eina_array_count_get(promises)); - - promise->promise.value_free_cb = (Eina_Promise_Free_Cb)&_eina_promise_all_free; - - _eina_promise_iterator_setup(internal_it, promises); - - cur_promise = internal_it->data.promises; - last = internal_it->data.promises + internal_it->data.num_promises; - for (;cur_promise != last; ++cur_promise) - { - eina_promise_ref(*cur_promise); // We need to keep the value alive until this promise is freed - // We need to keep the all promise alive while there are callbacks registered to it - eina_promise_ref(promise->promise.promise_pointer); - eina_promise_then(*cur_promise, &_eina_promise_all_compose_then_cb, - &_eina_promise_all_compose_error_then_cb, promise); - } - - eina_array_free(promises); - return promise->promise.promise_pointer; -} - -static Eina_Bool -_eina_promise_iterator_next(_Eina_Promise_Success_Iterator *it, void **data) -{ - if (it->promise_index == it->num_promises) - return EINA_FALSE; - - if (eina_promise_error_get(it->promises[it->promise_index])) - { - return EINA_FALSE; - } - else - { - *data = eina_promise_value_get(it->promises[it->promise_index++]); - return EINA_TRUE; - } -} - -static void ** -_eina_promise_iterator_get_container(_Eina_Promise_Success_Iterator *it) -{ - return (void**)it->promises; -} - -static void -_eina_promise_iterator_free(_Eina_Promise_Success_Iterator *it EINA_UNUSED) -{ -} - -static void -_eina_promise_iterator_setup(_Eina_Promise_Iterator* it, Eina_Array* promises_array) -{ - Eina_Promise** promises; - - it->data.num_promises = eina_array_count_get(promises_array); - it->data.promise_index = 0; - it->data.promises_finished = 0; - promises = (Eina_Promise**)promises_array->data; - - memcpy(&it->data.promises[0], promises, it->data.num_promises*sizeof(Eina_Promise*)); - - EINA_MAGIC_SET(&it->data.success_iterator_impl, EINA_MAGIC_ITERATOR); - - it->data.success_iterator_impl.version = EINA_ITERATOR_VERSION; - it->data.success_iterator_impl.next = FUNC_ITERATOR_NEXT(_eina_promise_iterator_next); - it->data.success_iterator_impl.get_container = FUNC_ITERATOR_GET_CONTAINER( - _eina_promise_iterator_get_container); - it->data.success_iterator_impl.free = FUNC_ITERATOR_FREE(_eina_promise_iterator_free); -} - -static void -_eina_promise_progress_notify_fulfilled(void* data, Eina_Promise_Owner* p EINA_UNUSED) -{ - Eina_Promise_Owner* owner = data; - // Make sure the promise is alive after value_set until our cleanup cp is called - eina_promise_ref(eina_promise_owner_promise_get(owner)); - eina_promise_owner_value_set(owner, NULL, NULL); -} - -EAPI Eina_Error EINA_ERROR_PROMISE_NO_NOTIFY; -EAPI Eina_Error EINA_ERROR_PROMISE_CANCEL; -EAPI Eina_Error EINA_ERROR_PROMISE_NULL; - -static void -_eina_promise_progress_notify_finish(void* data) -{ - Eina_Promise_Owner* owner = data; - if(eina_promise_owner_pending_is(owner)) - eina_promise_owner_error_set(owner, EINA_ERROR_PROMISE_NO_NOTIFY); - else // Cleanup the ref we got from the fulfilled cb - eina_promise_unref(eina_promise_owner_promise_get(owner)); -} - -// Race implementation -static void _eina_promise_race_unref(_Eina_Promise_Default* promise) -{ - _Eina_Promise_Race* p = (void*)EINA_PROMISE_GET_OWNER(promise); - unsigned i; - if (--p->promise_default.promise.ref <= 0 && p->promise_default.promise.can_be_deleted) - { - for(i = 0; i != p->num_promises; ++i) - { - eina_promise_unref(p->promises[i].promise); - } - _eina_promise_del(&p->promise_default); - } -} - -static void -_eina_promise_race_compose_then_cb(void *data, void* value EINA_UNUSED) -{ - struct _Eina_Promise_Race_Information* info = data; - _Eina_Promise_Race* race_promise = info->self; - - if (!race_promise->promise_default.promise.has_finished) - eina_promise_owner_value_set(race_promise->promise_default.owner_pointer, value, NULL); - eina_promise_unref(race_promise->promise_default.promise.promise_pointer); -} - -static void -_eina_promise_race_compose_error_then_cb(void *data, Eina_Error error) -{ - struct _Eina_Promise_Race_Information* info = data; - _Eina_Promise_Race* race_promise = info->self; - - if (!race_promise->promise_default.promise.has_finished) - eina_promise_owner_error_set(race_promise->promise_default.owner_pointer, error); - eina_promise_unref(race_promise->promise_default.promise.promise_pointer); -} - -Eina_Promise * -eina_promise_race(Eina_Iterator* it) -{ - _Eina_Promise_Race *promise; - Eina_Promise* current; - Eina_Array* promises; - struct _Eina_Promise_Race_Information *cur_promise, *last; - int num_promises; - - EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL); - - promises = eina_array_new(20); - - EINA_ITERATOR_FOREACH(it, current) - { - eina_array_push(promises, current); - } - - eina_iterator_free(it); - - num_promises = eina_array_count_get(promises); - promise = calloc(sizeof(_Eina_Promise_Race) + sizeof(struct _Eina_Promise_Race_Information)*num_promises, 1); - eina_promise_add_internal(&promise->promise_default); - - promise->num_promises = num_promises; - promise->promise_default.promise.vtable.unref = EINA_FUNC_PROMISE_UNREF(_eina_promise_race_unref); - - cur_promise = promise->promises; - last = promise->promises + num_promises; - for (int i = 0;cur_promise != last; ++cur_promise, ++i) - { - cur_promise->promise = eina_array_data_get(promises, i); - cur_promise->self = promise; - eina_promise_ref(cur_promise->promise); // We need to keep the value alive until this promise is freed - // We need to keep the all promise alive while there are callbacks registered to it - eina_promise_ref(promise->promise_default.promise.promise_pointer); - eina_promise_then(cur_promise->promise, &_eina_promise_race_compose_then_cb, - &_eina_promise_race_compose_error_then_cb, cur_promise); - } - - eina_array_free(promises); - return promise->promise_default.promise.promise_pointer; -} - -// API functions -EAPI Eina_Promise_Owner* eina_promise_owner_override(Eina_Promise_Owner_VTable* owner) -{ - _EINA_PROMISE_NULL_CHECK(owner, NULL); - EINA_MAGIC_CHECK_PROMISE_OWNER(owner); - Eina_Safepointer const* p = eina_safepointer_register(owner); - return (Eina_Promise_Owner*)p; -} - -EAPI Eina_Promise* eina_promise_override(Eina_Promise_VTable* promise) -{ - _EINA_PROMISE_NULL_CHECK(promise, NULL); - EINA_MAGIC_CHECK_PROMISE(promise); - Eina_Safepointer const* p = eina_safepointer_register(promise); - return (Eina_Promise*)p; -} - -EAPI Eina_Promise* -eina_promise_progress_notification(Eina_Promise_Owner* safe_promise) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, NULL); - Eina_Promise_Owner* owner; - - owner = eina_promise_add(); - - eina_promise_owner_progress_notify(safe_promise, &_eina_promise_progress_notify_fulfilled, owner, - &_eina_promise_progress_notify_finish); - - return eina_promise_owner_promise_get(owner); -} - -EAPI void -eina_promise_then(Eina_Promise* safe_promise, Eina_Promise_Cb callback, - Eina_Promise_Error_Cb error_cb, void* data) -{ - Eina_Promise_VTable* promise = eina_safepointer_get((void*)safe_promise); - if(!safe_promise || !promise) - { - if(!error_cb) - { - ERR("eina_promise_the with NULL promise and no error callback."); - eina_error_set(EINA_ERROR_PROMISE_NULL); - } - else - error_cb(data, EINA_ERROR_PROMISE_NULL); - return; - } - else - promise->then(promise, callback, error_cb, data); -} - -EAPI void -eina_promise_owner_value_set(Eina_Promise_Owner* safe_promise, const void* value, Eina_Promise_Free_Cb free) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE_OWNER(promise); - promise->value_set(promise, value, free); -} - -EAPI void -eina_promise_owner_error_set(Eina_Promise_Owner* safe_promise, Eina_Error error) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE_OWNER(promise); - promise->error_set(promise, error); -} - -EAPI void * -eina_promise_value_get(Eina_Promise const* safe_promise) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, NULL); - _EINA_PROMISE_NULL_CHECK(promise, NULL); - EINA_MAGIC_CHECK_PROMISE(promise); - return promise->value_get(promise); -} - -EAPI Eina_Error -eina_promise_error_get(Eina_Promise const* safe_promise) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, 0); - _EINA_PROMISE_NULL_CHECK(promise, EINA_ERROR_PROMISE_NULL); - EINA_MAGIC_CHECK_PROMISE(promise); - return promise->error_get(promise); -} - -EAPI Eina_Bool -eina_promise_pending_is(Eina_Promise const* safe_promise) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, EINA_FALSE); - _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE); - EINA_MAGIC_CHECK_PROMISE(promise); - return promise->pending_is(promise); -} - -EAPI void -eina_promise_progress_cb_add(Eina_Promise* safe_promise, Eina_Promise_Progress_Cb callback, void* data, - Eina_Promise_Free_Cb free_cb) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE(promise); - promise->progress_cb_add(promise, callback, data, free_cb); -} - -EAPI void -eina_promise_cancel(Eina_Promise* safe_promise) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE(promise); - promise->cancel(promise); -} - -EAPI void -eina_promise_ref(Eina_Promise* safe_promise) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE(promise); - promise->ref(promise); -} - -EAPI void -eina_promise_unref(Eina_Promise* safe_promise) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE(promise); - promise->unref(promise); -} - -EAPI int -eina_promise_ref_get(Eina_Promise* safe_promise) -{ - Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, 0); - _EINA_PROMISE_NULL_CHECK(promise, 0); - EINA_MAGIC_CHECK_PROMISE(promise); - return promise->ref_get(promise); -} - -EAPI Eina_Promise * -eina_promise_owner_promise_get(Eina_Promise_Owner* safe_promise) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, NULL); - _EINA_PROMISE_NULL_CHECK(promise, NULL); - EINA_MAGIC_CHECK_PROMISE_OWNER(promise); - return promise->promise_get(promise); -} - -EAPI Eina_Bool -eina_promise_owner_pending_is(Eina_Promise_Owner const* safe_promise) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, EINA_FALSE); - _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE); - EINA_MAGIC_CHECK_PROMISE_OWNER(promise); - return promise->pending_is(promise); -} - -EAPI Eina_Bool -eina_promise_owner_cancelled_is(Eina_Promise_Owner const* safe_promise) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, EINA_FALSE); - _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE); - EINA_MAGIC_CHECK_PROMISE_OWNER(promise); - return promise->cancelled_is(promise); -} - -EAPI void -eina_promise_owner_progress(Eina_Promise_Owner const* safe_promise, void* progress) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE_OWNER(promise); - promise->progress(promise, progress); -} - -EAPI void -eina_promise_owner_progress_notify(Eina_Promise_Owner* safe_promise, Eina_Promise_Progress_Notify_Cb progress_cb, - void* data, Eina_Promise_Free_Cb free_cb) -{ - Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, ); - _EINA_PROMISE_NULL_CHECK(promise, ); - EINA_MAGIC_CHECK_PROMISE_OWNER(promise); - promise->progress_notify(promise, progress_cb, data, free_cb); -} - -static const char EINA_ERROR_PROMISE_NO_NOTIFY_STR[] = "Out of memory"; -static const char EINA_ERROR_PROMISE_CANCEL_STR[] = "Promise cancelled"; -static const char EINA_ERROR_PROMISE_NULL_STR[] = "NULL promise"; - -Eina_Bool eina_promise_init() -{ - EINA_ERROR_PROMISE_NO_NOTIFY = eina_error_msg_static_register(EINA_ERROR_PROMISE_NO_NOTIFY_STR); - EINA_ERROR_PROMISE_CANCEL = eina_error_msg_static_register(EINA_ERROR_PROMISE_CANCEL_STR); - EINA_ERROR_PROMISE_NULL = eina_error_msg_static_register(EINA_ERROR_PROMISE_NULL_STR); - - _eina_promise_log_dom = eina_log_domain_register("eina_promise", - EINA_LOG_COLOR_DEFAULT); - if (_eina_promise_log_dom < 0) - { - EINA_LOG_ERR("Could not register log domain: eina_promise"); - return EINA_FALSE; - } - - return EINA_TRUE; -} - -Eina_Bool eina_promise_shutdown() -{ - eina_log_domain_unregister(_eina_promise_log_dom); - _eina_promise_log_dom = -1; - return EINA_TRUE; -} diff --git a/src/lib/eina/eina_promise.h b/src/lib/eina/eina_promise.h deleted file mode 100644 index 0d6f779..0000000 --- a/src/lib/eina/eina_promise.h +++ /dev/null @@ -1,515 +0,0 @@ -#ifndef EINA_PROMISE_H_ -#define EINA_PROMISE_H_ - -#ifdef EFL_BETA_API_SUPPORT - -/* - * @def Eina_Promise - */ -typedef struct _Eina_Promise Eina_Promise; - -/* - * @def Eina_Promise_VTable - */ -typedef struct _Eina_Promise_VTable Eina_Promise_VTable; - -/* - * @def Eina_Promise - */ -typedef struct _Eina_Promise_Owner Eina_Promise_Owner; - -/* - * @def Eina_Promise - */ -typedef struct _Eina_Promise_Owner_VTable Eina_Promise_Owner_VTable; - -/* - * @brief Callback type for freeing Promise value and void* pointer data for callbacks - */ -typedef void(*Eina_Promise_Free_Cb)(void* value); - -/* - * @brief Callback type for Promise_Owner to get notified of when someone registered a progress and/or then callback - */ -typedef void(*Eina_Promise_Progress_Notify_Cb)(void* data, Eina_Promise_Owner* promise); - -/* - * @brief Function callback type for when using eina_promise_then - */ -typedef void(*Eina_Promise_Cb)(void* data, void* value); - -/* - * @brief Function callback type for when using eina_promise_then - */ -typedef void(*Eina_Promise_Error_Cb)(void* data, Eina_Error error); - -/* - * @brief Function callback type for progress information - */ -typedef void(*Eina_Promise_Progress_Cb)(void* data, void* value); - -/* - * @brief Function callback type for then function override - */ -typedef void(*Eina_Promise_Then_Cb)(Eina_Promise_VTable* promise, Eina_Promise_Cb callback, - Eina_Promise_Error_Cb error_cb, void* data); - -#define EINA_FUNC_PROMISE_THEN(Function) ((Eina_Promise_Then_Cb)Function) - -/* - * @brief Function callback type for promise's value_get function override - */ -typedef void*(*Eina_Promise_Value_Get_Cb)(Eina_Promise_VTable const* promise); - -#define EINA_FUNC_PROMISE_VALUE_GET(Function) ((Eina_Promise_Value_Get_Cb)Function) - -/* - * @brief Function callback type for promise's error_get function override - */ -typedef Eina_Error(*Eina_Promise_Error_Get_Cb)(Eina_Promise_VTable const* promise); - -#define EINA_FUNC_PROMISE_ERROR_GET(Function) ((Eina_Promise_Error_Get_Cb)Function) - -/* - * @brief Function callback type for promise's pending function override - */ -typedef Eina_Bool(*Eina_Promise_Pending_Is_Cb)(Eina_Promise_VTable const* promise); - -#define EINA_FUNC_PROMISE_PENDING_IS(Function) ((Eina_Promise_Pending_Is_Cb)Function) - -/* - * @brief Function callback type for promise's progress add function override - */ -typedef void(*Eina_Promise_Progress_Cb_Add_Cb)(Eina_Promise_VTable* promise, Eina_Promise_Progress_Cb callback, void* data - , Eina_Promise_Free_Cb free_cb); - -#define EINA_FUNC_PROMISE_PROGRESS_CB_ADD(Function) ((Eina_Promise_Progress_Cb_Add_Cb)Function) - -/* - * @brief Function callback type for promise's cancel function override - */ -typedef void(*Eina_Promise_Cancel_Cb)(Eina_Promise_VTable* promise); - -#define EINA_FUNC_PROMISE_CANCEL(Function) ((Eina_Promise_Cancel_Cb)Function) - -/* - * @brief Function callback type for promise's ref function override - */ -typedef void(*Eina_Promise_Ref_Cb)(Eina_Promise_VTable* promise); - -#define EINA_FUNC_PROMISE_REF(Function) ((Eina_Promise_Ref_Cb)Function) - -/* - * @brief Function callback type for promise's unref function override - */ -typedef void(*Eina_Promise_Unref_Cb)(Eina_Promise_VTable* promise); - -#define EINA_FUNC_PROMISE_UNREF(Function) ((Eina_Promise_Unref_Cb)Function) - -/* - * @brief Function callback type for promise's ref_get function override - */ -typedef int(*Eina_Promise_Ref_Get_Cb)(Eina_Promise_VTable* promise); - -#define EINA_FUNC_PROMISE_REF_GET(Function) ((Eina_Promise_Ref_Get_Cb)Function) - -/* - * @brief Function callback type for promise's buffer_get function override - */ -typedef void*(*Eina_Promise_Buffer_Get_Cb)(Eina_Promise_VTable* promise); - -#define EINA_FUNC_PROMISE_BUFFER_GET(Function) ((Eina_Promise_Buffer_Get_Cb)Function) - -/* - * @brief Function callback type for promise owner's buffer_get function override - */ -typedef void*(*Eina_Promise_Owner_Buffer_Get_Cb)(Eina_Promise_Owner_VTable* promise); - -#define EINA_FUNC_PROMISE_OWNER_BUFFER_GET(Function) ((Eina_Promise_Owner_Buffer_Get_Cb)Function) - -/* - * @brief Function callback type for promise owner's promise_get function override - */ -typedef void*(*Eina_Promise_Owner_Promise_Get_Cb)(Eina_Promise_Owner_VTable const* promise); - -#define EINA_FUNC_PROMISE_OWNER_PROMISE_GET(Function) ((Eina_Promise_Owner_Promise_Get_Cb)Function) - -/* - * @brief Function callback type for promise owner's value_set function override - */ -typedef void(*Eina_Promise_Owner_Value_Set_Cb)(Eina_Promise_Owner_VTable* promise, const void* data, Eina_Promise_Free_Cb free_fun); - -#define EINA_FUNC_PROMISE_OWNER_VALUE_SET(Function) ((Eina_Promise_Owner_Value_Set_Cb)Function) - -/* - * @brief Function callback type for promise owner's error_set function override - */ -typedef void(*Eina_Promise_Owner_Error_Set_Cb)(Eina_Promise_Owner_VTable* promise, Eina_Error error); - -#define EINA_FUNC_PROMISE_OWNER_ERROR_SET(Function) ((Eina_Promise_Owner_Error_Set_Cb)Function) - -/* - * @brief Function callback type for promise owner's pending function override - */ -typedef Eina_Bool(*Eina_Promise_Owner_Pending_Is_Cb)(Eina_Promise_Owner_VTable const* promise); - -#define EINA_FUNC_PROMISE_OWNER_PENDING_IS(Function) ((Eina_Promise_Owner_Pending_Is_Cb)Function) - -/* - * @brief Function callback type for promise owner's cancelled function override - */ -typedef Eina_Bool(*Eina_Promise_Owner_Cancelled_Is_Cb)(Eina_Promise_Owner_VTable const* promise); - -#define EINA_FUNC_PROMISE_OWNER_CANCELLED_IS(Function) ((Eina_Promise_Owner_Cancelled_Is_Cb)Function) - -/* - * @brief Function callback type for promise owner's progress function override - */ -typedef Eina_Bool(*Eina_Promise_Owner_Progress_Cb)(Eina_Promise_Owner_VTable const* promise, void* progress); - -#define EINA_FUNC_PROMISE_OWNER_PROGRESS(Function) ((Eina_Promise_Owner_Progress_Cb)Function) - -/* - * @brief Function callback type for promise owner's progress notify registration function override - */ -typedef Eina_Bool(*Eina_Promise_Owner_Progress_Notify_Cb)(Eina_Promise_Owner_VTable* promise, - Eina_Promise_Progress_Notify_Cb progress_cb, void* data, Eina_Promise_Free_Cb free_cb); - -#define EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(Function) ((Eina_Promise_Owner_Progress_Notify_Cb)Function) - - -#define EINA_PROMISE_VERSION 1 - -struct _Eina_Promise_VTable -{ - int version; - Eina_Promise_Then_Cb then; - Eina_Promise_Value_Get_Cb value_get; - Eina_Promise_Error_Get_Cb error_get; - Eina_Promise_Pending_Is_Cb pending_is; - Eina_Promise_Progress_Cb_Add_Cb progress_cb_add; - Eina_Promise_Cancel_Cb cancel; - Eina_Promise_Ref_Cb ref; - Eina_Promise_Unref_Cb unref; - Eina_Promise_Ref_Get_Cb ref_get; -#define EINA_MAGIC_PROMISE 0x07932A5B - EINA_MAGIC; -}; - -struct _Eina_Promise_Owner_VTable -{ - int version; - Eina_Promise_Owner_Value_Set_Cb value_set; - Eina_Promise_Owner_Error_Set_Cb error_set; - Eina_Promise_Owner_Promise_Get_Cb promise_get; - Eina_Promise_Owner_Pending_Is_Cb pending_is; - Eina_Promise_Owner_Cancelled_Is_Cb cancelled_is; - Eina_Promise_Owner_Progress_Cb progress; - Eina_Promise_Owner_Progress_Notify_Cb progress_notify; -#define EINA_MAGIC_PROMISE_OWNER 0x07932A5C - EINA_MAGIC; -}; - -EAPI Eina_Promise_Owner* eina_promise_owner_override(Eina_Promise_Owner_VTable* owner); - -EAPI Eina_Promise* eina_promise_override(Eina_Promise_VTable* owner); - -/* - * @brief Appends a callback to be called when the Eina_Promise is - * finished. - * - * @param promise The Eina_Promise to wait for - * @param callback Callback to be called when Eina_Promise is finished - * @param data Private data passed to the callback - */ -EAPI void eina_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback, - Eina_Promise_Error_Cb error_cb, void* data); - -/* - * @brief Creates a new @Eina_Promise from other @Eina_Promise's - * - * The new @Eina_Promise is fulfilled when all promises - * have also been fulfilled with success or when the - * first one fails - * - * @param promises An Eina_Iterator for all Eina_Promises - * @return Returns a new Eina_Promise - */ -EAPI Eina_Promise* eina_promise_all(Eina_Iterator* promises); - -/* - * @brief Creates a new @Eina_Promise from other @Eina_Promises - * - * The new @Eina_Promise is fulfilled when the first promise - * has been fulfilled with success or when the - * first one fails - * - * @param promises An Eina_Iterator for all Eina_Promises - * @return Returns a new Eina_Promise - */ -EAPI Eina_Promise* eina_promise_race(Eina_Iterator* promises); - -/* - * @brief Creates a new @Eina_Promise from another @Eina_Promise_Owner which - * is fulfilled when @promise has a progress callback registered - * - * @param promise Promise Owner which to be waited for a progress callback register - * @return Returns a new Eina_Promise - */ -EAPI Eina_Promise* eina_promise_progress_notification(Eina_Promise_Owner* promise); - -/* - * @brief Sets value for Eina_Promise_Owner - * - * This finishes the Promise and calls all eina_promise_then callbacks - * that have been registered on Eina_Promise. This function must be - * called only once per Eina_Promise_Owner - * - * @param promise The promise owner for which to set the value - * @param value The pointer to the value that is going to be copied, or NULL. - * @param free_cb Callback function to be used to free the value copied - */ -EAPI void eina_promise_owner_value_set(Eina_Promise_Owner* promise, const void* value, Eina_Promise_Free_Cb free_cb); - -/* - * @brief Returns the pointer to the value - * - * If the Eina_Promise is not pending anymore and has not failed, - * returns the pointer to the value, otherwise returns NULL. - * - * @param promise The promise for which to get the value - * @return Value pointer or @NULL - */ -EAPI void* eina_promise_value_get(Eina_Promise const* promise); - -/* - * @brief Sets an error to the Eina_Promise - * - * Sets an error to the promise, finishing the promise and calling all - * eina_promise_then callbacks registered. - * - * @param promise The promise owner for which to set the error - * @param error Eina_Error to be set - */ -EAPI void eina_promise_owner_error_set(Eina_Promise_Owner* promise, Eina_Error error); - -/* - * @brief Gets the error of the @Eina_Promise - * - * If the promise is finished and has been set with an error, it - * retuns the @Eina_Error, otherwise returns 0. - * - * @param promise The promise for which to get the error - * @return @Eina_Error set in @Eina_Promise - */ -EAPI Eina_Error eina_promise_error_get(Eina_Promise const* promise); - -/* - * @brief Returns @EINA_TRUE if the promise is still pending and - * still waiting on a value to be set and @EINA_FALSE otherwise. - * - * @param promise The promise for which to get the pending status - * @return Returns @EINA_TRUE if the promise is still pending and - * still waiting on a value to be set and @EINA_FALSE otherwise. - */ -EAPI Eina_Bool eina_promise_pending_is(Eina_Promise const* promise); - -/* - * @brief Adds a progress callback that is called by the asynchronous - * call to inform of any progress made. - * - * @param promise The promise for which to register a progress callback - * @param progress The callback to be called when progress is made - * @param data The private data that will be passed to the progress callback - */ -EAPI void eina_promise_progress_cb_add(Eina_Promise* promise, Eina_Promise_Progress_Cb progress, void* data, - Eina_Promise_Free_Cb free_cb); - -/* - * @brief Increments the reference count for the Eina_Promise - * - * @param promise The promise for which to increment its reference - */ -EAPI void eina_promise_ref(Eina_Promise* promise); - -/* - * @brief Cancel asynchronous operation, if possible. - * - * @param promise The promise to cancel - */ -EAPI void eina_promise_cancel(Eina_Promise* promise); - -/* - * @brief Gets Promise from Promise_Owner - * - * This function returns an @Eina_Promise from an - * @Eina_Promise_Owner. The user of the asynchronous operation can - * query the value from the @Eina_Promise object, while the - * asynchronous operation should use the @Eina_Promise_Owner object to - * set the value, or error, and thus finish the promise. - * - * @param promise The promise owner to get promise from. - * @return Return the @Eina_Promise - */ -EAPI Eina_Promise* eina_promise_owner_promise_get(Eina_Promise_Owner* promise); - -/* - * @brief Returns @EINA_TRUE if the promise is still pending and - * still waiting on a value to be set and @EINA_FALSE otherwise. - * - * @param promise The promise owner for which to get the pending status - * @return Returns @EINA_TRUE if the promise is still pending and - * still waiting on a value to be set and @EINA_FALSE otherwise. - */ -EAPI Eina_Bool eina_promise_owner_pending_is(Eina_Promise_Owner const* promise); - -/* - * @brief Returns @EINA_TRUE if the promise was cancelled - * or @EINA_FALSE otherwise. - * - * @param promise The promise owner for which to get the cancelled status - * @return Returns @EINA_TRUE if the promise was cancelled - * or @EINA_FALSE otherwise. - */ -EAPI Eina_Bool eina_promise_owner_cancelled_is(Eina_Promise_Owner const* promise); - -/* - * @brief Calls progress callbacks in promise, if any exists, with - * the data. - * - * The progress callbacks registered in @Eina_Promise must not free - * the progress data pointer. The data pointer ownership must be dealt - * by the @Eina_Promise_Owner's user. - * - * @param promise The promise for which to get the cancelled status - * @param data The data to be passed to progress - */ -EAPI void eina_promise_owner_progress(Eina_Promise_Owner const* promise, void* progress); - -/* - * @brief Registers a progress notify callbacks in promise owner. - * - * Registers a callback to be called for when a progress callback is - * registered by the linked @Eina_Promise. - * - * @param promise The promise for which to get the cancelled status - * @param notify_cb The callback to be called - * @param data The data to be passed to progress notify callback - * @param free_cb The free function that is called for the data param - */ -EAPI void eina_promise_owner_progress_notify(Eina_Promise_Owner* promise, - Eina_Promise_Progress_Notify_Cb notify_cb, void* data, Eina_Promise_Free_Cb free_cb); - -/* - * @brief Decrement the reference count for the Eina_Promise. - - * The Eina_Promise, if its reference count drops to zero and is not - * pending, will be free'd immediately. - * - * @param promise The promise for which to decrement its reference - */ -EAPI void eina_promise_unref(Eina_Promise* promise); - -/* - * @brief Get the reference count for the Eina_Promise. - - * @param promise The promise for which to get its reference - */ -EAPI int eina_promise_ref_get(Eina_Promise* promise); - -/* - * @brief Function callback type when promise is canceled - */ -typedef void(*Eina_Promise_Default_Cancel_Cb)(void* data, Eina_Promise_Owner* promise); - -/* - * @brief Creates a @Eina_Promise_Owner - * - * Create a @Eina_Promise_Owner for a pointer-type. Which is a promise - * with ownership of the pointer when its value is set. The Promise - * itself, returned by eina_promise_owner_promise_get, represents the - * asynchronicity of the value itself and is used solely to get the - * value and to handle users of the asynchronous value. That's why - * Promises have a reference count while Promise Owners do not, the - * eina_promise_owner_value_set must be done only once, and - * consequently, has a unique ownership of the owner lifetime, while - * the promise can be queried and used by multiple users. - * - * @return @Eina_Promise_Owner just instantiated - */ -EAPI Eina_Promise_Owner* eina_promise_add(); - -/* - * @brief Adds a cancel callback to be called when the promise is - * canceled by the usuer - * - * @param promise The promise for which to register a cancel callback - */ -EAPI void eina_promise_owner_default_cancel_cb_add( - Eina_Promise_Owner* promise, Eina_Promise_Default_Cancel_Cb cancel, void* data, - Eina_Promise_Free_Cb free_cb); - -/* - * @brief Commands the @Eina_Promise_Owner not to call the then - * callbacks automatically - * - * @param promise The promise for which to register a cancel callback - */ -EAPI void eina_promise_owner_default_manual_then_set(Eina_Promise_Owner* promise, Eina_Bool is_manual); - -/* - * @brief Calls the @Eina_Promise_Owner's then callbacks already registered - * - * @param promise The promise for which to register a cancel callback - */ -EAPI void eina_promise_owner_default_call_then(Eina_Promise_Owner* promise); - -/** - * @var EINA_ERROR_PROMISE_NO_NOTIFY - * - * @brief The error identifier corresponding to when a promise was - * free'd before any progress callback was registered - */ -EAPI extern Eina_Error EINA_ERROR_PROMISE_NO_NOTIFY; - -/** - * @var EINA_ERROR_PROMISE_CANCEL - * - * @brief The error identifier corresponding to when a promise was - * cancelled before the callback can be called - */ -EAPI extern Eina_Error EINA_ERROR_PROMISE_CANCEL; - -/** - * @var EINA_ERROR_PROMISE_NULL - * - * @brief The error identifier corresponding to when a promise function - * is called on a NULL promise - */ -EAPI extern Eina_Error EINA_ERROR_PROMISE_NULL; - -/* - * @internal - */ -#define _EINA_PROMISE_BEFORE_HOOK(PromiseValue, Ret, ...) \ - Eina_Promise_Owner* const __eo_promise = eina_promise_add(); \ - typedef Ret (*_Eo_Promise_func_t_)(Eo*, void *obj_data, ##__VA_ARGS__); \ - _Eo_Promise_func_t_ const _eo_promise_func_ = (_Eo_Promise_func_t_)_func_; - -/* - * @internal - */ -#define _EINA_PROMISE_CALL_HOOK(Arguments) \ - _eo_promise_func_(___call.eo_id, ___call.data, Arguments); - - -/* - * @internal - */ -#define _EINA_PROMISE_AFTER_HOOK(Promise) \ - if(Promise) \ - *Promise = eina_promise_owner_promise_get(__eo_promise); - -#endif - -#endif /* ! EINA_PROMISE_H_ */ --