felipealmeida pushed a commit to branch master.

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

commit de9be13d458f2739a536e5863aa8caddd3f7f715
Author: Felipe Magno de Almeida <[email protected]>
Date:   Wed May 25 18:14:29 2016 -0300

    eina: Add promise parameter to then calllbacks
    
    Added promise parameter to then callbacks so callbacks can steal
    ownership of the value from the promise.
---
 src/lib/ecore/ecore_thread_promise.c |  9 ++++++++-
 src/lib/eina/eina_promise.c          | 30 ++++++++++++++++++++++++++----
 src/lib/eina/eina_promise.h          | 25 +++++++++++++++++++++----
 src/lib/elementary/elm_view_form.c   |  8 ++++----
 src/tests/ecore/ecore_test_promise.c | 14 +++++++-------
 src/tests/eina/eina_test_promise.c   | 13 ++++++-------
 6 files changed, 72 insertions(+), 27 deletions(-)

diff --git a/src/lib/ecore/ecore_thread_promise.c 
b/src/lib/ecore/ecore_thread_promise.c
index 1dea1bc..caf312c 100644
--- a/src/lib/ecore/ecore_thread_promise.c
+++ b/src/lib/ecore/ecore_thread_promise.c
@@ -47,7 +47,7 @@ static void 
_ecore_promise_ref_update(_Ecore_Thread_Promise_Owner* p)
     }
 }
 
-static void _ecore_promise_thread_release_ref(void* data, void* value 
EINA_UNUSED)
+static void _ecore_promise_thread_release_ref(void* data, void* value 
EINA_UNUSED, Eina_Promise* promise EINA_UNUSED)
 {
    _Ecore_Thread_Promise_Owner* p = data;
    p->ref_count -= p->then_count;
@@ -197,6 +197,11 @@ 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);
 }
+static void* _ecore_promise_release_value_ownership(Eina_Promise* promise)
+{
+   _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
+   return v->eina_promise->release_value_ownership(v->eina_promise);
+}
 
 Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
                                        Ecore_Thread_Promise_Cb func_cancel,
@@ -230,6 +235,8 @@ 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);
+   priv->promise_vtable.release_value_ownership = 
EINA_FUNC_PROMISE_RELEASE_VALUE_OWNERSHIP
+     (&_ecore_promise_release_value_ownership);
    
    priv->thread_callback_data.data = data;
    priv->thread_callback_data.func_blocking = func_blocking;
diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c
index 93e7094..e8ef06d 100644
--- a/src/lib/eina/eina_promise.c
+++ b/src/lib/eina/eina_promise.c
@@ -169,11 +169,11 @@ _eina_promise_then_calls(_Eina_Promise_Default_Owner* 
promise)
        if (error)
         {
           if (callback->error_cb)
-            (*callback->error_cb)(callback->data, &promise->promise.error);
+            (*callback->error_cb)(callback->data, promise->promise.error, 
&promise->promise.vtable);
         }
        else if (callback->callback)
         {
-          (*callback->callback)(callback->data, &promise->value[0]);
+          (*callback->callback)(callback->data, &promise->value[0], 
&promise->promise.vtable);
         }
        free(callback);
        _eina_promise_unref(&promise->promise);
@@ -240,8 +240,23 @@ _eina_promise_value_get(_Eina_Promise_Default const* p)
      }
 }
 
+static void *
+_eina_promise_release_value_ownership(_Eina_Promise_Default* p)
+{
+   _Eina_Promise_Default_Owner* promise = EINA_PROMISE_GET_OWNER(p);
+   if (promise->promise.has_finished && !promise->promise.has_errored)
+     {
+       promise->promise.value_free_cb = NULL;
+       return (void*)&promise->value[0];
+     }
+   else
+     {
+        return NULL;
+     }
+}
+
 static void
-_eina_promise_owner_value_set(_Eina_Promise_Default_Owner* promise, void* 
data, Eina_Promise_Free_Cb free)
+_eina_promise_owner_value_set(_Eina_Promise_Default_Owner* promise, const 
void* data, Eina_Promise_Free_Cb free)
 {
    if (data && promise->promise.value_size)
      {
@@ -481,6 +496,7 @@ eina_promise_default_add(int value_size)
    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.release_value_ownership = 
EINA_FUNC_PROMISE_RELEASE_VALUE_OWNERSHIP(_eina_promise_release_value_ownership);
    p->promise.has_finished = p->promise.has_errored =
      p->promise.is_cancelled = p->promise.is_manual_then = EINA_FALSE;
    p->promise.is_first_then = EINA_TRUE;
@@ -781,7 +797,7 @@ eina_promise_then(Eina_Promise* promise, Eina_Promise_Cb 
callback,
 }
 
 EAPI void
-eina_promise_owner_value_set(Eina_Promise_Owner* promise, void* value, 
Eina_Promise_Free_Cb free)
+eina_promise_owner_value_set(Eina_Promise_Owner* promise, const void* value, 
Eina_Promise_Free_Cb free)
 {
    promise->value_set(promise, value, free);
 }
@@ -847,6 +863,12 @@ eina_promise_buffer_get(Eina_Promise* promise)
    return promise->buffer_get(promise);
 }
 
+EAPI void *
+eina_promise_release_value_ownership(Eina_Promise* promise)
+{
+   return promise->release_value_ownership(promise);
+}
+
 EAPI size_t
 eina_promise_value_size_get(Eina_Promise const* promise)
 {
diff --git a/src/lib/eina/eina_promise.h b/src/lib/eina/eina_promise.h
index 6921c6a..8bba454 100644
--- a/src/lib/eina/eina_promise.h
+++ b/src/lib/eina/eina_promise.h
@@ -29,12 +29,12 @@ typedef void(*Eina_Promise_Progress_Notify_Cb)(void* data, 
Eina_Promise_Owner* p
 /*
  * @brief Function callback type for when using eina_promise_then
  */
-typedef void(*Eina_Promise_Cb)(void* data, void* value);
+typedef void(*Eina_Promise_Cb)(void* data, void* value, Eina_Promise* promise);
 
 /*
  * @brief Function callback type for when using eina_promise_then
  */
-typedef void(*Eina_Promise_Error_Cb)(void* data, Eina_Error const* error);
+typedef void(*Eina_Promise_Error_Cb)(void* data, Eina_Error error, 
Eina_Promise* promise);
 
 /*
  * @brief Function callback type for progress information
@@ -107,6 +107,13 @@ 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 release_value_ownership 
function override
+ */
+typedef void*(*Eina_Promise_Release_Value_Ownership_Cb)(Eina_Promise* promise);
+
+#define EINA_FUNC_PROMISE_RELEASE_VALUE_OWNERSHIP(Function) 
((Eina_Promise_Release_Value_Ownership_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);
@@ -138,7 +145,7 @@ typedef 
void*(*Eina_Promise_Owner_Promise_Get_Cb)(Eina_Promise_Owner const* prom
 /*
  * @brief Function callback type for promise owner's value_set function 
override
  */
-typedef void(*Eina_Promise_Owner_Value_Set_Cb)(Eina_Promise_Owner* promise, 
void* data, Eina_Promise_Free_Cb free_fun);
+typedef void(*Eina_Promise_Owner_Value_Set_Cb)(Eina_Promise_Owner* promise, 
const void* data, Eina_Promise_Free_Cb free_fun);
 
 #define EINA_FUNC_PROMISE_OWNER_VALUE_SET(Function) 
((Eina_Promise_Owner_Value_Set_Cb)Function)
 
@@ -194,6 +201,7 @@ struct _Eina_Promise
   Eina_Promise_Unref_Cb unref;
   Eina_Promise_Value_Size_Get_Cb value_size_get;
   Eina_Promise_Buffer_Get_Cb buffer_get;
+  Eina_Promise_Release_Value_Ownership_Cb release_value_ownership;
 #define EINA_MAGIC_PROMISE 0x07932A5B
   EINA_MAGIC;
 };
@@ -269,7 +277,7 @@ EAPI Eina_Promise* 
eina_promise_progress_notification(Eina_Promise_Owner* promis
  * @param value The pointer to the value that is going to be copied, or NULL.
  * @param free_cb Callback function to be used to free the value copied
  */
-EAPI void eina_promise_owner_value_set(Eina_Promise_Owner* promise, void* 
value, Eina_Promise_Free_Cb free_cb);
+EAPI void eina_promise_owner_value_set(Eina_Promise_Owner* promise, const 
void* value, Eina_Promise_Free_Cb free_cb);
 
 /*
  * @brief Returns the pointer to the value
@@ -296,6 +304,15 @@ EAPI void* eina_promise_value_get(Eina_Promise const* 
promise);
 EAPI void* eina_promise_buffer_get(Eina_Promise* promise);
 
 /*
+ * @brief Returns the pointer to the value and releases ownership of
+ * the value by the promise.
+ * 
+ * @param promise The promise for which to release value ownership
+ * @return Pointer to value
+ */
+EAPI void* eina_promise_release_value_ownership(Eina_Promise* promise);
+
+/*
  * @brief Returns the pointer to the buffer that holds the value.
  *
  * This function always return the buffer pointer independently if the
diff --git a/src/lib/elementary/elm_view_form.c 
b/src/lib/elementary/elm_view_form.c
index 612165f..8f2fb85 100644
--- a/src/lib/elementary/elm_view_form.c
+++ b/src/lib/elementary/elm_view_form.c
@@ -46,18 +46,18 @@ struct _Elm_View_Form_Promise
 
 
 static void
-_efl_promise_then_widget(Elm_View_Form_Widget *w, Eina_Value *value)
+_efl_promise_then_widget(Elm_View_Form_Widget *w, Eina_Value *value, 
Eina_Promise* promise EINA_UNUSED)
 {
     w->widget_obj_set_cb(w->widget_obj, value, w->widget_propname);
 }
 
 static void
-_efl_promise_error_widget(void *data EINA_UNUSED, const Eina_Error *err 
EINA_UNUSED)
+_efl_promise_error_widget(void *data EINA_UNUSED, Eina_Error err EINA_UNUSED, 
Eina_Promise* promise EINA_UNUSED)
 {
 }
 
 static void
-_efl_model_promise_then_cb(Elm_View_Form_Promise *p, Eina_Value *value)
+_efl_model_promise_then_cb(Elm_View_Form_Promise *p, Eina_Value *value, 
Eina_Promise* promise EINA_UNUSED)
 {
    EINA_SAFETY_ON_NULL_RETURN(p);
 
@@ -78,7 +78,7 @@ _efl_model_promise_then_cb(Elm_View_Form_Promise *p, 
Eina_Value *value)
 }
 
 static void
-_efl_model_promise_error_cb(Elm_View_Form_Promise *p, const Eina_Error *error 
EINA_UNUSED)
+_efl_model_promise_error_cb(Elm_View_Form_Promise *p, Eina_Error error 
EINA_UNUSED, Eina_Promise* promise EINA_UNUSED)
 {
    EINA_SAFETY_ON_NULL_RETURN(p);
 
diff --git a/src/tests/ecore/ecore_test_promise.c 
b/src/tests/ecore/ecore_test_promise.c
index 5a54281..bf2a160 100644
--- a/src/tests/ecore/ecore_test_promise.c
+++ b/src/tests/ecore/ecore_test_promise.c
@@ -11,7 +11,7 @@ void promised_thread(const void* data EINA_UNUSED, 
Eina_Promise_Owner* promise,
   eina_promise_owner_value_set(promise, NULL, NULL);
 }
 
-void promise_callback(void* data EINA_UNUSED, void* value EINA_UNUSED)
+void promise_callback(void* data EINA_UNUSED, void* value EINA_UNUSED, 
Eina_Promise* promise EINA_UNUSED)
 {
   ecore_main_loop_quit();
 }
@@ -36,9 +36,9 @@ void promise_error_thread(const void* data EINA_UNUSED, 
Eina_Promise_Owner* prom
   eina_promise_owner_error_set(promise, EINA_ERROR_OUT_OF_MEMORY);
 }
 
-void promise_error_callback(void* data EINA_UNUSED, Eina_Error const* error)
+void promise_error_callback(void* data EINA_UNUSED, Eina_Error error, 
Eina_Promise* promise EINA_UNUSED)
 {
-  ck_assert(*error == EINA_ERROR_OUT_OF_MEMORY);
+  ck_assert(error == EINA_ERROR_OUT_OF_MEMORY);
   ecore_main_loop_quit();
 }
 
@@ -74,7 +74,7 @@ START_TEST(ecore_test_promise_all)
 }
 END_TEST
 
-void promise_callback2(void* data, void* value EINA_UNUSED)
+void promise_callback2(void* data, void* value EINA_UNUSED, Eina_Promise* 
promise EINA_UNUSED)
 {
   if(++(*(int*)data) == 2)
     ecore_main_loop_quit();
@@ -201,7 +201,7 @@ void promised_block_thread(const void* data EINA_UNUSED, 
Eina_Promise_Owner* pro
 }
 
 static void
-_ecore_test_promise_normal_lifetime_cb(void* data EINA_UNUSED, void* value 
EINA_UNUSED)
+_ecore_test_promise_normal_lifetime_cb(void* data EINA_UNUSED, void* value 
EINA_UNUSED, Eina_Promise* promise EINA_UNUSED)
 {
   ecore_main_loop_quit();
 }
@@ -254,7 +254,7 @@ START_TEST(ecore_test_promise_normal_lifetime_all)
 END_TEST
 
 static void
-_ecore_test_promise_immediate_set_lifetime_cb(void* data EINA_UNUSED, void* 
value EINA_UNUSED)
+_ecore_test_promise_immediate_set_lifetime_cb(void* data EINA_UNUSED, void* 
value EINA_UNUSED, Eina_Promise* promise EINA_UNUSED)
 {
    ecore_main_loop_quit();
 }
@@ -327,7 +327,7 @@ static void _cancel_callback(const void* data, 
Eina_Promise_Owner* promise EINA_
   eina_lock_release(&v->lock);
 }
 
-static void _cancel_promise_callback(void* data EINA_UNUSED, Eina_Error const* 
value)
+static void _cancel_promise_callback(void* data EINA_UNUSED, Eina_Error value, 
Eina_Promise* promise EINA_UNUSED)
 {
   ck_assert(!!value);
   ecore_main_loop_quit();
diff --git a/src/tests/eina/eina_test_promise.c 
b/src/tests/eina/eina_test_promise.c
index 2932e1c..cc7aa88 100644
--- a/src/tests/eina/eina_test_promise.c
+++ b/src/tests/eina/eina_test_promise.c
@@ -32,7 +32,7 @@
 #include "eina_suite.h"
 
 static void
-_eina_test_promise_cb(void* data, void* value EINA_UNUSED)
+_eina_test_promise_cb(void* data, void* value EINA_UNUSED, Eina_Promise* 
promise EINA_UNUSED)
 {
    *(Eina_Bool*)data = EINA_TRUE;
 }
@@ -122,7 +122,7 @@ START_TEST(eina_test_promise_immediate_set_lifetime_all)
 }
 END_TEST
 
-static void _eina_test_promise_value_all_cb(void* data, void* value)
+static void _eina_test_promise_value_all_cb(void* data, void* value, 
Eina_Promise* promise EINA_UNUSED)
 {
   Eina_Iterator** iterator = value;
   int *i, *j;
@@ -178,9 +178,8 @@ static void cancel_callback(void* data, Eina_Promise_Owner* 
promise EINA_UNUSED)
    *(Eina_Bool*)data = EINA_TRUE;
 }
 
-static void _cancel_promise_callback(void* data EINA_UNUSED, Eina_Error const* 
value)
+static void _cancel_promise_callback(void* data EINA_UNUSED, Eina_Error error, 
Eina_Promise* promise EINA_UNUSED)
 {
-   ck_assert(!!value);
    *(Eina_Bool*)data = EINA_TRUE;
 }
 
@@ -207,7 +206,7 @@ START_TEST(eina_test_promise_cancel_promise)
 }
 END_TEST
 
-void progress_callback(void* data, void* value)
+void progress_callback(void* data, void* value, Eina_Promise* promise 
EINA_UNUSED)
 {
    int* i = value;
    ck_assert(*i == 1);
@@ -285,13 +284,13 @@ START_TEST(eina_test_promise_progress_notify2)
 END_TEST
 
 static void
-_eina_promise_progress_notify_fulfilled(void* data, void* value EINA_UNUSED)
+_eina_promise_progress_notify_fulfilled(void* data, void* value EINA_UNUSED, 
Eina_Promise* promise EINA_UNUSED)
 {
   *(Eina_Bool*)data = EINA_TRUE;
 }
 
 static void
-_eina_promise_progress_notify_error(void* data EINA_UNUSED, Eina_Error const* 
error EINA_UNUSED)
+_eina_promise_progress_notify_error(void* data EINA_UNUSED, Eina_Error error 
EINA_UNUSED, Eina_Promise* promise EINA_UNUSED)
 {
   ck_assert(EINA_FALSE);
 }

-- 


Reply via email to