felipealmeida pushed a commit to branch master.

http://git.enlightenment.org/core/efl.git/commit/?id=217f3ce842cba43b51d26bf518ecb7c432751ded

commit 217f3ce842cba43b51d26bf518ecb7c432751ded
Author: Lauro Moura <lauromo...@expertisesolutions.com.br>
Date:   Sun Jun 5 20:19:41 2016 -0300

    ecore: Fix ecore thread promises
    
    Make sure we free the promise memory, set MAGIC numbers and avoid
    leaking the underlying eina promise
---
 src/lib/ecore/ecore_thread_promise.c | 16 +++++++++++-----
 src/tests/ecore/ecore_test_promise.c |  2 ++
 2 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/lib/ecore/ecore_thread_promise.c 
b/src/lib/ecore/ecore_thread_promise.c
index 443920a..7798d36 100644
--- a/src/lib/ecore/ecore_thread_promise.c
+++ b/src/lib/ecore/ecore_thread_promise.c
@@ -41,9 +41,12 @@ static void 
_ecore_promise_ref_update(_Ecore_Thread_Promise_Owner* p)
   if(!p->ref_count)
     {
        p->eina_promise->unref(p->eina_promise);
+       if (!p->then_count) // Whether we still own the initial eina_promise ref
+         p->eina_promise->unref(p->eina_promise);
        p->eina_promise = NULL;
        p->eina_owner = NULL;
        p->thread_callback_data.thread = NULL;
+       free(p);
     }
 }
 
@@ -67,6 +70,10 @@ static void _ecore_promise_thread_end(void* data, 
Ecore_Thread* thread EINA_UNUS
    else
      {
         eina_promise_owner_default_manual_then_set(p->eina_owner, EINA_FALSE);
+        // This then will steal the ref to the eina_promise, working
+        // refcount-wise like a normal then on the thread promise.
+        p->ref_count++;
+        p->then_count++;
         eina_promise_then(p->eina_promise, &_ecore_promise_thread_release_ref,
                           
(Eina_Promise_Error_Cb)&_ecore_promise_thread_release_ref, p);
      }
@@ -145,10 +152,7 @@ static void _ecore_promise_then(Eina_Promise* promise, 
Eina_Promise_Cb callback,
 {
    _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->ref_count++;
    v->then_count++;
 }
 static void* _ecore_promise_value_get(Eina_Promise const* promise)
@@ -219,6 +223,7 @@ Ecore_Thread* 
ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
    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);
+   EINA_MAGIC_SET(&priv->owner_vtable, EINA_MAGIC_PROMISE_OWNER);
 
    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);
@@ -230,6 +235,7 @@ Ecore_Thread* 
ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
    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;
    priv->thread_callback_data.func_blocking = func_blocking;
@@ -248,6 +254,6 @@ Ecore_Thread* 
ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
                                &_ecore_promise_thread_end, 
&_ecore_promise_thread_cancel, priv,
                                EINA_FALSE);
    if(promise)
-     *promise = priv->eina_promise;
+     *promise = &priv->promise_vtable;
    return priv->thread_callback_data.thread;
 }
diff --git a/src/tests/ecore/ecore_test_promise.c 
b/src/tests/ecore/ecore_test_promise.c
index 791e6fc..5f2a754 100644
--- a/src/tests/ecore/ecore_test_promise.c
+++ b/src/tests/ecore/ecore_test_promise.c
@@ -348,6 +348,8 @@ static void promise_progress_thread(const void* data 
EINA_UNUSED,
 {
   void* v = (void*)1;
   eina_promise_owner_progress(promise, v);
+  // Release the promise to avoid leaks
+  eina_promise_owner_value_set(promise, NULL, NULL);
 }
 
 static void _progress_callback(void* data EINA_UNUSED, void* value)

-- 


Reply via email to