felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=35dd5b5cab8fa483b24de4dc1cffa5edc70bbd97

commit 35dd5b5cab8fa483b24de4dc1cffa5edc70bbd97
Author: Felipe Magno de Almeida <fel...@expertisesolutions.com.br>
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);
 }

-- 


Reply via email to