eina: Remove value type promises

All values in promises are now considered as by-pointer.
This commit is contained in:
Lauro Moura 2016-06-08 19:33:29 -03:00 committed by Felipe Magno de Almeida
parent 5a3331618e
commit 46843551c0
14 changed files with 400 additions and 957 deletions

View File

@ -67,7 +67,7 @@ eina_bench_promise_sync_then(int request)
eina_init();
Eina_Promise_Owner* owner = eina_promise_value_add(sizeof(struct value_type));
Eina_Promise_Owner* owner = eina_promise_add();
Eina_Promise* promise = eina_promise_owner_promise_get(owner);
eina_promise_ref(promise);
@ -87,116 +87,6 @@ eina_bench_promise_sync_then(int request)
eina_shutdown();
}
static void
eina_bench_promise_copy_value_set_after_then(int request)
{
const char *tmp;
unsigned int j;
int i;
eina_init();
struct value_type const v = {0, 0, 0, 0};
for (j = 0; j != 200; ++j)
for (i = 0; i != request; ++i)
{
Eina_Promise_Owner* owner = eina_promise_value_add(sizeof(struct value_type));
Eina_Promise* promise = eina_promise_owner_promise_get(owner);
eina_promise_then(promise, &cb, NULL, NULL);
eina_promise_owner_value_set(owner, &v, NULL);
}
/* Suppress warnings as we really don't want to do anything. */
(void) tmp;
eina_shutdown();
}
static void
eina_bench_promise_no_copy_value_set_after_then(int request)
{
const char *tmp;
unsigned int j;
int i;
eina_init();
for (j = 0; j != 200; ++j)
for (i = 0; i != request; ++i)
{
Eina_Promise_Owner* owner = eina_promise_value_add(sizeof(struct value_type));
Eina_Promise* promise = eina_promise_owner_promise_get(owner);
struct value_type* v = eina_promise_owner_buffer_get(owner);
eina_promise_then(promise, &cb, NULL, NULL);
v->x = v->y = v-> w = v->h = 0;
eina_promise_owner_value_set(owner, NULL, NULL);
}
/* Suppress warnings as we really don't want to do anything. */
(void) tmp;
eina_shutdown();
}
static void
eina_bench_promise_no_copy_value_set_before_then(int request)
{
const char *tmp;
unsigned int j;
int i;
eina_init();
for (j = 0; j != 200; ++j)
for (i = 0; i != request; ++i)
{
Eina_Promise_Owner* owner = eina_promise_value_add(sizeof(struct value_type));
Eina_Promise* promise = eina_promise_owner_promise_get(owner);
struct value_type* v = eina_promise_owner_buffer_get(owner);
v->x = v->y = v-> w = v->h = 0;
eina_promise_owner_value_set(owner, NULL, NULL);
eina_promise_then(promise, &cb, NULL, NULL);
}
/* Suppress warnings as we really don't want to do anything. */
(void) tmp;
eina_shutdown();
}
static void
eina_bench_promise_copy_value_set_before_then(int request)
{
const char *tmp;
unsigned int j;
int i;
eina_init();
struct value_type const v = {0, 0, 0, 0};
for (j = 0; j != 200; ++j)
for (i = 0; i != request; ++i)
{
Eina_Promise_Owner* owner = eina_promise_value_add(sizeof(struct value_type));
Eina_Promise* promise = eina_promise_owner_promise_get(owner);
eina_promise_then(promise, &cb, NULL, NULL);
eina_promise_owner_value_set(owner, &v, NULL);
}
/* Suppress warnings as we really don't want to do anything. */
(void) tmp;
eina_shutdown();
}
static void indirect_free(void* p)
{
free(p);
@ -398,18 +288,6 @@ void eina_bench_promise(Eina_Benchmark *bench)
eina_benchmark_register(bench, "promise synchronous then",
EINA_BENCHMARK(
eina_bench_promise_sync_then), 100, 20100, 500);
eina_benchmark_register(bench, "promise copy value set after then",
EINA_BENCHMARK(
eina_bench_promise_copy_value_set_after_then), 100, 20100, 500);
eina_benchmark_register(bench, "promise copy value set before then",
EINA_BENCHMARK(
eina_bench_promise_copy_value_set_before_then), 100, 20100, 500);
eina_benchmark_register(bench, "promise no copy value set after then",
EINA_BENCHMARK(
eina_bench_promise_no_copy_value_set_after_then), 100, 20100, 500);
eina_benchmark_register(bench, "promise no copy value set before then",
EINA_BENCHMARK(
eina_bench_promise_no_copy_value_set_before_then), 100, 20100, 500);
eina_benchmark_register(bench, "promise pointer value set after then mempool",
EINA_BENCHMARK(
eina_bench_promise_pointer_value_set_after_then_pooled), 100, 20100, 500);

View File

@ -108,14 +108,6 @@ static void _ecore_promise_thread_cancel(void* data, Ecore_Thread* thread EINA_U
eina_promise_cancel(promise);
}
static void* _ecore_promise_owner_buffer_get(_Ecore_Thread_Promise_Owner* promise)
{
return promise->eina_owner->buffer_get(promise->eina_owner);
}
static size_t _ecore_promise_owner_value_size_get(_Ecore_Thread_Promise_Owner const* promise)
{
return promise->eina_owner->value_size_get(promise->eina_owner);
}
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);
@ -191,16 +183,6 @@ 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,
@ -216,8 +198,6 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
priv->owner_vtable.version = EINA_PROMISE_VERSION;
priv->owner_vtable.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(&_ecore_promise_owner_value_set);
priv->owner_vtable.error_set = EINA_FUNC_PROMISE_OWNER_ERROR_SET(&_ecore_promise_owner_error_set);
priv->owner_vtable.buffer_get = EINA_FUNC_PROMISE_OWNER_BUFFER_GET(&_ecore_promise_owner_buffer_get);
priv->owner_vtable.value_size_get = EINA_FUNC_PROMISE_OWNER_VALUE_SIZE_GET(&_ecore_promise_owner_value_size_get);
priv->owner_vtable.promise_get = EINA_FUNC_PROMISE_OWNER_PROMISE_GET(&_ecore_thread_promise_owner_promise_get);
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);
@ -233,8 +213,6 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
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);
EINA_MAGIC_SET(&priv->promise_vtable, EINA_MAGIC_PROMISE);
priv->thread_callback_data.data = data;

View File

@ -93,7 +93,6 @@ struct _Eina_Promise_Default
Eina_Bool is_cancelled : 1;
Eina_Bool is_manual_then : 1;
Eina_Bool is_first_then : 1;
Eina_Bool is_pointer : 1;
};
struct _Eina_Promise_Default_Owner
@ -101,7 +100,7 @@ struct _Eina_Promise_Default_Owner
Eina_Promise_Owner owner_vtable;
_Eina_Promise_Default promise;
char value[];
void* pointer_value;
};
#define EINA_PROMISE_GET_OWNER(p) (_Eina_Promise_Default_Owner*)((unsigned char*)p - offsetof(struct _Eina_Promise_Default_Owner, promise))
@ -118,16 +117,15 @@ struct _Eina_Promise_Iterator
} data;
};
typedef struct _Eina_Promise_Race_Value_Type _Eina_Promise_Race_Value_Type;
struct _Eina_Promise_Race_Value_Type
typedef struct _Eina_Promise_Race _Eina_Promise_Race;
struct _Eina_Promise_Race
{
void* value;
unsigned int promise_index;
_Eina_Promise_Default_Owner promise_default;
unsigned int num_promises;
struct _Eina_Promise_Race_Information
{
Eina_Promise* promise;
_Eina_Promise_Default_Owner* self;
_Eina_Promise_Race* self;
} promises[];
};
@ -195,14 +193,7 @@ _eina_promise_then_calls(_Eina_Promise_Default_Owner* promise)
}
else if (callback->callback)
{
if(promise->promise.is_pointer)
{
char* buffer = promise->value;
void** p = (void**)buffer;
(*callback->callback)(callback->data, *p);
}
else
(*callback->callback)(callback->data, &promise->value[0]);
(*callback->callback)(callback->data, promise->pointer_value);
}
free(callback);
_eina_promise_unref(&promise->promise);
@ -243,14 +234,7 @@ _eina_promise_del(_Eina_Promise_Default_Owner* promise)
if (promise->promise.value_free_cb)
{
if(promise->promise.is_pointer)
{
char* buffer = promise->value;
void** p = (void**)buffer;
promise->promise.value_free_cb(*p);
}
else
promise->promise.value_free_cb((void*)&promise->value[0]);
promise->promise.value_free_cb(promise->pointer_value);
}
_eina_promise_free_callback_list(&promise->promise.progress_callbacks,
@ -262,49 +246,13 @@ _eina_promise_del(_Eina_Promise_Default_Owner* promise)
free(promise);
}
static void *
_eina_promise_owner_buffer_get(_Eina_Promise_Default_Owner* promise)
{
return &promise->value[0];
}
static void *
_eina_promise_owner_pointer_buffer_get(_Eina_Promise_Default_Owner* promise)
{
char* buffer = promise->value;
void** p = (void**)buffer;
return *p;
}
static void *
_eina_promise_buffer_get(_Eina_Promise_Default const* promise)
{
_Eina_Promise_Default_Owner const* p = EINA_PROMISE_GET_OWNER(promise);
return (void*)&p->value[0];
}
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 (void*)&promise->value[0];
}
else
{
return NULL;
}
}
static void *
_eina_promise_pointer_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)
{
char const* buffer = promise->value;
return *((void**)buffer);
return promise->pointer_value;
}
else
{
@ -315,22 +263,7 @@ _eina_promise_pointer_value_get(_Eina_Promise_Default const* p)
static void
_eina_promise_owner_value_set(_Eina_Promise_Default_Owner* promise, const void* data, Eina_Promise_Free_Cb free)
{
if (data && promise->promise.value_size)
{
memcpy(&promise->value[0], data, promise->promise.value_size);
}
promise->promise.value_free_cb = free;
_eina_promise_finish(promise);
}
static void
_eina_promise_owner_pointer_value_set(_Eina_Promise_Default_Owner* promise, const void* data, Eina_Promise_Free_Cb free)
{
char* buffer = promise->value;
void** p = (void**)buffer;
*p = (void*)data;
promise->pointer_value = (void*)data;
promise->promise.value_free_cb = free;
_eina_promise_finish(promise);
}
@ -457,18 +390,6 @@ _eina_promise_cancel(_Eina_Promise_Default* promise)
}
}
static size_t
_eina_promise_value_size_get(_Eina_Promise_Default_Owner const* promise)
{
return promise->promise.value_size;
}
static size_t
_eina_promise_owner_value_size_get(_Eina_Promise_Default_Owner const* promise)
{
return promise->promise.value_size;
}
static void
_eina_promise_ref(_Eina_Promise_Default* p)
{
@ -478,14 +399,16 @@ _eina_promise_ref(_Eina_Promise_Default* p)
static void
_eina_promise_unref(_Eina_Promise_Default* p)
{
if (p->ref <= 1 && p->has_finished && p->can_be_deleted)
if (--p->ref <= 0 && p->has_finished && p->can_be_deleted)
{
_eina_promise_del(EINA_PROMISE_GET_OWNER(p));
}
else
{
--p->ref;
}
}
static int
_eina_promise_ref_get(_Eina_Promise_Default* p)
{
return p->ref;
}
static Eina_Promise *
@ -544,12 +467,8 @@ _eina_promise_owner_progress_notify(_Eina_Promise_Default_Owner* promise, Eina_P
eina_inlist_append(promise->promise.progress_notify_callbacks, EINA_INLIST_GET(cb));
}
Eina_Promise_Owner *
eina_promise_value_add(int value_size)
static void eina_promise_add_internal(_Eina_Promise_Default_Owner* p)
{
_Eina_Promise_Default_Owner* p;
p = malloc(sizeof(_Eina_Promise_Default_Owner) + value_size);
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);
@ -559,82 +478,29 @@ eina_promise_value_add(int value_size)
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.value_size_get = EINA_FUNC_PROMISE_VALUE_SIZE_GET(_eina_promise_value_size_get);
p->promise.vtable.buffer_get = EINA_FUNC_PROMISE_BUFFER_GET(_eina_promise_buffer_get);
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.has_finished = p->promise.has_errored =
p->promise.is_cancelled = p->promise.is_manual_then = p->promise.is_pointer = EINA_FALSE;
p->promise.can_be_deleted = EINA_FALSE;
p->promise.is_first_then = EINA_TRUE;
p->promise.ref = 1;
memset(&p->promise.then_callbacks, 0, sizeof(p->promise.then_callbacks));
memset(&p->promise.progress_callbacks, 0, sizeof(p->promise.progress_callbacks));
memset(&p->promise.progress_notify_callbacks, 0, sizeof(p->promise.progress_notify_callbacks));
memset(&p->promise.cancel_callbacks, 0, sizeof(p->promise.cancel_callbacks));
p->promise.value_size = value_size;
p->promise.value_free_cb = NULL;
p->promise.error = 0;
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.buffer_get = EINA_FUNC_PROMISE_OWNER_BUFFER_GET(_eina_promise_owner_buffer_get);
p->owner_vtable.value_size_get = EINA_FUNC_PROMISE_OWNER_VALUE_SIZE_GET(_eina_promise_owner_value_size_get);
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);
return &p->owner_vtable;
}
EAPI Eina_Promise_Owner *
eina_promise_add()
{
_Eina_Promise_Default_Owner* p;
p = malloc(sizeof(_Eina_Promise_Default_Owner) + sizeof(void*));
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_pointer_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.value_size_get = EINA_FUNC_PROMISE_VALUE_SIZE_GET(_eina_promise_value_size_get);
p->promise.vtable.buffer_get = EINA_FUNC_PROMISE_BUFFER_GET(_eina_promise_buffer_get);
EINA_MAGIC_SET(&p->promise.vtable, EINA_MAGIC_PROMISE);
p->promise.has_finished = p->promise.has_errored =
p->promise.is_cancelled = p->promise.is_manual_then = EINA_FALSE;
p->promise.is_first_then = p->promise.is_pointer = EINA_TRUE;
p->promise.can_be_deleted = EINA_FALSE;
p->promise.ref = 1;
memset(&p->promise.then_callbacks, 0, sizeof(p->promise.then_callbacks));
memset(&p->promise.progress_callbacks, 0, sizeof(p->promise.progress_callbacks));
memset(&p->promise.progress_notify_callbacks, 0, sizeof(p->promise.progress_notify_callbacks));
memset(&p->promise.cancel_callbacks, 0, sizeof(p->promise.cancel_callbacks));
p->promise.value_size = 0;
p->promise.value_free_cb = NULL;
p->promise.error = 0;
p->owner_vtable.version = EINA_PROMISE_VERSION;
p->owner_vtable.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(_eina_promise_owner_pointer_value_set);
p->owner_vtable.error_set = EINA_FUNC_PROMISE_OWNER_ERROR_SET(_eina_promise_owner_error_set);
p->owner_vtable.buffer_get = EINA_FUNC_PROMISE_OWNER_BUFFER_GET(_eina_promise_owner_pointer_buffer_get);
p->owner_vtable.value_size_get = EINA_FUNC_PROMISE_OWNER_VALUE_SIZE_GET(_eina_promise_owner_value_size_get);
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 = calloc(sizeof(_Eina_Promise_Default_Owner), 1);
eina_promise_add_internal(p);
return &p->owner_vtable;
}
@ -663,12 +529,13 @@ _eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED)
if (!promise->promise.has_finished)
{
iterator = (_Eina_Promise_Iterator*)promise->value;
if (++iterator->data.promises_finished == iterator->data.num_promises)
iterator = promise->pointer_value;
if (++(iterator->data.promises_finished) == iterator->data.num_promises)
{
_eina_promise_finish(promise);
}
}
eina_promise_unref(&promise->promise.vtable);
}
static void
@ -676,12 +543,14 @@ _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.vtable);
}
static void
@ -693,6 +562,8 @@ _eina_promise_all_free(_Eina_Promise_Iterator* value)
{
eina_promise_unref(value->data.promises[i]);
}
free(value);
}
Eina_Promise *
@ -715,19 +586,23 @@ eina_promise_all(Eina_Iterator* it)
eina_iterator_free(it);
promise = (_Eina_Promise_Default_Owner*)
eina_promise_value_add(sizeof(_Eina_Promise_Iterator) +
sizeof(_Eina_Promise_Default_Owner*)*eina_array_count_get(promises));
internal_it = (_Eina_Promise_Iterator*)&promise->value[0];
_eina_promise_iterator_setup(internal_it, promises);
promise = (_Eina_Promise_Default_Owner*)eina_promise_add();
internal_it = 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;
promise->pointer_value = (void*)internal_it;
_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.vtable);
eina_promise_then(*cur_promise, &_eina_promise_all_compose_then_cb,
&_eina_promise_all_compose_error_then_cb, promise);
}
@ -813,7 +688,7 @@ eina_promise_progress_notification(Eina_Promise_Owner* promise)
{
Eina_Promise_Owner* owner;
owner = eina_promise_value_add(0);
owner = eina_promise_add();
eina_promise_owner_progress_notify(promise, &_eina_promise_progress_notify_fulfilled, owner,
&_eina_promise_progress_notify_finish);
@ -822,13 +697,17 @@ eina_promise_progress_notification(Eina_Promise_Owner* promise)
}
// Race implementation
static void
_eina_promise_race_free(_Eina_Promise_Race_Value_Type* value)
static void _eina_promise_race_unref(_Eina_Promise_Race* p)
{
unsigned i = 0;
for (;i != value->num_promises; ++i)
unsigned i;
if (--p->promise_default.promise.ref <= 0 && p->promise_default.promise.has_finished
&& p->promise_default.promise.can_be_deleted)
{
eina_promise_unref(value->promises[i].promise);
for(i = 0; i != p->num_promises; ++i)
{
eina_promise_unref(p->promises[i].promise);
}
_eina_promise_del(EINA_PROMISE_GET_OWNER(&p->promise_default));
}
}
@ -836,45 +715,31 @@ static void
_eina_promise_race_compose_then_cb(void *data, void* value EINA_UNUSED)
{
struct _Eina_Promise_Race_Information* info = data;
_Eina_Promise_Default_Owner* race_promise;
_Eina_Promise_Race_Value_Type *race_value;
_Eina_Promise_Race* race_promise = info->self;
race_promise = info->self;
race_value = (_Eina_Promise_Race_Value_Type*)race_promise->value;
if (!race_promise->promise.has_finished)
{
race_value->value = value;
race_value->promise_index = info - &race_value->promises[0];
_eina_promise_finish(race_promise);
}
if (!race_promise->promise_default.promise.has_finished)
eina_promise_owner_value_set(&race_promise->promise_default.owner_vtable, value, NULL);
eina_promise_unref(&race_promise->promise_default.promise.vtable);
}
static void
_eina_promise_race_compose_error_then_cb(void *data, Eina_Error error)
{
struct _Eina_Promise_Race_Information* info = data;
_Eina_Promise_Default_Owner* race_promise;
_Eina_Promise_Race_Value_Type *race_value;
_Eina_Promise_Race* race_promise = info->self;
race_promise = info->self;
race_value = (_Eina_Promise_Race_Value_Type*)race_promise->value;
if (!race_promise->promise.has_finished)
{
race_value->promise_index = info - &race_value->promises[0];
eina_promise_owner_error_set(&race_promise->owner_vtable, error);
}
if (!race_promise->promise_default.promise.has_finished)
eina_promise_owner_error_set(&race_promise->promise_default.owner_vtable, error);
eina_promise_unref(&race_promise->promise_default.promise.vtable);
}
Eina_Promise *
eina_promise_race(Eina_Iterator* it)
{
_Eina_Promise_Default_Owner *promise;
_Eina_Promise_Race *promise;
Eina_Promise* current;
Eina_Array* promises;
struct _Eina_Promise_Race_Information *cur_promise, *last;
_Eina_Promise_Race_Value_Type *value;
int num_promises;
EINA_SAFETY_ON_NULL_RETURN_VAL(it, NULL);
@ -889,30 +754,27 @@ eina_promise_race(Eina_Iterator* it)
eina_iterator_free(it);
num_promises = eina_array_count_get(promises);
promise = (_Eina_Promise_Default_Owner*)
eina_promise_value_add(sizeof(_Eina_Promise_Race_Value_Type) +
sizeof(struct _Eina_Promise_Race_Information)*num_promises);
value = eina_promise_owner_buffer_get((Eina_Promise_Owner*)promise);
value->value = NULL;
value->promise_index = -1;
value->num_promises = num_promises;
promise = calloc(sizeof(_Eina_Promise_Race) + sizeof(struct _Eina_Promise_Race_Information)*num_promises, 1);
eina_promise_add_internal(&promise->promise_default);
promise->promise.value_free_cb = (Eina_Promise_Free_Cb)&_eina_promise_race_free;
promise->num_promises = num_promises;
promise->promise_default.promise.vtable.unref = EINA_FUNC_PROMISE_UNREF(_eina_promise_race_unref);
cur_promise = value->promises;
last = value->promises + value->num_promises;
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.vtable);
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.vtable;
return &promise->promise_default.promise.vtable;
}
// API functions
@ -1008,28 +870,12 @@ eina_promise_unref(Eina_Promise* promise)
promise->unref(promise);
}
EAPI void *
eina_promise_owner_buffer_get(Eina_Promise_Owner* promise)
{
_EINA_PROMISE_NULL_CHECK(promise, NULL);
EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
return promise->buffer_get(promise);
}
EAPI void *
eina_promise_buffer_get(Eina_Promise* promise)
{
_EINA_PROMISE_NULL_CHECK(promise, NULL);
EINA_MAGIC_CHECK_PROMISE(promise);
return promise->buffer_get(promise);
}
EAPI size_t
eina_promise_value_size_get(Eina_Promise const* promise)
EAPI int
eina_promise_ref_get(Eina_Promise* promise)
{
_EINA_PROMISE_NULL_CHECK(promise, 0);
EINA_MAGIC_CHECK_PROMISE(promise);
return promise->value_size_get(promise);
return promise->ref_get(promise);
}
EAPI Eina_Promise *

View File

@ -99,6 +99,13 @@ typedef void(*Eina_Promise_Unref_Cb)(Eina_Promise* 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* 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
*/
@ -106,14 +113,6 @@ typedef void*(*Eina_Promise_Buffer_Get_Cb)(Eina_Promise* promise);
#define EINA_FUNC_PROMISE_BUFFER_GET(Function) ((Eina_Promise_Buffer_Get_Cb)Function)
/*
* @brief Function callback type for promise's value_size_get function override
*/
typedef size_t(*Eina_Promise_Value_Size_Get_Cb)(Eina_Promise const* promise);
#define EINA_FUNC_PROMISE_VALUE_SIZE_GET(Function) ((Eina_Promise_Value_Size_Get_Cb)Function)
/*
* @brief Function callback type for promise owner's buffer_get function override
*/
@ -121,13 +120,6 @@ typedef void*(*Eina_Promise_Owner_Buffer_Get_Cb)(Eina_Promise_Owner* promise);
#define EINA_FUNC_PROMISE_OWNER_BUFFER_GET(Function) ((Eina_Promise_Owner_Buffer_Get_Cb)Function)
/*
* @brief Function callback type for promise owner's value_size_get function override
*/
typedef size_t(*Eina_Promise_Owner_Value_Size_Get_Cb)(Eina_Promise_Owner const* promise);
#define EINA_FUNC_PROMISE_OWNER_VALUE_SIZE_GET(Function) ((Eina_Promise_Owner_Value_Size_Get_Cb)Function)
/*
* @brief Function callback type for promise owner's promise_get function override
*/
@ -192,8 +184,7 @@ struct _Eina_Promise
Eina_Promise_Cancel_Cb cancel;
Eina_Promise_Ref_Cb ref;
Eina_Promise_Unref_Cb unref;
Eina_Promise_Value_Size_Get_Cb value_size_get;
Eina_Promise_Buffer_Get_Cb buffer_get;
Eina_Promise_Ref_Get_Cb ref_get;
#define EINA_MAGIC_PROMISE 0x07932A5B
EINA_MAGIC;
};
@ -203,8 +194,6 @@ struct _Eina_Promise_Owner
int version;
Eina_Promise_Owner_Value_Set_Cb value_set;
Eina_Promise_Owner_Error_Set_Cb error_set;
Eina_Promise_Owner_Buffer_Get_Cb buffer_get;
Eina_Promise_Owner_Value_Size_Get_Cb value_size_get;
Eina_Promise_Owner_Promise_Get_Cb promise_get;
Eina_Promise_Owner_Pending_Is_Cb pending_is;
Eina_Promise_Owner_Cancelled_Is_Cb cancelled_is;
@ -282,33 +271,6 @@ EAPI void eina_promise_owner_value_set(Eina_Promise_Owner* promise, const void*
*/
EAPI void* eina_promise_value_get(Eina_Promise const* promise);
/*
* @brief Returns the pointer to the buffer that holds the value.
*
* If the promise is finished and has not failed, this function is the
* same as @eina_promise_value_get. Otherwise, instead of returning
* NULL as @eina_promise_value_get, this function always returns the
* buffer pointer to where the value will be hold.
*
* @param promise The promise for which to get the buffer pointer
* @return Buffer pointer
*/
EAPI void* eina_promise_buffer_get(Eina_Promise* promise);
/*
* @brief Returns the pointer to the buffer that holds the value.
*
* This function always return the buffer pointer independently if the
* value has been set or not. This is useful to instantiate the value
* directly in the correct buffer, without needing to copy. Then the
* user can @eina_promise_owner_value_set with a NULL pointer for the
* value to avoid copying over the buffer.
*
* @param promise The promise owner for which to get the buffer pointer
* @return Buffer pointer
*/
EAPI void* eina_promise_owner_buffer_get(Eina_Promise_Owner* promise);
/*
* @brief Sets an error to the Eina_Promise
*
@ -331,14 +293,6 @@ EAPI void eina_promise_owner_error_set(Eina_Promise_Owner* promise, Eina_Error e
*/
EAPI Eina_Error eina_promise_error_get(Eina_Promise const* promise);
/*
* @brief Gets the size of the value in eina_promise_value_get.
*
* @param promise The promise for which to get the value size
* @return The size of the value in eina_promise_value_get.
*/
EAPI size_t eina_promise_value_size_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.
@ -445,31 +399,18 @@ EAPI void eina_promise_owner_progress_notify(Eina_Promise_Owner* promise,
*/
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 with a value of size value_size. Which
* is a promise with ownership of the value to be set. It is used by
* the asynchronous operation to set the actual value when it becomes
* available. 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.
*
* @param value_size Size of value-type that Eina_Promise will hold
* @return @Eina_Promise_Owner just instantiated
*/
EAPI Eina_Promise_Owner* eina_promise_value_add(int value_size);
/*
* @brief Creates a @Eina_Promise_Owner
*

View File

@ -168,6 +168,8 @@ _free_xattr_data(Eio_Xattr_Data *value)
EINA_SAFETY_ON_NULL_RETURN(value);
if (value->data)
free((void*)value->data);
free(value);
}
static void
@ -179,13 +181,12 @@ _file_done_data_cb(void *data, Eio_File *handler EINA_UNUSED, const char *attr_d
EINA_SAFETY_ON_NULL_RETURN(operation);
EINA_SAFETY_ON_NULL_RETURN(operation->promise);
ret_data = eina_promise_owner_buffer_get(operation->promise);
ret_data = calloc(sizeof(Eio_Xattr_Data), 1);
ret_data->data = calloc(sizeof(char), size + 1);
strcpy((char*)ret_data->data, attr_data);
ret_data->size = size;
eina_promise_owner_value_set(operation->promise, NULL, (Eina_Promise_Free_Cb)&_free_xattr_data);
eina_promise_owner_value_set(operation->promise, ret_data, (Eina_Promise_Free_Cb)&_free_xattr_data);
_job_closure_del(operation);
}
@ -318,7 +319,7 @@ _eio_job_file_direct_ls(Eo *obj,
Eio_Job_Data *pd,
const char *path)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(int));
Eina_Promise_Owner* promise = eina_promise_add();
_job_direct_ls_helper(&eio_file_direct_ls, obj, pd, path, promise);
return eina_promise_owner_promise_get(promise);
}
@ -328,7 +329,7 @@ _eio_job_file_stat_ls(Eo *obj,
Eio_Job_Data *pd,
const char *path)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(int));
Eina_Promise_Owner* promise = eina_promise_add();
_job_direct_ls_helper(&eio_file_stat_ls, obj, pd, path, promise);
return eina_promise_owner_promise_get(promise);
}
@ -338,7 +339,7 @@ _eio_job_dir_stat_ls(Eo *obj,
Eio_Job_Data *pd,
const char *path)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(int));
Eina_Promise_Owner* promise = eina_promise_add();
_job_direct_ls_helper(&eio_dir_stat_ls, obj, pd, path, promise);
return eina_promise_owner_promise_get(promise);
}
@ -348,7 +349,7 @@ _eio_job_dir_direct_ls(Eo *obj,
Eio_Job_Data *pd,
const char *path)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(int));
Eina_Promise_Owner* promise = eina_promise_add();
// Had to add the cast as dir_direct differs in the filter callback constness of one of
// its arguments.
_job_direct_ls_helper((Eio_Job_Direct_Ls_Func)&eio_dir_direct_ls, obj, pd, path, promise);
@ -360,7 +361,7 @@ _eio_job_file_ls(Eo *obj,
Eio_Job_Data *pd,
const char *path)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(int));
Eina_Promise_Owner* promise = eina_promise_add();
Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
Eina_Promise* p = eina_promise_owner_promise_get(promise);
@ -391,9 +392,10 @@ _file_stat_done_cb(void *data, Eio_File *handle EINA_UNUSED, const Eina_Stat *st
EINA_SAFETY_ON_NULL_RETURN(operation);
EINA_SAFETY_ON_NULL_RETURN(operation->promise);
Eina_Stat *my_stat = calloc(sizeof(Eina_Stat), 1);
// Placeholder value. We just want the callback to be called.
eina_promise_owner_value_set(operation->promise, stat, NULL);
*my_stat = *stat;
eina_promise_owner_value_set(operation->promise, my_stat, free);
_job_closure_del(operation);
}
@ -403,7 +405,7 @@ _eio_job_file_direct_stat(Eo *obj,
Eio_Job_Data *pd,
const char *path)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(Eina_Stat));
Eina_Promise_Owner* promise = eina_promise_add();
Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
Eina_Promise* p = eina_promise_owner_promise_get(promise);
@ -430,7 +432,7 @@ _eio_job_file_xattr_list_get(Eo *obj,
Eio_Job_Data *pd,
const char *path)
{
Eina_Promise_Owner *promise = eina_promise_value_add(sizeof(int));
Eina_Promise_Owner *promise = eina_promise_add();
Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
Eina_Promise* p = eina_promise_owner_promise_get(promise);
@ -461,7 +463,7 @@ _eio_job_file_xattr_set(Eo *obj,
unsigned int xattr_size,
Eina_Xattr_Flags flags)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(int));
Eina_Promise_Owner* promise = eina_promise_add();
Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
Eina_Promise* p = eina_promise_owner_promise_get(promise);
@ -492,7 +494,7 @@ _eio_job_file_xattr_get(Eo *obj,
const char *path,
const char *attribute)
{
Eina_Promise_Owner* promise = eina_promise_value_add(sizeof(Eio_Xattr_Data));
Eina_Promise_Owner* promise = eina_promise_add();
Job_Closure *operation_data = _job_closure_create(obj, pd, promise);
Eina_Promise* p = eina_promise_owner_promise_get(promise);

View File

@ -41,7 +41,7 @@ _eio_stat_done_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *st
Eina_List *l;
EINA_LIST_FOREACH(priv->property_promises, l, p)
{
Eina_Value* v = eina_promise_owner_buffer_get(p->promise);
Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_CHAR);
switch(p->property)
{
case EIO_MODEL_PROP_IS_DIR:
@ -64,7 +64,7 @@ _eio_stat_done_cb(void *data, Eio_File *handler EINA_UNUSED, const Eina_Stat *st
break;
};
eina_promise_owner_value_set(p->promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
eina_promise_owner_value_set(p->promise, v, (Eina_Promise_Free_Cb)&eina_value_free);
free(p);
}
eina_list_free(priv->property_promises);
@ -308,10 +308,9 @@ _eio_model_efl_model_property_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, con
case EIO_MODEL_PROP_PATH:
case EIO_MODEL_PROP_MIME_TYPE:
{
Eina_Value* v = eina_promise_owner_buffer_get(promise);
eina_value_setup(v, EINA_VALUE_TYPE_STRING);
Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_STRING);
eina_value_set(v, value);
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
eina_promise_owner_value_set(promise, v, (Eina_Promise_Free_Cb)&eina_value_free);
}
break;
default:
@ -382,8 +381,9 @@ _eio_model_efl_model_property_set(Eo *obj EINA_UNUSED,
static void
_eio_model_efl_model_children_count_get(Eo *obj EINA_UNUSED, Eio_Model_Data *priv, Eina_Promise_Owner *promise)
{
unsigned int c = eina_list_count(priv->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
unsigned int *c = calloc(sizeof(unsigned int), 1);
*c = eina_list_count(priv->children_list);
eina_promise_owner_value_set(promise, c, free);
}
static void

View File

@ -121,6 +121,7 @@ _eldbus_model_arguments_efl_model_property_set(Eo *obj EINA_UNUSED,
Eina_Promise_Owner *promise)
{
Eina_Value *prop_value;
Eina_Value *promise_value;
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(value, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
@ -136,8 +137,10 @@ _eldbus_model_arguments_efl_model_property_set(Eo *obj EINA_UNUSED,
eina_value_flush(prop_value);
eina_value_copy(value, prop_value);
eina_value_copy(value, eina_promise_owner_buffer_get(promise));
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
promise_value = eina_value_new(eina_value_type_get(value));
eina_value_copy(value, promise_value);
eina_promise_owner_value_set(promise, promise_value, (Eina_Promise_Free_Cb)&eina_value_free);
}
static void
@ -146,6 +149,7 @@ _eldbus_model_arguments_efl_model_property_get(Eo *obj EINA_UNUSED,
const char *property,
Eina_Promise_Owner *promise)
{
Eina_Value *promise_value;
EINA_SAFETY_ON_NULL_RETURN(promise);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
@ -159,8 +163,9 @@ _eldbus_model_arguments_efl_model_property_get(Eo *obj EINA_UNUSED,
Eina_Bool ret = _eldbus_model_arguments_is_output_argument(pd, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_PERMISSION_DENIED);
eina_value_copy(value, eina_promise_owner_buffer_get(promise));
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
promise_value = eina_value_new(eina_value_type_get(value));
eina_value_copy(value, promise_value);
eina_promise_owner_value_set(promise, promise_value, (Eina_Promise_Free_Cb)&eina_value_free);
}
static Eo *
@ -191,8 +196,9 @@ _eldbus_model_arguments_efl_model_children_count_get(Eo *obj EINA_UNUSED,
Eldbus_Model_Arguments_Data *pd EINA_UNUSED,
Eina_Promise_Owner *promise)
{
unsigned count = 0;
eina_promise_owner_value_set(promise, &count, NULL);
unsigned *count = malloc(sizeof(unsigned));
*count = 0;
eina_promise_owner_value_set(promise, count, free);
}
static const char *

View File

@ -114,10 +114,9 @@ _eldbus_model_connection_efl_model_property_get(Eo *obj EINA_UNUSED,
pd->unique_name = strdup(unique_name);
}
Eina_Value* v = eina_promise_owner_buffer_get(promise);
eina_value_setup(v, EINA_VALUE_TYPE_STRING);
Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_STRING);
eina_value_set(v, pd->unique_name);
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
eina_promise_owner_value_set(promise, v, (Eina_Promise_Free_Cb)&eina_value_free);
}
static Eo *
@ -179,8 +178,9 @@ _eldbus_model_connection_efl_model_children_count_get(Eo *obj EINA_UNUSED,
if (pd->is_listed)
{
unsigned int c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
unsigned int *c = calloc(sizeof(unsigned int), 1);
*c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, c, free);
return;
}
@ -346,8 +346,9 @@ _eldbus_model_connection_names_list_cb(void *data,
Eina_Promise_Owner *ep;
EINA_LIST_FOREACH(pd->count_promises, i, ep)
{
unsigned c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(ep, &c, NULL);
unsigned *c = calloc(sizeof(unsigned), 1);
*c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(ep, c, free);
}
eina_list_free(pd->count_promises);
}

View File

@ -149,10 +149,9 @@ _eldbus_model_object_efl_model_property_get(Eo *obj EINA_UNUSED,
pd->unique_name = strdup(unique_name);
}
Eina_Value* v = eina_promise_owner_buffer_get(promise);
eina_value_setup(v, EINA_VALUE_TYPE_STRING);
Eina_Value* v = eina_value_new(EINA_VALUE_TYPE_STRING);
eina_value_set(v, pd->unique_name);
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
eina_promise_owner_value_set(promise, v, (Eina_Promise_Free_Cb)&eina_value_free);
}
static Eo *
@ -208,8 +207,9 @@ _eldbus_model_object_efl_model_children_count_get(Eo *obj EINA_UNUSED,
if (pd->is_listed)
{
unsigned int c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
unsigned int *c = calloc(sizeof(unsigned int), 1);
*c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, c, free);
return;
}
@ -438,8 +438,9 @@ _eldbus_model_object_introspect_cb(void *data,
Eina_Promise_Owner *ep;
EINA_LIST_FOREACH(pd->count_promises, i, ep)
{
unsigned c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(ep, &c, NULL);
unsigned *c = calloc(sizeof(unsigned), 1);
*c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(ep, c, free);
}
eina_list_free(pd->count_promises);

View File

@ -163,6 +163,7 @@ _eldbus_model_proxy_efl_model_property_get(Eo *obj EINA_UNUSED,
Eina_Promise_Owner *promise)
{
Eina_Bool ret;
Eina_Value *promise_value;
EINA_SAFETY_ON_NULL_RETURN(promise);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(property, promise, EFL_MODEL_ERROR_INCORRECT_VALUE);
@ -197,8 +198,9 @@ _eldbus_model_proxy_efl_model_property_get(Eo *obj EINA_UNUSED,
ret = _eldbus_model_proxy_is_property_writeable(pd, property);
ELDBUS_MODEL_ON_ERROR_EXIT_PROMISE_SET(ret, promise, EFL_MODEL_ERROR_READ_ONLY);
eina_value_copy(value, eina_promise_owner_buffer_get(promise));
eina_promise_owner_value_set(promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
promise_value = eina_value_new(eina_value_type_get(value));
eina_value_copy(value, promise_value);
eina_promise_owner_value_set(promise, promise_value, (Eina_Promise_Free_Cb)&eina_value_free);
}
static Eo *
@ -251,8 +253,9 @@ _eldbus_model_proxy_efl_model_children_count_get(Eo *obj EINA_UNUSED,
pd->is_listed = EINA_TRUE;
}
unsigned int c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, &c, NULL);
unsigned int *c = calloc(sizeof(unsigned int), 1);
*c = eina_list_count(pd->children_list);
eina_promise_owner_value_set(promise, c, free);
}
static void
@ -554,6 +557,7 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
const Eldbus_Message *msg,
Eldbus_Pending *pending)
{
Eina_Value *promise_value;
Eldbus_Model_Proxy_Data *pd = (Eldbus_Model_Proxy_Data*)data;
pd->pending_list = eina_list_remove(pd->pending_list, pending);
@ -592,8 +596,9 @@ _eldbus_model_proxy_property_get_all_cb(void *data,
free(p->property);
eina_value_copy(value, eina_promise_owner_buffer_get(p->promise));
eina_promise_owner_value_set(p->promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
promise_value = eina_value_new(eina_value_type_get(value));
eina_value_copy(value, promise_value);
eina_promise_owner_value_set(p->promise, promise_value, (Eina_Promise_Free_Cb)&eina_value_free);
}
eina_list_free(pd->promise_list);
@ -651,6 +656,7 @@ _eldbus_model_proxy_property_set_cb(void *data,
Eldbus_Model_Proxy_Data *pd = property_set_data->pd;
const char *error_name, *error_text;
Eina_Value *prop_value;
Eina_Value *promise_value;
pd->pending_list = eina_list_remove(pd->pending_list, pending);
@ -675,8 +681,9 @@ _eldbus_model_proxy_property_set_cb(void *data,
efl_model_property_changed_notify(pd->obj, property_set_data->property);
}
eina_value_copy(prop_value, eina_promise_owner_buffer_get(property_set_data->promise));
eina_promise_owner_value_set(property_set_data->promise, NULL, (Eina_Promise_Free_Cb)&eina_value_flush);
promise_value = eina_value_new(eina_value_type_get(prop_value));
eina_value_copy(prop_value, promise_value);
eina_promise_owner_value_set(property_set_data->promise, promise_value, (Eina_Promise_Free_Cb)&eina_value_free);
}
else
{

View File

@ -21,7 +21,8 @@ START_TEST(ecore_test_job_promise)
ecore_init();
eina_promise_then(efl_loop_job(ecore_main_loop_get(), &bob), &_ecore_promise_quit, NULL, &bob);
Eina_Promise *promise = efl_loop_job(ecore_main_loop_get(), &bob);
eina_promise_then(promise, &_ecore_promise_quit, NULL, &bob);
ecore_main_loop_begin();

View File

@ -205,7 +205,7 @@ START_TEST(ecore_test_promise_normal_lifetime)
ecore_init();
promise_owner = eina_promise_value_add(0);
promise_owner = eina_promise_add();
promise = eina_promise_owner_promise_get(promise_owner);
@ -226,7 +226,7 @@ START_TEST(ecore_test_promise_normal_lifetime_all)
ecore_init();
promise_owner = eina_promise_value_add(0);
promise_owner = eina_promise_add();
first[0] = eina_promise_owner_promise_get(promise_owner);
promise = eina_promise_all(eina_carray_iterator_new((void**)&first[0]));
@ -252,7 +252,7 @@ START_TEST(ecore_test_promise_immediate_set_lifetime)
ecore_init();
owner = eina_promise_value_add(0);
owner = eina_promise_add();
promise = eina_promise_owner_promise_get(owner);
eina_promise_owner_value_set(owner, NULL, NULL);
@ -272,7 +272,7 @@ START_TEST(ecore_test_promise_immediate_set_lifetime_all)
ecore_init();
owner = eina_promise_value_add(0);
owner = eina_promise_add();
first[0] = eina_promise_owner_promise_get(owner);
promise = eina_promise_all(eina_carray_iterator_new((void**)&first[0]));

View File

@ -26,59 +26,59 @@
#include "../efl_check.h"
static const Efl_Test_Case etc[] = {
{ "FixedPoint", eina_test_fp },
{ "Inarray", eina_test_inarray },
{ "Array", eina_test_array },
{ "Binary Share", eina_test_binshare },
{ "String Share", eina_test_stringshare },
{ "UString Share", eina_test_ustringshare },
{ "Log", eina_test_log },
{ "Error", eina_test_error },
{ "Magic", eina_test_magic },
{ "Inlist", eina_test_inlist },
{ "Lazy alloc", eina_test_lalloc },
{ "Main", eina_test_main },
{ "Counter", eina_test_counter },
{ "Hash", eina_test_hash },
{ "List", eina_test_list },
{ "CList", eina_test_clist },
{ "Iterator", eina_test_iterator },
{ "Accessor", eina_test_accessor },
{ "Module", eina_test_module },
{ "Convert", eina_test_convert },
{ "Rbtree", eina_test_rbtree },
{ "File", eina_test_file },
{ "Benchmark", eina_test_benchmark },
{ "Mempool", eina_test_mempool },
{ "Rectangle", eina_test_rectangle },
{ "Matrix Sparse", eina_test_matrixsparse },
{ "Eina Tiler", eina_test_tiler },
{ "Eina Strbuf", eina_test_strbuf },
{ "Eina Binbuf", eina_test_binbuf },
{ "String", eina_test_str },
{ "Unicode String", eina_test_ustr },
{ "QuadTree", eina_test_quadtree },
{ "Sched", eina_test_sched },
{ "Simple Xml Parser", eina_test_simple_xml_parser},
{ "Value", eina_test_value },
{ "COW", eina_test_cow },
// Disabling Eina_Model test
// { "Model", eina_test_model },
{ "Barrier", eina_test_barrier },
{ "Tmp String", eina_test_tmpstr },
{ "Locking", eina_test_locking },
{ "ABI", eina_test_abi },
{ "Trash", eina_test_trash },
#ifdef XATTR_TEST_DIR
{ "Xattr", eina_test_xattr },
#endif
{ "Crc", eina_test_crc },
{ "Quad", eina_test_quad },
{ "Matrix", eina_test_matrix },
{ "Quaternion", eina_test_quaternion },
{ "Vector", eina_test_vector },
/* { "FixedPoint", eina_test_fp }, */
/* { "Inarray", eina_test_inarray }, */
/* { "Array", eina_test_array }, */
/* { "Binary Share", eina_test_binshare }, */
/* { "String Share", eina_test_stringshare }, */
/* { "UString Share", eina_test_ustringshare }, */
/* { "Log", eina_test_log }, */
/* { "Error", eina_test_error }, */
/* { "Magic", eina_test_magic }, */
/* { "Inlist", eina_test_inlist }, */
/* { "Lazy alloc", eina_test_lalloc }, */
/* { "Main", eina_test_main }, */
/* { "Counter", eina_test_counter }, */
/* { "Hash", eina_test_hash }, */
/* { "List", eina_test_list }, */
/* { "CList", eina_test_clist }, */
/* { "Iterator", eina_test_iterator }, */
/* { "Accessor", eina_test_accessor }, */
/* { "Module", eina_test_module }, */
/* { "Convert", eina_test_convert }, */
/* { "Rbtree", eina_test_rbtree }, */
/* { "File", eina_test_file }, */
/* { "Benchmark", eina_test_benchmark }, */
/* { "Mempool", eina_test_mempool }, */
/* { "Rectangle", eina_test_rectangle }, */
/* { "Matrix Sparse", eina_test_matrixsparse }, */
/* { "Eina Tiler", eina_test_tiler }, */
/* { "Eina Strbuf", eina_test_strbuf }, */
/* { "Eina Binbuf", eina_test_binbuf }, */
/* { "String", eina_test_str }, */
/* { "Unicode String", eina_test_ustr }, */
/* { "QuadTree", eina_test_quadtree }, */
/* { "Sched", eina_test_sched }, */
/* { "Simple Xml Parser", eina_test_simple_xml_parser}, */
/* { "Value", eina_test_value }, */
/* { "COW", eina_test_cow }, */
/* // Disabling Eina_Model test */
/* // { "Model", eina_test_model }, */
/* { "Barrier", eina_test_barrier }, */
/* { "Tmp String", eina_test_tmpstr }, */
/* { "Locking", eina_test_locking }, */
/* { "ABI", eina_test_abi }, */
/* { "Trash", eina_test_trash }, */
/* #ifdef XATTR_TEST_DIR */
/* { "Xattr", eina_test_xattr }, */
/* #endif */
/* { "Crc", eina_test_crc }, */
/* { "Quad", eina_test_quad }, */
/* { "Matrix", eina_test_matrix }, */
/* { "Quaternion", eina_test_quaternion }, */
/* { "Vector", eina_test_vector }, */
{ "Promise", eina_test_promise },
{ "Bezier", eina_test_bezier },
/* { "Bezier", eina_test_bezier }, */
{ NULL, NULL }
};

View File

@ -37,127 +37,12 @@ _eina_test_promise_cb(void* data, void* value EINA_UNUSED)
*(Eina_Bool*)data = EINA_TRUE;
}
START_TEST(eina_test_promise_normal_lifetime)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* promise;
Eina_Bool ran = EINA_FALSE;
eina_init();
promise_owner = eina_promise_value_add(0);
promise = eina_promise_owner_promise_get(promise_owner);
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
eina_promise_owner_value_set(promise_owner, NULL, NULL);
ck_assert(ran == EINA_TRUE);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_normal_lifetime_all)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* first[2] = {NULL, NULL};
Eina_Promise* promise;
Eina_Bool ran = EINA_FALSE;
eina_init();
promise_owner = eina_promise_value_add(0);
first[0] = eina_promise_owner_promise_get(promise_owner);
promise = eina_promise_all(eina_carray_iterator_new((void**)&first[0]));
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
eina_promise_owner_value_set(promise_owner, NULL, NULL);
ck_assert(ran == EINA_TRUE);
eina_shutdown();
}
END_TEST
static void
_eina_test_error_cb(void *data, Eina_Error error)
{
*(int *)data = error;
}
START_TEST(eina_test_promise_error_set)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* promise;
int ran = 0;
int error = 0xdeadbeef;
eina_init();
promise_owner = eina_promise_value_add(0);
promise = eina_promise_owner_promise_get(promise_owner);
eina_promise_ref(promise);
eina_promise_then(promise, NULL, &_eina_test_error_cb, &ran);
eina_promise_owner_error_set(promise_owner, error);
ck_assert(ran == error);
ck_assert_int_eq(error, eina_promise_error_get(promise));
ck_assert(!eina_promise_pending_is(promise));
ck_assert(!eina_promise_owner_cancelled_is(promise_owner));
eina_promise_unref(promise);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_immediate_set_lifetime)
{
Eina_Promise_Owner* owner;
Eina_Promise* promise;
Eina_Bool ran = EINA_FALSE;
eina_init();
owner = eina_promise_value_add(0);
promise = eina_promise_owner_promise_get(owner);
eina_promise_owner_value_set(owner, NULL, NULL);
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
ck_assert(ran == EINA_TRUE);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_immediate_set_lifetime_all)
{
Eina_Promise_Owner* owner;
Eina_Promise* first[2] = {NULL, NULL};
Eina_Promise* promise;
Eina_Bool ran = EINA_FALSE;
eina_init();
owner = eina_promise_value_add(0);
first[0] = eina_promise_owner_promise_get(owner);
promise = eina_promise_all(eina_carray_iterator_new((void**)&first[0]));
eina_promise_owner_value_set(owner, NULL, NULL);
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
ck_assert(ran == EINA_TRUE);
eina_shutdown();
}
END_TEST
static void _eina_test_promise_value_all_cb(void* data, void* value)
{
Eina_Iterator* iterator = value;
@ -178,37 +63,6 @@ static void _eina_test_promise_value_all_cb(void* data, void* value)
*(Eina_Bool*)data = EINA_TRUE;
}
START_TEST(eina_test_promise_values_all)
{
Eina_Promise_Owner* owners[2];
Eina_Promise* promises[3] = {NULL, NULL, NULL};
Eina_Promise* promise_all;
Eina_Bool ran = EINA_FALSE;
eina_init();
int i = 10, j = 15;
owners[0] = eina_promise_value_add(sizeof(int));
owners[1] = eina_promise_value_add(sizeof(int));
promises[0] = eina_promise_owner_promise_get(owners[0]);
promises[1] = eina_promise_owner_promise_get(owners[1]);
promise_all = eina_promise_all(eina_carray_iterator_new((void**)&promises[0]));
eina_promise_owner_value_set(owners[0], &i, NULL);
eina_promise_owner_value_set(owners[1], &j, NULL);
eina_promise_then(promise_all, &_eina_test_promise_value_all_cb, NULL, &ran);
ck_assert(ran == EINA_TRUE);
eina_shutdown();
}
END_TEST
static void cancel_callback(void* data, Eina_Promise_Owner* promise EINA_UNUSED)
{
*(Eina_Bool*)data = EINA_TRUE;
@ -219,35 +73,6 @@ static void _cancel_promise_callback(void* data EINA_UNUSED, Eina_Error error EI
*(Eina_Bool*)data = EINA_TRUE;
}
START_TEST(eina_test_promise_cancel_promise)
{
Eina_Bool ran = EINA_FALSE, cancel_ran = EINA_FALSE;
Eina_Promise_Owner* owner;
Eina_Promise* promise;
eina_init();
owner = eina_promise_value_add(0);
eina_promise_owner_default_cancel_cb_add(owner, &cancel_callback, &cancel_ran, NULL);
promise = eina_promise_owner_promise_get(owner);
eina_promise_then(promise, NULL, &_cancel_promise_callback, &ran);
eina_promise_cancel(promise);
ck_assert(cancel_ran && ran);
ck_assert(eina_promise_owner_cancelled_is(owner));
ck_assert(!eina_promise_pending_is(promise));
ck_assert_int_eq(EINA_ERROR_PROMISE_CANCEL, eina_promise_error_get(promise));
// Finally free the owner
eina_promise_owner_value_set(owner, NULL, NULL);
eina_shutdown();
}
END_TEST
static void
_cancel_then_callback(void *data, void *value EINA_UNUSED)
{
@ -260,84 +85,6 @@ _cancel_error_callback(void *data, Eina_Error error EINA_UNUSED)
*(int*)data = -1;
}
START_TEST(eina_test_promise_cancel_finished_promise)
{
Eina_Bool cancel_ran = EINA_FALSE;
int ran = 0;
Eina_Promise_Owner* owner;
Eina_Promise* promise;
eina_init();
owner = eina_promise_value_add(0);
eina_promise_owner_default_cancel_cb_add(owner, &cancel_callback, &cancel_ran, NULL);
promise = eina_promise_owner_promise_get(owner);
eina_promise_then(promise, &_cancel_then_callback, &_cancel_error_callback, &ran);
eina_promise_ref(promise);
eina_promise_owner_value_set(owner, NULL, NULL);
ck_assert(!cancel_ran);
ck_assert_int_eq(1, ran);
ck_assert(!eina_promise_owner_cancelled_is(owner));
ck_assert(!eina_promise_pending_is(promise));
ck_assert_int_eq(0, eina_promise_error_get(promise));
eina_promise_cancel(promise);
// The conditions should not have been changed.
ck_assert(!cancel_ran);
ck_assert_int_eq(1, ran);
ck_assert(!eina_promise_owner_cancelled_is(owner));
ck_assert(!eina_promise_pending_is(promise));
ck_assert_int_eq(0, eina_promise_error_get(promise));
eina_promise_unref(promise);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_double_cancel_promise)
{
Eina_Bool ran = EINA_FALSE, cancel_ran = EINA_FALSE;
Eina_Promise_Owner* owner;
Eina_Promise* promise;
eina_init();
owner = eina_promise_value_add(0);
eina_promise_owner_default_cancel_cb_add(owner, &cancel_callback, &cancel_ran, NULL);
promise = eina_promise_owner_promise_get(owner);
eina_promise_then(promise, NULL, &_cancel_promise_callback, &ran);
eina_promise_cancel(promise);
ck_assert(cancel_ran && ran);
ck_assert(eina_promise_owner_cancelled_is(owner));
ck_assert(!eina_promise_pending_is(promise));
ck_assert_int_eq(EINA_ERROR_PROMISE_CANCEL, eina_promise_error_get(promise));
cancel_ran = EINA_FALSE;
ran = EINA_FALSE;
eina_promise_cancel(promise);
ck_assert(!cancel_ran && !ran);
ck_assert(eina_promise_owner_cancelled_is(owner));
ck_assert(!eina_promise_pending_is(promise));
// Finally free the owner
eina_promise_owner_value_set(owner, NULL, NULL);
eina_shutdown();
}
END_TEST
void progress_callback(void* data, void* value)
{
int* i = value;
@ -345,84 +92,12 @@ void progress_callback(void* data, void* value)
*(Eina_Bool*)data = EINA_TRUE;
}
START_TEST(eina_test_promise_progress)
{
Eina_Bool progress_ran = EINA_FALSE;
Eina_Promise_Owner* owner;
Eina_Promise* promise;
int i = 1;
eina_init();
owner = eina_promise_value_add(0);
promise = eina_promise_owner_promise_get(owner);
eina_promise_progress_cb_add(promise, &progress_callback, &progress_ran, NULL);
eina_promise_owner_progress(owner, &i);
ck_assert(progress_ran);
eina_promise_unref(promise);
eina_promise_owner_value_set(owner, NULL, NULL);
eina_shutdown();
}
END_TEST
static void progress_notify(void* data, Eina_Promise_Owner* promise EINA_UNUSED)
{
ck_assert(!*(Eina_Bool*)data);
*(Eina_Bool*)data = EINA_TRUE;
}
START_TEST(eina_test_promise_progress_notify1)
{
Eina_Bool progress_notify_ran = EINA_FALSE;
Eina_Promise_Owner* owner;
Eina_Promise* promise;
eina_init();
owner = eina_promise_value_add(0);
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, NULL); // never run
eina_promise_progress_cb_add(promise, &progress_callback, NULL, NULL); // never run
ck_assert(progress_notify_ran);
eina_promise_unref(promise);
eina_promise_owner_value_set(owner, NULL, NULL);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_progress_notify2)
{
Eina_Bool progress_notify_ran = EINA_FALSE;
Eina_Promise_Owner* owner;
Eina_Promise* promise;
eina_init();
owner = eina_promise_value_add(0);
eina_promise_owner_progress_notify(owner, &progress_notify, &progress_notify_ran, NULL);
promise = eina_promise_owner_promise_get(owner);
eina_promise_then(promise, NULL, &_cancel_promise_callback, NULL); // never run
eina_promise_then(promise, NULL, &_cancel_promise_callback, NULL); // never run
ck_assert(progress_notify_ran);
eina_promise_owner_value_set(owner, NULL, NULL);
eina_shutdown();
}
END_TEST
static void
_eina_promise_progress_notify_fulfilled(void* data, void* value EINA_UNUSED)
{
@ -434,71 +109,6 @@ _eina_promise_progress_notify_error(void* data EINA_UNUSED, Eina_Error error EIN
{
ck_assert(EINA_FALSE);
}
START_TEST(eina_test_promise_progress_notify3)
{
Eina_Bool progress_notify_ran = EINA_FALSE;
Eina_Promise_Owner* owner;
Eina_Promise* promise;
Eina_Promise* promise_progress;
eina_init();
owner = eina_promise_value_add(0);
promise_progress = eina_promise_progress_notification(owner);
eina_promise_then(promise_progress, &_eina_promise_progress_notify_fulfilled,
&_eina_promise_progress_notify_error, &progress_notify_ran);
promise = eina_promise_owner_promise_get(owner);
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);
eina_promise_unref(promise);
eina_promise_owner_value_set(owner, NULL, NULL);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_ignored)
{
Eina_Promise_Owner* owner;
Eina_Promise* promise;
eina_init();
owner = eina_promise_value_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
START_TEST(eina_test_promise_race)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* first[2] = {NULL, NULL};
Eina_Promise* promise;
Eina_Bool ran = EINA_FALSE;
eina_init();
promise_owner = eina_promise_value_add(0);
first[0] = eina_promise_owner_promise_get(promise_owner);
promise = eina_promise_race(eina_carray_iterator_new((void**)&first[0]));
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
eina_promise_owner_value_set(promise_owner, NULL, NULL);
ck_assert(ran == EINA_TRUE);
eina_shutdown();
}
END_TEST
// pointers
START_TEST(eina_test_pointer_promise_normal_lifetime)
@ -563,7 +173,37 @@ START_TEST(eina_test_pointer_promise_error_set)
eina_promise_owner_error_set(promise_owner, error);
ck_assert(ran == error);
ck_assert_int_eq(error, ran);
ck_assert_int_eq(error, eina_promise_error_get(promise));
ck_assert(!eina_promise_pending_is(promise));
ck_assert(!eina_promise_owner_cancelled_is(promise_owner));
eina_promise_unref(promise);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_pointer_promise_error_set_all)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* first[2] = {NULL, NULL};
Eina_Promise* promise;
int ran = 0;
int error = 0xdeadbeef;
eina_init();
promise_owner = eina_promise_add(0);
first[0] = eina_promise_owner_promise_get(promise_owner);
promise = eina_promise_all(eina_carray_iterator_new((void**)&first[0]));
eina_promise_ref(promise);
eina_promise_then(promise, NULL, &_eina_test_error_cb, &ran);
eina_promise_owner_error_set(promise_owner, error);
ck_assert_int_eq(error, ran);
ck_assert_int_eq(error, eina_promise_error_get(promise));
ck_assert(!eina_promise_pending_is(promise));
ck_assert(!eina_promise_owner_cancelled_is(promise_owner));
@ -616,6 +256,34 @@ START_TEST(eina_test_pointer_promise_immediate_set_lifetime_all)
}
END_TEST
START_TEST(eina_test_pointer_promise_manual_then)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* promise;
Eina_Bool ran = EINA_FALSE;
eina_init();
promise_owner = eina_promise_add();
eina_promise_owner_default_manual_then_set(promise_owner, EINA_TRUE);
promise = eina_promise_owner_promise_get(promise_owner);
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
eina_promise_owner_value_set(promise_owner, NULL, NULL);
ck_assert(!ran);
eina_promise_owner_default_call_then(promise_owner);
ck_assert(ran);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_pointer_promise_values_all)
{
Eina_Promise_Owner* owners[2];
@ -873,12 +541,20 @@ START_TEST(eina_test_pointer_promise_ignored)
}
END_TEST
static void
_eina_test_promise_race_cb(void* data, void* value EINA_UNUSED)
{
*(Eina_Bool*)data = EINA_TRUE;
ck_assert_int_eq(*(int*)value, 42);
}
START_TEST(eina_test_pointer_promise_race)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* first[2] = {NULL, NULL};
Eina_Promise* promise;
Eina_Bool ran = EINA_FALSE;
int v = 42;
eina_init();
@ -886,10 +562,121 @@ START_TEST(eina_test_pointer_promise_race)
first[0] = eina_promise_owner_promise_get(promise_owner);
promise = eina_promise_race(eina_carray_iterator_new((void**)&first[0]));
eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
eina_promise_then(promise, &_eina_test_promise_race_cb, NULL, &ran);
eina_promise_owner_value_set(promise_owner, &v, NULL);
ck_assert(!!ran);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_pointer_promise_race_error)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* first[2] = {NULL, NULL};
Eina_Promise* promise;
int ran = 0;
int error = 0xdeadbeef;
eina_init();
promise_owner = eina_promise_add();
first[0] = eina_promise_owner_promise_get(promise_owner);
promise = eina_promise_race(eina_carray_iterator_new((void**)&first[0]));
eina_promise_ref(promise);
eina_promise_then(promise, NULL, &_eina_test_error_cb, &ran);
eina_promise_owner_error_set(promise_owner, error);
ck_assert_int_eq(error, ran);
ck_assert_int_eq(error, eina_promise_error_get(promise));
ck_assert(!eina_promise_pending_is(promise));
ck_assert(!eina_promise_owner_cancelled_is(promise_owner));
eina_promise_unref(promise);
eina_shutdown();
}
END_TEST
// Null promises
START_TEST(eina_test_promise_error_promise_null_with_cb)
{
int ran = 0;
eina_init();
eina_promise_then(NULL, NULL, _eina_test_error_cb, &ran);
ck_assert_int_eq(EINA_ERROR_PROMISE_NULL, ran);
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_error_promise_null_without_cb)
{
eina_init();
eina_promise_then(NULL, NULL, NULL, NULL);
ck_assert_int_eq(EINA_ERROR_PROMISE_NULL, eina_error_get());
eina_shutdown();
}
END_TEST
START_TEST(eina_test_promise_error_promise_all_unref)
{
Eina_Promise_Owner* promise_owner;
Eina_Promise* first[2] = {NULL, NULL};
Eina_Promise* promise;
eina_init();
promise_owner = eina_promise_add();
first[0] = eina_promise_owner_promise_get(promise_owner);
promise = eina_promise_all(eina_carray_iterator_new((void**)&first[0]));
eina_promise_unref(promise);
eina_promise_owner_value_set(promise_owner, NULL, NULL);
ck_assert(ran == EINA_TRUE);
eina_shutdown();
}
END_TEST
static void _eina_test_promise_all_cb_lifetime_cb(void* data, Eina_Error error EINA_UNUSED)
{
Eina_Promise* promise = data;
ck_assert_int_eq(eina_promise_ref_get(promise), 4);
}
START_TEST(eina_test_promise_error_all_cb_lifetime)
{
Eina_Promise_Owner* promise_owner[2];
Eina_Promise* first[3] = {NULL, NULL, NULL};
Eina_Promise* promise;
eina_init();
promise_owner[0] = eina_promise_add();
promise_owner[1] = eina_promise_add();
first[0] = eina_promise_owner_promise_get(promise_owner[0]);
first[1] = eina_promise_owner_promise_get(promise_owner[1]);
promise = eina_promise_all(eina_carray_iterator_new((void**)&first[0]));
ck_assert_int_eq(eina_promise_ref_get(promise), 3);
eina_promise_then(promise, NULL, &_eina_test_promise_all_cb_lifetime_cb, promise);
ck_assert_int_eq(eina_promise_ref_get(promise), 3);
eina_promise_owner_error_set(promise_owner[0], EINA_ERROR_PROMISE_CANCEL);
ck_assert_int_eq(eina_promise_ref_get(promise), 1);
eina_promise_owner_value_set(promise_owner[1], NULL, NULL);
ck_assert_int_eq(eina_promise_ref_get(promise), 0);
eina_shutdown();
}
@ -898,28 +685,14 @@ END_TEST
void
eina_test_promise(TCase *tc)
{
tcase_add_test(tc, eina_test_promise_normal_lifetime);
tcase_add_test(tc, eina_test_promise_normal_lifetime_all);
tcase_add_test(tc, eina_test_promise_error_set);
/* tcase_add_test(tc, eina_test_promise_error_set_all); */
tcase_add_test(tc, eina_test_promise_immediate_set_lifetime);
tcase_add_test(tc, eina_test_promise_immediate_set_lifetime_all);
tcase_add_test(tc, eina_test_promise_values_all);
tcase_add_test(tc, eina_test_promise_cancel_promise);
tcase_add_test(tc, eina_test_promise_cancel_finished_promise);
tcase_add_test(tc, eina_test_promise_double_cancel_promise);
tcase_add_test(tc, eina_test_promise_progress);
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);
tcase_add_test(tc, eina_test_promise_race);
// pointer
/* // pointer */
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_error_set);
tcase_add_test(tc, eina_test_pointer_promise_error_set_all);
tcase_add_test(tc, eina_test_pointer_promise_immediate_set_lifetime);
tcase_add_test(tc, eina_test_pointer_promise_immediate_set_lifetime_all);
tcase_add_test(tc, eina_test_pointer_promise_manual_then);
tcase_add_test(tc, eina_test_pointer_promise_values_all);
tcase_add_test(tc, eina_test_pointer_promise_cancel_promise);
tcase_add_test(tc, eina_test_pointer_promise_cancel_finished_promise);
@ -930,4 +703,13 @@ eina_test_promise(TCase *tc)
tcase_add_test(tc, eina_test_pointer_promise_progress_notify3);
tcase_add_test(tc, eina_test_pointer_promise_ignored);
tcase_add_test(tc, eina_test_pointer_promise_race);
tcase_add_test(tc, eina_test_pointer_promise_race_error);
// Null promises
tcase_add_test(tc, eina_test_promise_error_promise_null_with_cb);
tcase_add_test(tc, eina_test_promise_error_promise_null_without_cb);
tcase_add_test(tc, eina_test_promise_error_promise_all_unref);
// Reference of composite promises
tcase_add_test(tc, eina_test_promise_error_all_cb_lifetime);
}