felipealmeida pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=35dd5b5cab8fa483b24de4dc1cffa5edc70bbd97
commit 35dd5b5cab8fa483b24de4dc1cffa5edc70bbd97 Author: Felipe Magno de Almeida <[email protected]> Date: Wed Apr 13 14:43:43 2016 -0300 eina: Fix promise error with eina_promise_all Fix value_set and error_set signatures which were receiving a owner. They actually receive the promise and not the owner, this caused wrong access to memory and were not visible by warnings because the functions are casted. This problem caused errors in which it seemed that promise had actually error'ed when questioned it. --- src/lib/eina/eina_promise.c | 37 +++++++++++++++------------ src/tests/eina/eina_test_promise.c | 52 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c index 9a7c259..459f686 100644 --- a/src/lib/eina/eina_promise.c +++ b/src/lib/eina/eina_promise.c @@ -108,7 +108,6 @@ _eina_promise_then_calls(_Eina_Promise_Default_Owner* promise) } else if (callback->callback) { - fprintf(stderr, "then callback\n"); (*callback->callback)(callback->data, &promise->value[0]); } _eina_promise_unref(&promise->promise); @@ -151,18 +150,18 @@ _eina_promise_del(_Eina_Promise_Default_Owner* promise) } static void * -_eina_promise_buffer_get(_Eina_Promise_Default_Owner* promise) +_eina_promise_owner_buffer_get(_Eina_Promise_Default_Owner* promise) { return &promise->value[0]; } static void * -_eina_promise_value_get(_Eina_Promise_Default_Owner const* promise) +_eina_promise_value_get(_Eina_Promise_Default const* p) { - if (promise->promise.has_finished) + _Eina_Promise_Default_Owner const* promise = EINA_PROMISE_GET_OWNER(p); + if (promise->promise.has_finished && !promise->promise.has_errored) { - return (void*)(promise->promise.value_size && !promise->promise.has_errored ? - &promise->value[0] : NULL); + return (void*)&promise->value[0]; } else { @@ -171,7 +170,7 @@ _eina_promise_value_get(_Eina_Promise_Default_Owner const* promise) } static void -_eina_promise_value_set(_Eina_Promise_Default_Owner* promise, void* data, Eina_Promise_Free_Cb free) +_eina_promise_owner_value_set(_Eina_Promise_Default_Owner* promise, void* data, Eina_Promise_Free_Cb free) { if (data && promise->promise.value_size) { @@ -198,7 +197,6 @@ _eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback, cb->error_cb = error_cb; cb->data = data; promise->promise.then_callbacks = eina_inlist_append(promise->promise.then_callbacks, EINA_INLIST_GET(cb)); - fprintf(stderr, "appending then callback\n"); if (!promise->promise.is_first_then) { @@ -212,7 +210,7 @@ _eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback, } static void -_eina_promise_error_set(_Eina_Promise_Default_Owner* promise, Eina_Error error) +_eina_promise_owner_error_set(_Eina_Promise_Default_Owner* promise, Eina_Error error) { promise->promise.error = error; promise->promise.has_errored = EINA_TRUE; @@ -231,11 +229,11 @@ _eina_promise_finish(_Eina_Promise_Default_Owner* promise) } static Eina_Error -_eina_promise_error_get(_Eina_Promise_Default_Owner const* promise) +_eina_promise_error_get(_Eina_Promise_Default const* promise) { - if (promise->promise.has_errored) + if (promise->has_errored) { - return promise->promise.error; + return promise->error; } else { @@ -292,6 +290,12 @@ _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) { @@ -377,12 +381,13 @@ eina_promise_default_add(int value_size) 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_value_set); - p->owner_vtable.error_set = EINA_FUNC_PROMISE_OWNER_ERROR_SET(_eina_promise_error_set); - p->owner_vtable.buffer_get = EINA_FUNC_PROMISE_OWNER_BUFFER_GET(_eina_promise_buffer_get); - p->owner_vtable.value_size_get = EINA_FUNC_PROMISE_OWNER_VALUE_SIZE_GET(_eina_promise_value_size_get); + 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); diff --git a/src/tests/eina/eina_test_promise.c b/src/tests/eina/eina_test_promise.c index 898a4ba..59ed7d7 100644 --- a/src/tests/eina/eina_test_promise.c +++ b/src/tests/eina/eina_test_promise.c @@ -122,6 +122,57 @@ START_TEST(eina_test_promise_immediate_set_lifetime_all) } END_TEST +static void _eina_test_promise_value_all_cb(void* data, void* value) +{ + Eina_Iterator** iterator = value; + int *i, *j; + Eina_Bool b; + + b = eina_iterator_next(*iterator, (void**)&i); + ck_assert(!!b); + + b = eina_iterator_next(*iterator, (void**)&j); + ck_assert(!!b); + + ck_assert(i != NULL); + ck_assert(j != NULL); + ck_assert(*i == 10); + ck_assert(*j == 15); + + *(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_default_add(sizeof(int)); + owners[1] = eina_promise_default_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; @@ -192,6 +243,7 @@ eina_test_promise(TCase *tc) tcase_add_test(tc, eina_test_promise_normal_lifetime_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_progress); } --
