eina: Add support for eina_safepointer in promises

This commit is contained in:
Felipe Magno de Almeida 2016-06-10 22:32:07 -03:00
parent f6d20c839e
commit 949af55947
5 changed files with 166 additions and 110 deletions

View File

@ -20,10 +20,12 @@ typedef struct _Ecore_Thread_Data _Ecore_Thread_Data;
struct _Ecore_Thread_Promise_Owner struct _Ecore_Thread_Promise_Owner
{ {
Eina_Promise_Owner owner_vtable; Eina_Promise_Owner_VTable owner_vtable;
Eina_Promise_Owner* eina_owner; Eina_Promise_Owner* eina_owner;
Eina_Promise promise_vtable; Eina_Promise_VTable promise_vtable;
Eina_Promise* eina_promise; Eina_Promise* eina_promise;
Eina_Promise_Owner* owner_pointer;
Eina_Promise* promise_pointer;
_Ecore_Thread_Data thread_callback_data; _Ecore_Thread_Data thread_callback_data;
int ref_count; int ref_count;
int then_count; int then_count;
@ -40,9 +42,9 @@ static void _ecore_promise_ref_update(_Ecore_Thread_Promise_Owner* p)
} }
if(!p->ref_count) if(!p->ref_count)
{ {
p->eina_promise->unref(p->eina_promise); eina_promise_unref(p->eina_promise);
if (!p->then_count) // Whether we still own the initial eina_promise ref if (!p->then_count) // Whether we still own the initial eina_promise ref
p->eina_promise->unref(p->eina_promise); eina_promise_unref(p->eina_promise);
p->eina_promise = NULL; p->eina_promise = NULL;
p->eina_owner = NULL; p->eina_owner = NULL;
p->thread_callback_data.thread = NULL; p->thread_callback_data.thread = NULL;
@ -83,7 +85,7 @@ static void
_ecore_promise_thread_blocking(void* data, Ecore_Thread* thread EINA_UNUSED) _ecore_promise_thread_blocking(void* data, Ecore_Thread* thread EINA_UNUSED)
{ {
_Ecore_Thread_Promise_Owner* promise = data; _Ecore_Thread_Promise_Owner* promise = data;
(promise->thread_callback_data.func_blocking)(promise->thread_callback_data.data, &promise->owner_vtable, thread); (promise->thread_callback_data.func_blocking)(promise->thread_callback_data.data, promise->owner_pointer, thread);
} }
static void _ecore_promise_thread_notify(void* data, Ecore_Thread* thread EINA_UNUSED, void* msg_data) static void _ecore_promise_thread_notify(void* data, Ecore_Thread* thread EINA_UNUSED, void* msg_data)
@ -95,7 +97,7 @@ static void _ecore_promise_thread_notify(void* data, Ecore_Thread* thread EINA_U
static void _ecore_promise_cancel_cb(void* data, Eina_Promise_Owner* promise EINA_UNUSED) static void _ecore_promise_cancel_cb(void* data, Eina_Promise_Owner* promise EINA_UNUSED)
{ {
_Ecore_Thread_Promise_Owner* priv = data; _Ecore_Thread_Promise_Owner* priv = data;
(priv->thread_callback_data.func_cancel)(priv->thread_callback_data.data, &priv->owner_vtable, (priv->thread_callback_data.func_cancel)(priv->thread_callback_data.data, priv->owner_pointer,
priv->thread_callback_data.thread); priv->thread_callback_data.thread);
} }
@ -110,23 +112,23 @@ static void _ecore_promise_thread_cancel(void* data, Ecore_Thread* thread EINA_U
static void _ecore_promise_owner_value_set(_Ecore_Thread_Promise_Owner* promise, void* data, Eina_Promise_Free_Cb free) static void _ecore_promise_owner_value_set(_Ecore_Thread_Promise_Owner* promise, void* data, Eina_Promise_Free_Cb free)
{ {
promise->eina_owner->value_set(promise->eina_owner, data, free); eina_promise_owner_value_set(promise->eina_owner, data, free);
} }
static void _ecore_promise_owner_error_set(_Ecore_Thread_Promise_Owner* promise, Eina_Error error) static void _ecore_promise_owner_error_set(_Ecore_Thread_Promise_Owner* promise, Eina_Error error)
{ {
promise->eina_owner->error_set(promise->eina_owner, error); eina_promise_owner_error_set(promise->eina_owner, error);
} }
static Eina_Bool _ecore_promise_owner_pending_is(_Ecore_Thread_Promise_Owner const* promise) static Eina_Bool _ecore_promise_owner_pending_is(_Ecore_Thread_Promise_Owner const* promise)
{ {
return promise->eina_owner->pending_is(promise->eina_owner); return eina_promise_owner_pending_is(promise->eina_owner);
} }
static Eina_Bool _ecore_promise_owner_cancelled_is(_Ecore_Thread_Promise_Owner const* promise) static Eina_Bool _ecore_promise_owner_cancelled_is(_Ecore_Thread_Promise_Owner const* promise)
{ {
return promise->eina_owner->cancelled_is(promise->eina_owner); return eina_promise_owner_cancelled_is(promise->eina_owner);
} }
static Eina_Promise* _ecore_thread_promise_owner_promise_get(_Ecore_Thread_Promise_Owner* promise) static Eina_Promise* _ecore_thread_promise_owner_promise_get(_Ecore_Thread_Promise_Owner* promise)
{ {
return &promise->promise_vtable; return promise->promise_pointer;
} }
static void _ecore_thread_promise_owner_progress(_Ecore_Thread_Promise_Owner* promise, void* data) static void _ecore_thread_promise_owner_progress(_Ecore_Thread_Promise_Owner* promise, void* data)
{ {
@ -136,42 +138,42 @@ static void _ecore_thread_promise_owner_progress_notify(_Ecore_Thread_Promise_Ow
Eina_Promise_Progress_Notify_Cb progress_cb, Eina_Promise_Progress_Notify_Cb progress_cb,
void* data, Eina_Promise_Free_Cb free_cb) void* data, Eina_Promise_Free_Cb free_cb)
{ {
promise->eina_owner->progress_notify(promise->eina_owner, progress_cb, data, free_cb); eina_promise_owner_progress_notify(promise->eina_owner, progress_cb, data, free_cb);
} }
static void _ecore_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback, static void _ecore_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback,
Eina_Promise_Error_Cb error_cb, void* data) Eina_Promise_Error_Cb error_cb, void* data)
{ {
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
v->eina_promise->then(v->eina_promise, callback, error_cb, data); eina_promise_then(v->eina_promise, callback, error_cb, data);
v->ref_count++; v->ref_count++;
v->then_count++; v->then_count++;
} }
static void* _ecore_promise_value_get(Eina_Promise const* promise) static void* _ecore_promise_value_get(Eina_Promise const* promise)
{ {
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
return v->eina_promise->value_get(v->eina_promise); return eina_promise_value_get(v->eina_promise);
} }
static Eina_Error _ecore_promise_error_get(Eina_Promise const* promise) static Eina_Error _ecore_promise_error_get(Eina_Promise const* promise)
{ {
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
return v->eina_promise->error_get(v->eina_promise); return eina_promise_error_get(v->eina_promise);
} }
static Eina_Bool _ecore_promise_pending_is(Eina_Promise const* promise) static Eina_Bool _ecore_promise_pending_is(Eina_Promise const* promise)
{ {
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
return v->eina_promise->pending_is(v->eina_promise); return eina_promise_pending_is(v->eina_promise);
} }
static void _ecore_promise_progress_cb_add(Eina_Promise const* promise, Eina_Promise_Progress_Cb callback, void* data, static void _ecore_promise_progress_cb_add(Eina_Promise const* promise, Eina_Promise_Progress_Cb callback, void* data,
Eina_Promise_Free_Cb free_cb) Eina_Promise_Free_Cb free_cb)
{ {
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
v->eina_promise->progress_cb_add(v->eina_promise, callback, data, free_cb); eina_promise_progress_cb_add(v->eina_promise, callback, data, free_cb);
} }
static void _ecore_promise_cancel(Eina_Promise const* promise) static void _ecore_promise_cancel(Eina_Promise const* promise)
{ {
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
v->eina_promise->cancel(v->eina_promise); eina_promise_cancel(v->eina_promise);
} }
static void _ecore_promise_ref(Eina_Promise const* promise) static void _ecore_promise_ref(Eina_Promise const* promise)
{ {
@ -204,6 +206,7 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
priv->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(&_ecore_thread_promise_owner_progress); priv->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(&_ecore_thread_promise_owner_progress);
priv->owner_vtable.progress_notify = EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(&_ecore_thread_promise_owner_progress_notify); priv->owner_vtable.progress_notify = EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(&_ecore_thread_promise_owner_progress_notify);
EINA_MAGIC_SET(&priv->owner_vtable, EINA_MAGIC_PROMISE_OWNER); EINA_MAGIC_SET(&priv->owner_vtable, EINA_MAGIC_PROMISE_OWNER);
priv->owner_pointer = eina_promise_owner_override(&priv->owner_vtable);
priv->promise_vtable.then = EINA_FUNC_PROMISE_THEN(&_ecore_promise_then); priv->promise_vtable.then = EINA_FUNC_PROMISE_THEN(&_ecore_promise_then);
priv->promise_vtable.value_get = EINA_FUNC_PROMISE_VALUE_GET(&_ecore_promise_value_get); priv->promise_vtable.value_get = EINA_FUNC_PROMISE_VALUE_GET(&_ecore_promise_value_get);
@ -214,14 +217,15 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
priv->promise_vtable.ref = EINA_FUNC_PROMISE_REF(&_ecore_promise_ref); priv->promise_vtable.ref = EINA_FUNC_PROMISE_REF(&_ecore_promise_ref);
priv->promise_vtable.unref = EINA_FUNC_PROMISE_UNREF(&_ecore_promise_unref); priv->promise_vtable.unref = EINA_FUNC_PROMISE_UNREF(&_ecore_promise_unref);
EINA_MAGIC_SET(&priv->promise_vtable, EINA_MAGIC_PROMISE); EINA_MAGIC_SET(&priv->promise_vtable, EINA_MAGIC_PROMISE);
priv->promise_pointer = eina_promise_override(&priv->promise_vtable);
priv->thread_callback_data.data = data; priv->thread_callback_data.data = data;
priv->thread_callback_data.func_blocking = func_blocking; priv->thread_callback_data.func_blocking = func_blocking;
priv->thread_callback_data.func_cancel = func_cancel; priv->thread_callback_data.func_cancel = func_cancel;
eina_promise_owner_default_manual_then_set(priv->eina_owner, EINA_TRUE); eina_promise_owner_default_manual_then_set(priv->eina_owner, EINA_TRUE);
priv->eina_promise = priv->eina_owner->promise_get(priv->eina_owner); priv->eina_promise = eina_promise_owner_promise_get(priv->eina_owner);
priv->eina_promise->ref(priv->eina_promise); eina_promise_ref(priv->eina_promise);
priv->ref_count = 0; priv->ref_count = 0;
priv->then_count = 0; priv->then_count = 0;
@ -232,6 +236,6 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
&_ecore_promise_thread_end, &_ecore_promise_thread_cancel, priv, &_ecore_promise_thread_end, &_ecore_promise_thread_cancel, priv,
EINA_FALSE); EINA_FALSE);
if(promise) if(promise)
*promise = &priv->promise_vtable; *promise = priv->promise_pointer;
return priv->thread_callback_data.thread; return priv->thread_callback_data.thread;
} }

View File

@ -154,8 +154,8 @@ EAPI Eina_Inlist *_eina_tracking = NULL;
S(cpu); S(cpu);
S(thread_queue); S(thread_queue);
S(rbtree); S(rbtree);
S(promise);
S(safepointer); S(safepointer);
S(promise);
/* no model for now /* no model for now
S(model); S(model);
*/ */
@ -203,8 +203,8 @@ static const struct eina_desc_setup _eina_desc_setup[] = {
S(cpu), S(cpu),
S(thread_queue), S(thread_queue),
S(rbtree), S(rbtree),
S(promise), S(safepointer),
S(safepointer) S(promise)
/* no model for now /* no model for now
S(model) S(model)
*/ */

View File

@ -27,6 +27,9 @@ static int _eina_promise_log_dom = -1;
#define EINA_MAGIC_CHECK_PROMISE_OWNER(promise) \ #define EINA_MAGIC_CHECK_PROMISE_OWNER(promise) \
do {if(!EINA_MAGIC_CHECK(promise, EINA_MAGIC_PROMISE_OWNER)) \ do {if(!EINA_MAGIC_CHECK(promise, EINA_MAGIC_PROMISE_OWNER)) \
{EINA_MAGIC_FAIL(promise, EINA_MAGIC_PROMISE_OWNER);} } while(0) {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_Then_Cb _Eina_Promise_Then_Cb;
typedef struct _Eina_Promise_Progress_Cb _Eina_Promise_Progress_Cb; typedef struct _Eina_Promise_Progress_Cb _Eina_Promise_Progress_Cb;
@ -75,7 +78,7 @@ struct _Eina_Promise_Owner_Progress_Notify_Data
struct _Eina_Promise_Default struct _Eina_Promise_Default
{ {
Eina_Promise vtable; Eina_Promise_VTable vtable;
Eina_Error error; Eina_Error error;
size_t value_size; size_t value_size;
@ -84,6 +87,7 @@ struct _Eina_Promise_Default
Eina_Inlist *cancel_callbacks; Eina_Inlist *cancel_callbacks;
Eina_Inlist *progress_notify_callbacks; Eina_Inlist *progress_notify_callbacks;
Eina_Promise_Free_Cb value_free_cb; Eina_Promise_Free_Cb value_free_cb;
Eina_Promise* promise_pointer;
int ref; int ref;
@ -97,9 +101,9 @@ struct _Eina_Promise_Default
struct _Eina_Promise_Default_Owner struct _Eina_Promise_Default_Owner
{ {
Eina_Promise_Owner owner_vtable; Eina_Promise_Owner_VTable owner_vtable;
_Eina_Promise_Default promise; _Eina_Promise_Default promise;
Eina_Promise_Owner* owner_pointer;
void* pointer_value; void* pointer_value;
}; };
@ -290,7 +294,7 @@ _eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback,
EINA_INLIST_FOREACH(promise->promise.progress_notify_callbacks, notify_data) EINA_INLIST_FOREACH(promise->promise.progress_notify_callbacks, notify_data)
{ {
(*notify_data->callback)(notify_data->data, &promise->owner_vtable); (*notify_data->callback)(notify_data->data, promise->owner_pointer);
} }
_eina_promise_free_callback_list(&promise->promise.progress_notify_callbacks, &free); _eina_promise_free_callback_list(&promise->promise.progress_notify_callbacks, &free);
@ -372,7 +376,7 @@ _eina_promise_progress_cb_add(_Eina_Promise_Default* promise, Eina_Promise_Progr
promise->progress_callbacks = eina_inlist_append(promise->progress_callbacks, EINA_INLIST_GET(cb)); promise->progress_callbacks = eina_inlist_append(promise->progress_callbacks, EINA_INLIST_GET(cb));
EINA_INLIST_FOREACH(owner->promise.progress_notify_callbacks, notify_data) EINA_INLIST_FOREACH(owner->promise.progress_notify_callbacks, notify_data)
{ {
(*notify_data->callback)(notify_data->data, &owner->owner_vtable); (*notify_data->callback)(notify_data->data, owner->owner_pointer);
} }
_eina_promise_free_callback_list(&owner->promise.progress_notify_callbacks, _eina_promise_free_callback_list(&owner->promise.progress_notify_callbacks,
&_eina_promise_free_progress_notify_callback_node); &_eina_promise_free_progress_notify_callback_node);
@ -417,19 +421,17 @@ _eina_promise_ref_get(_Eina_Promise_Default* p)
static Eina_Promise * static Eina_Promise *
_eina_promise_owner_promise_get(_Eina_Promise_Default_Owner* p) _eina_promise_owner_promise_get(_Eina_Promise_Default_Owner* p)
{ {
return &p->promise.vtable; return p->promise.promise_pointer;
} }
void EAPI void
eina_promise_owner_default_cancel_cb_add(Eina_Promise_Owner* p, eina_promise_owner_default_cancel_cb_add(Eina_Promise_Owner* p,
Eina_Promise_Default_Cancel_Cb callback, void* data, Eina_Promise_Default_Cancel_Cb callback, void* data,
Eina_Promise_Free_Cb free_cb) Eina_Promise_Free_Cb free_cb)
{ {
_Eina_Promise_Default_Owner *promise; _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, p, );
_Eina_Promise_Cancel_Cb *cb; _Eina_Promise_Cancel_Cb *cb;
promise = (_Eina_Promise_Default_Owner *)p;
cb = malloc(sizeof(struct _Eina_Promise_Cancel_Cb)); cb = malloc(sizeof(struct _Eina_Promise_Cancel_Cb));
cb->callback = callback; cb->callback = callback;
@ -486,6 +488,7 @@ static void eina_promise_add_internal(_Eina_Promise_Default_Owner* p)
p->promise.is_first_then = EINA_TRUE; p->promise.is_first_then = EINA_TRUE;
p->promise.ref = 1; p->promise.ref = 1;
p->promise.promise_pointer = eina_promise_override(&p->promise.vtable);
p->owner_vtable.version = EINA_PROMISE_VERSION; 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.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(_eina_promise_owner_value_set);
@ -496,6 +499,7 @@ static void eina_promise_add_internal(_Eina_Promise_Default_Owner* p)
p->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(_eina_promise_owner_progress); 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); 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); EINA_MAGIC_SET(&p->owner_vtable, EINA_MAGIC_PROMISE_OWNER);
p->owner_pointer = eina_promise_owner_override(&p->owner_vtable);
} }
EAPI Eina_Promise_Owner * EAPI Eina_Promise_Owner *
@ -504,25 +508,28 @@ eina_promise_add()
_Eina_Promise_Default_Owner* p; _Eina_Promise_Default_Owner* p;
p = calloc(sizeof(_Eina_Promise_Default_Owner), 1); p = calloc(sizeof(_Eina_Promise_Default_Owner), 1);
eina_promise_add_internal(p); eina_promise_add_internal(p);
return &p->owner_vtable; return p->owner_pointer;
} }
void EAPI void
eina_promise_owner_default_manual_then_set(Eina_Promise_Owner* owner, Eina_Bool is_manual) eina_promise_owner_default_manual_then_set(Eina_Promise_Owner* owner, Eina_Bool is_manual)
{ {
_Eina_Promise_Default_Owner* p = (_Eina_Promise_Default_Owner*)owner; _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; p->promise.is_manual_then = is_manual;
} }
void EAPI void
eina_promise_owner_default_call_then(Eina_Promise_Owner* promise) eina_promise_owner_default_call_then(Eina_Promise_Owner* owner)
{ {
_Eina_Promise_Default_Owner* owner = (_Eina_Promise_Default_Owner*)promise; _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(p, owner, );
EINA_MAGIC_CHECK_PROMISE_OWNER(&p->owner_vtable);
_eina_promise_then_calls(owner); _eina_promise_then_calls(p);
} }
// eina_promise_all implementation
static void static void
_eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED) _eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED)
{ {
@ -538,7 +545,7 @@ _eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED)
_eina_promise_finish(promise); _eina_promise_finish(promise);
} }
} }
eina_promise_unref(&promise->promise.vtable); eina_promise_unref(promise->promise.promise_pointer);
} }
static void static void
@ -553,7 +560,7 @@ _eina_promise_all_compose_error_then_cb(void *data, Eina_Error error)
promise->promise.error = error; promise->promise.error = error;
_eina_promise_finish(promise); _eina_promise_finish(promise);
} }
eina_promise_unref(&promise->promise.vtable); eina_promise_unref(promise->promise.promise_pointer);
} }
static void static void
@ -572,6 +579,7 @@ _eina_promise_all_free(_Eina_Promise_Iterator* value)
Eina_Promise * Eina_Promise *
eina_promise_all(Eina_Iterator* it) eina_promise_all(Eina_Iterator* it)
{ {
Eina_Promise_Owner *safe_promise;
_Eina_Promise_Default_Owner *promise; _Eina_Promise_Default_Owner *promise;
Eina_Promise* current; Eina_Promise* current;
Eina_Array* promises; Eina_Array* promises;
@ -589,14 +597,12 @@ eina_promise_all(Eina_Iterator* it)
eina_iterator_free(it); eina_iterator_free(it);
promise = (_Eina_Promise_Default_Owner*)eina_promise_add(); promise = eina_safepointer_get((Eina_Safepointer*)(safe_promise = eina_promise_add()));
internal_it = malloc(sizeof(_Eina_Promise_Iterator) + internal_it = promise->pointer_value = malloc(sizeof(_Eina_Promise_Iterator) +
sizeof(_Eina_Promise_Default_Owner*) * eina_array_count_get(promises)); sizeof(_Eina_Promise_Default_Owner*) * eina_array_count_get(promises));
promise->promise.value_free_cb = (Eina_Promise_Free_Cb)&_eina_promise_all_free; promise->promise.value_free_cb = (Eina_Promise_Free_Cb)&_eina_promise_all_free;
promise->pointer_value = (void*)internal_it;
_eina_promise_iterator_setup(internal_it, promises); _eina_promise_iterator_setup(internal_it, promises);
cur_promise = internal_it->data.promises; cur_promise = internal_it->data.promises;
@ -605,13 +611,13 @@ eina_promise_all(Eina_Iterator* it)
{ {
eina_promise_ref(*cur_promise); // We need to keep the value alive until this promise is freed 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 // We need to keep the all promise alive while there are callbacks registered to it
eina_promise_ref(&promise->promise.vtable); eina_promise_ref(promise->promise.promise_pointer);
eina_promise_then(*cur_promise, &_eina_promise_all_compose_then_cb, eina_promise_then(*cur_promise, &_eina_promise_all_compose_then_cb,
&_eina_promise_all_compose_error_then_cb, promise); &_eina_promise_all_compose_error_then_cb, promise);
} }
eina_array_free(promises); eina_array_free(promises);
return &promise->promise.vtable; return promise->promise.promise_pointer;
} }
static Eina_Bool static Eina_Bool
@ -686,19 +692,6 @@ _eina_promise_progress_notify_finish(void* data)
eina_promise_unref(eina_promise_owner_promise_get(owner)); eina_promise_unref(eina_promise_owner_promise_get(owner));
} }
EAPI Eina_Promise*
eina_promise_progress_notification(Eina_Promise_Owner* promise)
{
Eina_Promise_Owner* owner;
owner = eina_promise_add();
eina_promise_owner_progress_notify(promise, &_eina_promise_progress_notify_fulfilled, owner,
&_eina_promise_progress_notify_finish);
return eina_promise_owner_promise_get(owner);
}
// Race implementation // Race implementation
static void _eina_promise_race_unref(_Eina_Promise_Race* p) static void _eina_promise_race_unref(_Eina_Promise_Race* p)
{ {
@ -721,8 +714,8 @@ _eina_promise_race_compose_then_cb(void *data, void* value EINA_UNUSED)
_Eina_Promise_Race* race_promise = info->self; _Eina_Promise_Race* race_promise = info->self;
if (!race_promise->promise_default.promise.has_finished) if (!race_promise->promise_default.promise.has_finished)
eina_promise_owner_value_set(&race_promise->promise_default.owner_vtable, value, NULL); eina_promise_owner_value_set(race_promise->promise_default.owner_pointer, value, NULL);
eina_promise_unref(&race_promise->promise_default.promise.vtable); eina_promise_unref(race_promise->promise_default.promise.promise_pointer);
} }
static void static void
@ -732,8 +725,8 @@ _eina_promise_race_compose_error_then_cb(void *data, Eina_Error error)
_Eina_Promise_Race* race_promise = info->self; _Eina_Promise_Race* race_promise = info->self;
if (!race_promise->promise_default.promise.has_finished) if (!race_promise->promise_default.promise.has_finished)
eina_promise_owner_error_set(&race_promise->promise_default.owner_vtable, error); eina_promise_owner_error_set(race_promise->promise_default.owner_pointer, error);
eina_promise_unref(&race_promise->promise_default.promise.vtable); eina_promise_unref(race_promise->promise_default.promise.promise_pointer);
} }
Eina_Promise * Eina_Promise *
@ -771,21 +764,52 @@ eina_promise_race(Eina_Iterator* it)
cur_promise->self = promise; cur_promise->self = promise;
eina_promise_ref(cur_promise->promise); // We need to keep the value alive until this promise is freed 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 // We need to keep the all promise alive while there are callbacks registered to it
eina_promise_ref(&promise->promise_default.promise.vtable); eina_promise_ref(promise->promise_default.promise.promise_pointer);
eina_promise_then(cur_promise->promise, &_eina_promise_race_compose_then_cb, eina_promise_then(cur_promise->promise, &_eina_promise_race_compose_then_cb,
&_eina_promise_race_compose_error_then_cb, cur_promise); &_eina_promise_race_compose_error_then_cb, cur_promise);
} }
eina_array_free(promises); eina_array_free(promises);
return &promise->promise_default.promise.vtable; return promise->promise_default.promise.promise_pointer;
} }
// API functions // 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 EAPI void
eina_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback, eina_promise_then(Eina_Promise* safe_promise, Eina_Promise_Cb callback,
Eina_Promise_Error_Cb error_cb, void* data) Eina_Promise_Error_Cb error_cb, void* data)
{ {
if(!promise) Eina_Promise_VTable* promise = eina_safepointer_get((void*)safe_promise);
if(!safe_promise || !promise)
{ {
if(!error_cb) if(!error_cb)
{ {
@ -801,122 +825,137 @@ eina_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback,
} }
EAPI void EAPI void
eina_promise_owner_value_set(Eina_Promise_Owner* promise, const void* value, Eina_Promise_Free_Cb free) 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_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE_OWNER(promise); EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
promise->value_set(promise, value, free); promise->value_set(promise, value, free);
} }
EAPI void EAPI void
eina_promise_owner_error_set(Eina_Promise_Owner* promise, Eina_Error error) 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_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE_OWNER(promise); EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
promise->error_set(promise, error); promise->error_set(promise, error);
} }
EAPI void * EAPI void *
eina_promise_value_get(Eina_Promise const* promise) 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_PROMISE_NULL_CHECK(promise, NULL);
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
return promise->value_get(promise); return promise->value_get(promise);
} }
EAPI Eina_Error EAPI Eina_Error
eina_promise_error_get(Eina_Promise const* promise) 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_PROMISE_NULL_CHECK(promise, EINA_ERROR_PROMISE_NULL);
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
return promise->error_get(promise); return promise->error_get(promise);
} }
EAPI Eina_Bool EAPI Eina_Bool
eina_promise_pending_is(Eina_Promise const* promise) 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_PROMISE_NULL_CHECK(promise, EINA_FALSE);
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
return promise->pending_is(promise); return promise->pending_is(promise);
} }
EAPI void EAPI void
eina_promise_progress_cb_add(Eina_Promise* promise, Eina_Promise_Progress_Cb callback, void* data, eina_promise_progress_cb_add(Eina_Promise* safe_promise, Eina_Promise_Progress_Cb callback, void* data,
Eina_Promise_Free_Cb free_cb) Eina_Promise_Free_Cb free_cb)
{ {
Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
_EINA_PROMISE_NULL_CHECK(promise, ); _EINA_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
promise->progress_cb_add(promise, callback, data, free_cb); promise->progress_cb_add(promise, callback, data, free_cb);
} }
EAPI void EAPI void
eina_promise_cancel(Eina_Promise* promise) 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_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
promise->cancel(promise); promise->cancel(promise);
} }
EAPI void EAPI void
eina_promise_ref(Eina_Promise* promise) 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_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
promise->ref(promise); promise->ref(promise);
} }
EAPI void EAPI void
eina_promise_unref(Eina_Promise* promise) 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_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
promise->unref(promise); promise->unref(promise);
} }
EAPI int EAPI int
eina_promise_ref_get(Eina_Promise* promise) 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_PROMISE_NULL_CHECK(promise, 0);
EINA_MAGIC_CHECK_PROMISE(promise); EINA_MAGIC_CHECK_PROMISE(promise);
return promise->ref_get(promise); return promise->ref_get(promise);
} }
EAPI Eina_Promise * EAPI Eina_Promise *
eina_promise_owner_promise_get(Eina_Promise_Owner* 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_PROMISE_NULL_CHECK(promise, NULL);
EINA_MAGIC_CHECK_PROMISE_OWNER(promise); EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
return promise->promise_get(promise); return promise->promise_get(promise);
} }
EAPI Eina_Bool EAPI Eina_Bool
eina_promise_owner_pending_is(Eina_Promise_Owner const* promise) 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_PROMISE_NULL_CHECK(promise, EINA_FALSE);
EINA_MAGIC_CHECK_PROMISE_OWNER(promise); EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
return promise->pending_is(promise); return promise->pending_is(promise);
} }
EAPI Eina_Bool EAPI Eina_Bool
eina_promise_owner_cancelled_is(Eina_Promise_Owner const* promise) 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_PROMISE_NULL_CHECK(promise, EINA_FALSE);
EINA_MAGIC_CHECK_PROMISE_OWNER(promise); EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
return promise->cancelled_is(promise); return promise->cancelled_is(promise);
} }
EAPI void EAPI void
eina_promise_owner_progress(Eina_Promise_Owner const* promise, void* progress) 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_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE_OWNER(promise); EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
promise->progress(promise, progress); promise->progress(promise, progress);
} }
EAPI void EAPI void
eina_promise_owner_progress_notify(Eina_Promise_Owner* promise, Eina_Promise_Progress_Notify_Cb progress_cb, 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) 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_PROMISE_NULL_CHECK(promise, );
EINA_MAGIC_CHECK_PROMISE_OWNER(promise); EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
promise->progress_notify(promise, progress_cb, data, free_cb); promise->progress_notify(promise, progress_cb, data, free_cb);

View File

@ -3,19 +3,26 @@
#ifdef EFL_BETA_API_SUPPORT #ifdef EFL_BETA_API_SUPPORT
struct _Eina_Promise;
struct _Eina_Promise_Default;
/* /*
* @def Eina_Promise * @def Eina_Promise
*/ */
typedef struct _Eina_Promise Eina_Promise; typedef struct _Eina_Promise Eina_Promise;
/*
* @def Eina_Promise_VTable
*/
typedef struct _Eina_Promise_VTable Eina_Promise_VTable;
/* /*
* @def Eina_Promise * @def Eina_Promise
*/ */
typedef struct _Eina_Promise_Owner Eina_Promise_Owner; 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 * @brief Callback type for freeing Promise value and void* pointer data for callbacks
*/ */
@ -44,7 +51,7 @@ typedef void(*Eina_Promise_Progress_Cb)(void* data, void* value);
/* /*
* @brief Function callback type for then function override * @brief Function callback type for then function override
*/ */
typedef void(*Eina_Promise_Then_Cb)(Eina_Promise* promise, Eina_Promise_Cb callback, typedef void(*Eina_Promise_Then_Cb)(Eina_Promise_VTable* promise, Eina_Promise_Cb callback,
Eina_Promise_Error_Cb error_cb, void* data); Eina_Promise_Error_Cb error_cb, void* data);
#define EINA_FUNC_PROMISE_THEN(Function) ((Eina_Promise_Then_Cb)Function) #define EINA_FUNC_PROMISE_THEN(Function) ((Eina_Promise_Then_Cb)Function)
@ -52,28 +59,28 @@ typedef void(*Eina_Promise_Then_Cb)(Eina_Promise* promise, Eina_Promise_Cb callb
/* /*
* @brief Function callback type for promise's value_get function override * @brief Function callback type for promise's value_get function override
*/ */
typedef void*(*Eina_Promise_Value_Get_Cb)(Eina_Promise const* promise); 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) #define EINA_FUNC_PROMISE_VALUE_GET(Function) ((Eina_Promise_Value_Get_Cb)Function)
/* /*
* @brief Function callback type for promise's error_get function override * @brief Function callback type for promise's error_get function override
*/ */
typedef Eina_Error(*Eina_Promise_Error_Get_Cb)(Eina_Promise const* promise); 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) #define EINA_FUNC_PROMISE_ERROR_GET(Function) ((Eina_Promise_Error_Get_Cb)Function)
/* /*
* @brief Function callback type for promise's pending function override * @brief Function callback type for promise's pending function override
*/ */
typedef Eina_Bool(*Eina_Promise_Pending_Is_Cb)(Eina_Promise const* promise); 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) #define EINA_FUNC_PROMISE_PENDING_IS(Function) ((Eina_Promise_Pending_Is_Cb)Function)
/* /*
* @brief Function callback type for promise's progress add function override * @brief Function callback type for promise's progress add function override
*/ */
typedef void(*Eina_Promise_Progress_Cb_Add_Cb)(Eina_Promise* promise, Eina_Promise_Progress_Cb callback, void* data 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); , Eina_Promise_Free_Cb free_cb);
#define EINA_FUNC_PROMISE_PROGRESS_CB_ADD(Function) ((Eina_Promise_Progress_Cb_Add_Cb)Function) #define EINA_FUNC_PROMISE_PROGRESS_CB_ADD(Function) ((Eina_Promise_Progress_Cb_Add_Cb)Function)
@ -81,91 +88,91 @@ typedef void(*Eina_Promise_Progress_Cb_Add_Cb)(Eina_Promise* promise, Eina_Promi
/* /*
* @brief Function callback type for promise's cancel function override * @brief Function callback type for promise's cancel function override
*/ */
typedef void(*Eina_Promise_Cancel_Cb)(Eina_Promise* promise); typedef void(*Eina_Promise_Cancel_Cb)(Eina_Promise_VTable* promise);
#define EINA_FUNC_PROMISE_CANCEL(Function) ((Eina_Promise_Cancel_Cb)Function) #define EINA_FUNC_PROMISE_CANCEL(Function) ((Eina_Promise_Cancel_Cb)Function)
/* /*
* @brief Function callback type for promise's ref function override * @brief Function callback type for promise's ref function override
*/ */
typedef void(*Eina_Promise_Ref_Cb)(Eina_Promise* promise); typedef void(*Eina_Promise_Ref_Cb)(Eina_Promise_VTable* promise);
#define EINA_FUNC_PROMISE_REF(Function) ((Eina_Promise_Ref_Cb)Function) #define EINA_FUNC_PROMISE_REF(Function) ((Eina_Promise_Ref_Cb)Function)
/* /*
* @brief Function callback type for promise's unref function override * @brief Function callback type for promise's unref function override
*/ */
typedef void(*Eina_Promise_Unref_Cb)(Eina_Promise* promise); typedef void(*Eina_Promise_Unref_Cb)(Eina_Promise_VTable* promise);
#define EINA_FUNC_PROMISE_UNREF(Function) ((Eina_Promise_Unref_Cb)Function) #define EINA_FUNC_PROMISE_UNREF(Function) ((Eina_Promise_Unref_Cb)Function)
/* /*
* @brief Function callback type for promise's ref_get function override * @brief Function callback type for promise's ref_get function override
*/ */
typedef int(*Eina_Promise_Ref_Get_Cb)(Eina_Promise* promise); typedef int(*Eina_Promise_Ref_Get_Cb)(Eina_Promise_VTable* promise);
#define EINA_FUNC_PROMISE_REF_GET(Function) ((Eina_Promise_Ref_Get_Cb)Function) #define EINA_FUNC_PROMISE_REF_GET(Function) ((Eina_Promise_Ref_Get_Cb)Function)
/* /*
* @brief Function callback type for promise's buffer_get function override * @brief Function callback type for promise's buffer_get function override
*/ */
typedef void*(*Eina_Promise_Buffer_Get_Cb)(Eina_Promise* promise); typedef void*(*Eina_Promise_Buffer_Get_Cb)(Eina_Promise_VTable* promise);
#define EINA_FUNC_PROMISE_BUFFER_GET(Function) ((Eina_Promise_Buffer_Get_Cb)Function) #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 * @brief Function callback type for promise owner's buffer_get function override
*/ */
typedef void*(*Eina_Promise_Owner_Buffer_Get_Cb)(Eina_Promise_Owner* promise); 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) #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 * @brief Function callback type for promise owner's promise_get function override
*/ */
typedef void*(*Eina_Promise_Owner_Promise_Get_Cb)(Eina_Promise_Owner const* promise); 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) #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 * @brief Function callback type for promise owner's value_set function override
*/ */
typedef void(*Eina_Promise_Owner_Value_Set_Cb)(Eina_Promise_Owner* promise, const void* data, Eina_Promise_Free_Cb free_fun); 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) #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 * @brief Function callback type for promise owner's error_set function override
*/ */
typedef void(*Eina_Promise_Owner_Error_Set_Cb)(Eina_Promise_Owner* promise, Eina_Error error); 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) #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 * @brief Function callback type for promise owner's pending function override
*/ */
typedef Eina_Bool(*Eina_Promise_Owner_Pending_Is_Cb)(Eina_Promise_Owner const* promise); 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) #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 * @brief Function callback type for promise owner's cancelled function override
*/ */
typedef Eina_Bool(*Eina_Promise_Owner_Cancelled_Is_Cb)(Eina_Promise_Owner const* promise); 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) #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 * @brief Function callback type for promise owner's progress function override
*/ */
typedef Eina_Bool(*Eina_Promise_Owner_Progress_Cb)(Eina_Promise_Owner const* promise, void* progress); 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) #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 * @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* promise, 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); 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_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(Function) ((Eina_Promise_Owner_Progress_Notify_Cb)Function)
@ -173,7 +180,7 @@ typedef Eina_Bool(*Eina_Promise_Owner_Progress_Notify_Cb)(Eina_Promise_Owner* pr
#define EINA_PROMISE_VERSION 1 #define EINA_PROMISE_VERSION 1
struct _Eina_Promise struct _Eina_Promise_VTable
{ {
int version; int version;
Eina_Promise_Then_Cb then; Eina_Promise_Then_Cb then;
@ -189,7 +196,7 @@ struct _Eina_Promise
EINA_MAGIC; EINA_MAGIC;
}; };
struct _Eina_Promise_Owner struct _Eina_Promise_Owner_VTable
{ {
int version; int version;
Eina_Promise_Owner_Value_Set_Cb value_set; Eina_Promise_Owner_Value_Set_Cb value_set;
@ -203,6 +210,10 @@ struct _Eina_Promise_Owner
EINA_MAGIC; 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 * @brief Appends a callback to be called when the Eina_Promise is
* finished. * finished.

View File

@ -269,6 +269,7 @@ START_TEST(eina_test_pointer_promise_manual_then)
eina_promise_owner_default_manual_then_set(promise_owner, EINA_TRUE); eina_promise_owner_default_manual_then_set(promise_owner, EINA_TRUE);
promise = eina_promise_owner_promise_get(promise_owner); promise = eina_promise_owner_promise_get(promise_owner);
eina_promise_ref(promise);
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran); eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
@ -277,6 +278,7 @@ START_TEST(eina_test_pointer_promise_manual_then)
ck_assert(!ran); ck_assert(!ran);
eina_promise_owner_default_call_then(promise_owner); eina_promise_owner_default_call_then(promise_owner);
eina_promise_unref(promise);
ck_assert(ran); ck_assert(ran);
@ -685,7 +687,7 @@ END_TEST
void void
eina_test_promise(TCase *tc) eina_test_promise(TCase *tc)
{ {
/* // pointer */ // pointer
tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime); tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime);
tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime_all); tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime_all);
tcase_add_test(tc, eina_test_pointer_promise_error_set); tcase_add_test(tc, eina_test_pointer_promise_error_set);