forked from enlightenment/efl
eina: Fix memory leaks in promise
This commit is contained in:
parent
ba1e70278e
commit
6d43adaaf4
|
@ -7,6 +7,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include <ecore_private.h>
|
||||
|
||||
struct _Ecore_Thread_Data
|
||||
{
|
||||
Ecore_Thread_Promise_Cb func_blocking;
|
||||
|
@ -20,10 +22,38 @@ struct _Ecore_Thread_Promise_Owner
|
|||
{
|
||||
Eina_Promise_Owner owner_vtable;
|
||||
Eina_Promise_Owner* eina_owner;
|
||||
Eina_Promise promise_vtable;
|
||||
Eina_Promise* eina_promise;
|
||||
_Ecore_Thread_Data thread_callback_data;
|
||||
int ref_count;
|
||||
int then_count;
|
||||
};
|
||||
typedef struct _Ecore_Thread_Promise_Owner _Ecore_Thread_Promise_Owner;
|
||||
|
||||
#define ECORE_PROMISE_GET_OWNER(p) (_Ecore_Thread_Promise_Owner*)((unsigned char*)p - offsetof(struct _Ecore_Thread_Promise_Owner, promise_vtable))
|
||||
|
||||
static void _ecore_promise_ref_update(_Ecore_Thread_Promise_Owner* p)
|
||||
{
|
||||
if(p->ref_count < 0)
|
||||
{
|
||||
ERR("Reference count is negative for promise %p\n", p);
|
||||
}
|
||||
if(!p->ref_count)
|
||||
{
|
||||
p->eina_promise->unref(p->eina_promise);
|
||||
p->eina_promise = NULL;
|
||||
p->eina_owner = NULL;
|
||||
p->thread_callback_data.thread = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void _ecore_promise_thread_release_ref(void* data, void* value EINA_UNUSED)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* p = data;
|
||||
p->ref_count -= p->then_count;
|
||||
_ecore_promise_ref_update(p);
|
||||
}
|
||||
|
||||
static void _ecore_promise_thread_end(void* data, Ecore_Thread* thread EINA_UNUSED)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* p = data;
|
||||
|
@ -31,10 +61,14 @@ static void _ecore_promise_thread_end(void* data, Ecore_Thread* thread EINA_UNUS
|
|||
{
|
||||
eina_promise_owner_default_manual_then_set(p->eina_owner, EINA_FALSE);
|
||||
eina_promise_owner_default_call_then(p->eina_owner);
|
||||
p->ref_count -= p->then_count;
|
||||
_ecore_promise_ref_update(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
eina_promise_owner_default_manual_then_set(p->eina_owner, EINA_FALSE);
|
||||
eina_promise_then(p->eina_promise, &_ecore_promise_thread_release_ref,
|
||||
(Eina_Promise_Error_Cb)&_ecore_promise_thread_release_ref, p);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,7 +85,7 @@ static void _ecore_promise_thread_notify(void* data, Ecore_Thread* thread EINA_U
|
|||
eina_promise_owner_progress(promise->eina_owner, msg_data);
|
||||
}
|
||||
|
||||
static void _ecore_promise_cancel(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;
|
||||
(priv->thread_callback_data.func_cancel)(priv->thread_callback_data.data, &priv->owner_vtable,
|
||||
|
@ -93,12 +127,76 @@ static Eina_Bool _ecore_promise_owner_cancelled_is(_Ecore_Thread_Promise_Owner c
|
|||
}
|
||||
static Eina_Promise* _ecore_thread_promise_owner_promise_get(_Ecore_Thread_Promise_Owner* promise)
|
||||
{
|
||||
return promise->eina_owner->promise_get(promise->eina_owner);
|
||||
return &promise->promise_vtable;
|
||||
}
|
||||
static void _ecore_thread_promise_owner_progress(_Ecore_Thread_Promise_Owner* promise, void* data)
|
||||
{
|
||||
ecore_thread_feedback(promise->thread_callback_data.thread, data);
|
||||
}
|
||||
static void _ecore_thread_promise_owner_progress_notify(_Ecore_Thread_Promise_Owner* promise,
|
||||
Eina_Promise_Progress_Notify_Cb progress_cb,
|
||||
void* data, Eina_Promise_Free_Cb free_cb)
|
||||
{
|
||||
promise->eina_owner->progress_notify(promise->eina_owner, progress_cb, data, free_cb);
|
||||
}
|
||||
|
||||
static void _ecore_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback,
|
||||
Eina_Promise_Error_Cb error_cb, void* data)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
v->eina_promise->then(v->eina_promise, callback, error_cb, data);
|
||||
if(v->then_count)
|
||||
{
|
||||
v->ref_count++;
|
||||
}
|
||||
v->then_count++;
|
||||
}
|
||||
static void* _ecore_promise_value_get(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
return v->eina_promise->value_get(v->eina_promise);
|
||||
}
|
||||
static Eina_Error _ecore_promise_error_get(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
return v->eina_promise->error_get(v->eina_promise);
|
||||
}
|
||||
static Eina_Bool _ecore_promise_pending_is(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
return v->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,
|
||||
Eina_Promise_Free_Cb free_cb)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
v->eina_promise->progress_cb_add(v->eina_promise, callback, data, free_cb);
|
||||
}
|
||||
static void _ecore_promise_cancel(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
v->eina_promise->cancel(v->eina_promise);
|
||||
}
|
||||
static void _ecore_promise_ref(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
++v->ref_count;
|
||||
}
|
||||
static void _ecore_promise_unref(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
--v->ref_count;
|
||||
}
|
||||
static void* _ecore_promise_buffer_get(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
return v->eina_promise->buffer_get(v->eina_promise);
|
||||
}
|
||||
static size_t _ecore_promise_value_size_get(Eina_Promise const* promise)
|
||||
{
|
||||
_Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
|
||||
return v->eina_promise->value_size_get(v->eina_promise);
|
||||
}
|
||||
|
||||
Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
|
||||
Ecore_Thread_Promise_Cb func_cancel,
|
||||
|
@ -120,18 +218,36 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
|
|||
priv->owner_vtable.pending_is = EINA_FUNC_PROMISE_OWNER_PENDING_IS(&_ecore_promise_owner_pending_is);
|
||||
priv->owner_vtable.cancelled_is = EINA_FUNC_PROMISE_OWNER_CANCELLED_IS(&_ecore_promise_owner_cancelled_is);
|
||||
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->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.error_get = EINA_FUNC_PROMISE_ERROR_GET(&_ecore_promise_error_get);
|
||||
priv->promise_vtable.pending_is = EINA_FUNC_PROMISE_PENDING_IS(&_ecore_promise_pending_is);
|
||||
priv->promise_vtable.progress_cb_add = EINA_FUNC_PROMISE_PROGRESS_CB_ADD(&_ecore_promise_progress_cb_add);
|
||||
priv->promise_vtable.cancel = EINA_FUNC_PROMISE_CANCEL(&_ecore_promise_cancel);
|
||||
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.value_size_get = EINA_FUNC_PROMISE_VALUE_SIZE_GET(&_ecore_promise_value_size_get);
|
||||
priv->promise_vtable.buffer_get = EINA_FUNC_PROMISE_BUFFER_GET(&_ecore_promise_buffer_get);
|
||||
|
||||
priv->thread_callback_data.data = data;
|
||||
priv->thread_callback_data.func_blocking = func_blocking;
|
||||
priv->thread_callback_data.func_cancel = func_cancel;
|
||||
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->ref(priv->eina_promise);
|
||||
priv->ref_count = 0;
|
||||
priv->then_count = 0;
|
||||
|
||||
if(func_cancel)
|
||||
eina_promise_owner_default_cancel_cb_add(priv->eina_owner, &_ecore_promise_cancel, priv, NULL);
|
||||
eina_promise_owner_default_cancel_cb_add(priv->eina_owner, &_ecore_promise_cancel_cb, priv, NULL);
|
||||
priv->thread_callback_data.thread =
|
||||
ecore_thread_feedback_run(&_ecore_promise_thread_blocking, &_ecore_promise_thread_notify,
|
||||
&_ecore_promise_thread_end, &_ecore_promise_thread_cancel, priv,
|
||||
EINA_FALSE);
|
||||
if(promise)
|
||||
*promise = priv->eina_owner->promise_get(priv->eina_owner);
|
||||
*promise = priv->eina_promise;
|
||||
return priv->thread_callback_data.thread;
|
||||
}
|
||||
|
|
|
@ -87,7 +87,6 @@ static int _eina_main_count = 0;
|
|||
static int _eina_main_thread_count = 0;
|
||||
#endif
|
||||
static int _eina_log_dom = -1;
|
||||
void _eina_promise_init(void);
|
||||
|
||||
#ifdef ERR
|
||||
#undef ERR
|
||||
|
@ -155,6 +154,7 @@ EAPI Eina_Inlist *_eina_tracking = NULL;
|
|||
S(cpu);
|
||||
S(thread_queue);
|
||||
S(rbtree);
|
||||
S(promise);
|
||||
/* no model for now
|
||||
S(model);
|
||||
*/
|
||||
|
@ -201,7 +201,8 @@ static const struct eina_desc_setup _eina_desc_setup[] = {
|
|||
S(cow),
|
||||
S(cpu),
|
||||
S(thread_queue),
|
||||
S(rbtree)
|
||||
S(rbtree),
|
||||
S(promise)
|
||||
/* no model for now
|
||||
S(model)
|
||||
*/
|
||||
|
@ -300,8 +301,6 @@ eina_init(void)
|
|||
}
|
||||
}
|
||||
|
||||
_eina_promise_init();
|
||||
|
||||
eina_cpu_count_internal();
|
||||
|
||||
eina_log_timing(_eina_log_dom, EINA_LOG_STATE_STOP, EINA_LOG_STATE_INIT);
|
||||
|
|
|
@ -4,8 +4,17 @@
|
|||
|
||||
#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__)
|
||||
|
||||
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;
|
||||
|
@ -29,6 +38,7 @@ struct _Eina_Promise_Progress_Cb
|
|||
EINA_INLIST;
|
||||
|
||||
Eina_Promise_Progress_Cb callback;
|
||||
Eina_Promise_Free_Cb free;
|
||||
void* data;
|
||||
};
|
||||
|
||||
|
@ -94,6 +104,22 @@ struct _Eina_Promise_Iterator
|
|||
} data;
|
||||
};
|
||||
|
||||
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_finish(_Eina_Promise_Default_Owner* promise);
|
||||
static void _eina_promise_ref(_Eina_Promise_Default* promise);
|
||||
static void _eina_promise_unref(_Eina_Promise_Default* promise);
|
||||
|
@ -119,14 +145,14 @@ static void
|
|||
_eina_promise_then_calls(_Eina_Promise_Default_Owner* promise)
|
||||
{
|
||||
_Eina_Promise_Then_Cb* callback;
|
||||
Eina_Inlist* list2;
|
||||
Eina_Bool error;
|
||||
|
||||
_eina_promise_ref(&promise->promise);
|
||||
error = promise->promise.has_errored;
|
||||
|
||||
EINA_INLIST_FOREACH_SAFE(promise->promise.then_callbacks, list2, callback)
|
||||
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)
|
||||
|
@ -136,6 +162,7 @@ _eina_promise_then_calls(_Eina_Promise_Default_Owner* promise)
|
|||
{
|
||||
(*callback->callback)(callback->data, &promise->value[0]);
|
||||
}
|
||||
free(callback);
|
||||
_eina_promise_unref(&promise->promise);
|
||||
}
|
||||
_eina_promise_unref(&promise->promise);
|
||||
|
@ -145,14 +172,15 @@ static void
|
|||
_eina_promise_cancel_calls(_Eina_Promise_Default_Owner* promise, Eina_Bool call_cancel EINA_UNUSED)
|
||||
{
|
||||
_Eina_Promise_Cancel_Cb* callback;
|
||||
Eina_Inlist* list2;
|
||||
|
||||
EINA_INLIST_FOREACH_SAFE(promise->promise.cancel_callbacks, list2, callback)
|
||||
EINA_INLIST_FREE(promise->promise.cancel_callbacks, callback)
|
||||
{
|
||||
if (callback->callback)
|
||||
{
|
||||
(*callback->callback)(callback->data, (Eina_Promise_Owner*)promise);
|
||||
}
|
||||
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)
|
||||
|
@ -164,15 +192,19 @@ _eina_promise_cancel_calls(_Eina_Promise_Default_Owner* promise, Eina_Bool call_
|
|||
static void
|
||||
_eina_promise_del(_Eina_Promise_Default_Owner* promise)
|
||||
{
|
||||
if (promise->promise.has_finished)
|
||||
if (!promise->promise.has_finished)
|
||||
{
|
||||
if (promise->promise.value_free_cb)
|
||||
promise->promise.value_free_cb((void*)&promise->value[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
_eina_promise_cancel_calls(promise, EINA_TRUE);
|
||||
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((void*)&promise->value[0]);
|
||||
|
||||
_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);
|
||||
free(promise);
|
||||
}
|
||||
|
||||
static void *
|
||||
|
@ -234,8 +266,9 @@ _eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback,
|
|||
if (!promise->promise.is_first_then)
|
||||
{
|
||||
_eina_promise_ref(p);
|
||||
promise->promise.is_first_then = EINA_FALSE;
|
||||
}
|
||||
else
|
||||
promise->promise.is_first_then = EINA_FALSE;
|
||||
if (promise->promise.has_finished)
|
||||
{
|
||||
_eina_promise_then_calls(promise);
|
||||
|
@ -259,6 +292,10 @@ _eina_promise_finish(_Eina_Promise_Default_Owner* promise)
|
|||
{
|
||||
_eina_promise_then_calls(promise);
|
||||
}
|
||||
if(promise->promise.ref == 0)
|
||||
{
|
||||
_eina_promise_del(promise);
|
||||
}
|
||||
}
|
||||
|
||||
static Eina_Error
|
||||
|
@ -293,7 +330,8 @@ _eina_promise_owner_cancelled_is(_Eina_Promise_Default_Owner const* promise)
|
|||
}
|
||||
|
||||
static void
|
||||
_eina_promise_progress_cb_add(_Eina_Promise_Default* promise, Eina_Promise_Progress_Cb callback, void* data)
|
||||
_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;
|
||||
|
@ -302,13 +340,15 @@ _eina_promise_progress_cb_add(_Eina_Promise_Default* promise, Eina_Promise_Progr
|
|||
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_vtable);
|
||||
}
|
||||
_eina_promise_free_callback_list(&owner->promise.progress_notify_callbacks, &free);
|
||||
_eina_promise_free_callback_list(&owner->promise.progress_notify_callbacks,
|
||||
&_eina_promise_free_progress_notify_callback_node);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -393,7 +433,8 @@ _eina_promise_owner_progress(_Eina_Promise_Default_Owner* promise, void* data)
|
|||
|
||||
EINA_INLIST_FOREACH_SAFE(promise->promise.progress_callbacks, list2, callback)
|
||||
{
|
||||
(*callback->callback)(callback->data, data);
|
||||
if(callback->callback)
|
||||
(*callback->callback)(callback->data, data);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -605,6 +646,7 @@ _eina_promise_progress_notify_fulfilled(void* data, Eina_Promise_Owner* p EINA_U
|
|||
}
|
||||
|
||||
EAPI Eina_Error EINA_ERROR_PROMISE_NO_NOTIFY;
|
||||
EAPI Eina_Error EINA_ERROR_PROMISE_CANCEL;
|
||||
|
||||
static void
|
||||
_eina_promise_progress_notify_failed(void* data)
|
||||
|
@ -666,9 +708,10 @@ eina_promise_pending_is(Eina_Promise const* promise)
|
|||
}
|
||||
|
||||
EAPI void
|
||||
eina_promise_progress_cb_add(Eina_Promise* promise, Eina_Promise_Progress_Cb callback, void* data)
|
||||
eina_promise_progress_cb_add(Eina_Promise* promise, Eina_Promise_Progress_Cb callback, void* data,
|
||||
Eina_Promise_Free_Cb free_cb)
|
||||
{
|
||||
promise->progress_cb_add(promise, callback, data);
|
||||
promise->progress_cb_add(promise, callback, data, free_cb);
|
||||
}
|
||||
|
||||
EAPI void
|
||||
|
@ -739,8 +782,27 @@ eina_promise_owner_progress_notify(Eina_Promise_Owner* promise, Eina_Promise_Pro
|
|||
}
|
||||
|
||||
static const char EINA_ERROR_PROMISE_NO_NOTIFY_STR[] = "Out of memory";
|
||||
static const char EINA_ERROR_PROMISE_CANCEL_STR[] = "Promise cancelled";
|
||||
|
||||
void _eina_promise_init()
|
||||
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_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;
|
||||
}
|
||||
|
|
|
@ -71,7 +71,8 @@ typedef Eina_Bool(*Eina_Promise_Pending_Is_Cb)(Eina_Promise const* promise);
|
|||
/*
|
||||
* @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* 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)
|
||||
|
||||
|
@ -338,7 +339,8 @@ EAPI Eina_Bool eina_promise_pending_is(Eina_Promise const* promise);
|
|||
* @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);
|
||||
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
|
||||
|
@ -483,6 +485,14 @@ EAPI void eina_promise_owner_default_call_then(Eina_Promise_Owner* promise);
|
|||
*/
|
||||
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;
|
||||
|
||||
/*
|
||||
* @internal
|
||||
*/
|
||||
|
|
|
@ -378,7 +378,7 @@ START_TEST(ecore_test_promise_progress_promise)
|
|||
|
||||
ecore_thread_promise_run(&promise_progress_thread, NULL, NULL, 0, &promise);
|
||||
|
||||
eina_promise_progress_cb_add(promise, &_progress_callback, NULL);
|
||||
eina_promise_progress_cb_add(promise, &_progress_callback, NULL, NULL);
|
||||
|
||||
ecore_main_loop_begin();
|
||||
|
||||
|
|
|
@ -226,7 +226,7 @@ START_TEST(eina_test_promise_progress)
|
|||
owner = eina_promise_default_add(0);
|
||||
|
||||
promise = eina_promise_owner_promise_get(owner);
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, &progress_ran);
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, &progress_ran, NULL);
|
||||
|
||||
eina_promise_owner_progress(owner, &i);
|
||||
|
||||
|
@ -254,8 +254,8 @@ START_TEST(eina_test_promise_progress_notify1)
|
|||
eina_promise_owner_progress_notify(owner, &progress_notify, &progress_notify_ran, NULL);
|
||||
|
||||
promise = eina_promise_owner_promise_get(owner);
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL); // never run
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL); // never run
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL, NULL); // never run
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL, NULL); // never run
|
||||
|
||||
ck_assert(progress_notify_ran);
|
||||
|
||||
|
@ -311,8 +311,8 @@ START_TEST(eina_test_promise_progress_notify3)
|
|||
&_eina_promise_progress_notify_error, &progress_notify_ran);
|
||||
|
||||
promise = eina_promise_owner_promise_get(owner);
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL); // never run
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL); // never run
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL, NULL); // never run
|
||||
eina_promise_progress_cb_add(promise, &progress_callback, NULL, NULL); // never run
|
||||
|
||||
ck_assert(progress_notify_ran);
|
||||
|
||||
|
@ -320,6 +320,22 @@ START_TEST(eina_test_promise_progress_notify3)
|
|||
}
|
||||
END_TEST
|
||||
|
||||
START_TEST(eina_test_promise_ignored)
|
||||
{
|
||||
Eina_Promise_Owner* owner;
|
||||
Eina_Promise* promise;
|
||||
|
||||
eina_init();
|
||||
|
||||
owner = eina_promise_default_add(0);
|
||||
promise = eina_promise_owner_promise_get(owner);
|
||||
eina_promise_unref(promise);
|
||||
eina_promise_owner_value_set(owner, NULL, NULL);
|
||||
|
||||
eina_shutdown();
|
||||
}
|
||||
END_TEST
|
||||
|
||||
void
|
||||
eina_test_promise(TCase *tc)
|
||||
{
|
||||
|
@ -333,4 +349,5 @@ eina_test_promise(TCase *tc)
|
|||
tcase_add_test(tc, eina_test_promise_progress_notify1);
|
||||
tcase_add_test(tc, eina_test_promise_progress_notify2);
|
||||
tcase_add_test(tc, eina_test_promise_progress_notify3);
|
||||
tcase_add_test(tc, eina_test_promise_ignored);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue