summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-06-10 22:32:07 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-06-11 10:40:27 -0300
commit949af55947407de97165dab25814ea63045a28e7 (patch)
tree62edc5815dac8905911cad4cda097fe330b28641
parentf6d20c839ef61e1a21961c18045ea0eb7ccdb835 (diff)
eina: Add support for eina_safepointer in promises
-rw-r--r--src/lib/ecore/ecore_thread_promise.c46
-rw-r--r--src/lib/eina/eina_main.c6
-rw-r--r--src/lib/eina/eina_promise.c163
-rw-r--r--src/lib/eina/eina_promise.h57
-rw-r--r--src/tests/eina/eina_test_promise.c4
5 files changed, 166 insertions, 110 deletions
diff --git a/src/lib/ecore/ecore_thread_promise.c b/src/lib/ecore/ecore_thread_promise.c
index 5e4fa112f2..9531978c70 100644
--- a/src/lib/ecore/ecore_thread_promise.c
+++ b/src/lib/ecore/ecore_thread_promise.c
@@ -20,10 +20,12 @@ typedef struct _Ecore_Thread_Data _Ecore_Thread_Data;
20 20
21struct _Ecore_Thread_Promise_Owner 21struct _Ecore_Thread_Promise_Owner
22{ 22{
23 Eina_Promise_Owner owner_vtable; 23 Eina_Promise_Owner_VTable owner_vtable;
24 Eina_Promise_Owner* eina_owner; 24 Eina_Promise_Owner* eina_owner;
25 Eina_Promise promise_vtable; 25 Eina_Promise_VTable promise_vtable;
26 Eina_Promise* eina_promise; 26 Eina_Promise* eina_promise;
27 Eina_Promise_Owner* owner_pointer;
28 Eina_Promise* promise_pointer;
27 _Ecore_Thread_Data thread_callback_data; 29 _Ecore_Thread_Data thread_callback_data;
28 int ref_count; 30 int ref_count;
29 int then_count; 31 int then_count;
@@ -40,9 +42,9 @@ static void _ecore_promise_ref_update(_Ecore_Thread_Promise_Owner* p)
40 } 42 }
41 if(!p->ref_count) 43 if(!p->ref_count)
42 { 44 {
43 p->eina_promise->unref(p->eina_promise); 45 eina_promise_unref(p->eina_promise);
44 if (!p->then_count) // Whether we still own the initial eina_promise ref 46 if (!p->then_count) // Whether we still own the initial eina_promise ref
45 p->eina_promise->unref(p->eina_promise); 47 eina_promise_unref(p->eina_promise);
46 p->eina_promise = NULL; 48 p->eina_promise = NULL;
47 p->eina_owner = NULL; 49 p->eina_owner = NULL;
48 p->thread_callback_data.thread = NULL; 50 p->thread_callback_data.thread = NULL;
@@ -83,7 +85,7 @@ static void
83_ecore_promise_thread_blocking(void* data, Ecore_Thread* thread EINA_UNUSED) 85_ecore_promise_thread_blocking(void* data, Ecore_Thread* thread EINA_UNUSED)
84{ 86{
85 _Ecore_Thread_Promise_Owner* promise = data; 87 _Ecore_Thread_Promise_Owner* promise = data;
86 (promise->thread_callback_data.func_blocking)(promise->thread_callback_data.data, &promise->owner_vtable, thread); 88 (promise->thread_callback_data.func_blocking)(promise->thread_callback_data.data, promise->owner_pointer, thread);
87} 89}
88 90
89static void _ecore_promise_thread_notify(void* data, Ecore_Thread* thread EINA_UNUSED, void* msg_data) 91static void _ecore_promise_thread_notify(void* data, Ecore_Thread* thread EINA_UNUSED, void* msg_data)
@@ -95,7 +97,7 @@ static void _ecore_promise_thread_notify(void* data, Ecore_Thread* thread EINA_U
95static void _ecore_promise_cancel_cb(void* data, Eina_Promise_Owner* promise EINA_UNUSED) 97static void _ecore_promise_cancel_cb(void* data, Eina_Promise_Owner* promise EINA_UNUSED)
96{ 98{
97 _Ecore_Thread_Promise_Owner* priv = data; 99 _Ecore_Thread_Promise_Owner* priv = data;
98 (priv->thread_callback_data.func_cancel)(priv->thread_callback_data.data, &priv->owner_vtable, 100 (priv->thread_callback_data.func_cancel)(priv->thread_callback_data.data, priv->owner_pointer,
99 priv->thread_callback_data.thread); 101 priv->thread_callback_data.thread);
100} 102}
101 103
@@ -110,23 +112,23 @@ static void _ecore_promise_thread_cancel(void* data, Ecore_Thread* thread EINA_U
110 112
111static void _ecore_promise_owner_value_set(_Ecore_Thread_Promise_Owner* promise, void* data, Eina_Promise_Free_Cb free) 113static void _ecore_promise_owner_value_set(_Ecore_Thread_Promise_Owner* promise, void* data, Eina_Promise_Free_Cb free)
112{ 114{
113 promise->eina_owner->value_set(promise->eina_owner, data, free); 115 eina_promise_owner_value_set(promise->eina_owner, data, free);
114} 116}
115static void _ecore_promise_owner_error_set(_Ecore_Thread_Promise_Owner* promise, Eina_Error error) 117static void _ecore_promise_owner_error_set(_Ecore_Thread_Promise_Owner* promise, Eina_Error error)
116{ 118{
117 promise->eina_owner->error_set(promise->eina_owner, error); 119 eina_promise_owner_error_set(promise->eina_owner, error);
118} 120}
119static Eina_Bool _ecore_promise_owner_pending_is(_Ecore_Thread_Promise_Owner const* promise) 121static Eina_Bool _ecore_promise_owner_pending_is(_Ecore_Thread_Promise_Owner const* promise)
120{ 122{
121 return promise->eina_owner->pending_is(promise->eina_owner); 123 return eina_promise_owner_pending_is(promise->eina_owner);
122} 124}
123static Eina_Bool _ecore_promise_owner_cancelled_is(_Ecore_Thread_Promise_Owner const* promise) 125static Eina_Bool _ecore_promise_owner_cancelled_is(_Ecore_Thread_Promise_Owner const* promise)
124{ 126{
125 return promise->eina_owner->cancelled_is(promise->eina_owner); 127 return eina_promise_owner_cancelled_is(promise->eina_owner);
126} 128}
127static Eina_Promise* _ecore_thread_promise_owner_promise_get(_Ecore_Thread_Promise_Owner* promise) 129static Eina_Promise* _ecore_thread_promise_owner_promise_get(_Ecore_Thread_Promise_Owner* promise)
128{ 130{
129 return &promise->promise_vtable; 131 return promise->promise_pointer;
130} 132}
131static void _ecore_thread_promise_owner_progress(_Ecore_Thread_Promise_Owner* promise, void* data) 133static void _ecore_thread_promise_owner_progress(_Ecore_Thread_Promise_Owner* promise, void* data)
132{ 134{
@@ -136,42 +138,42 @@ static void _ecore_thread_promise_owner_progress_notify(_Ecore_Thread_Promise_Ow
136 Eina_Promise_Progress_Notify_Cb progress_cb, 138 Eina_Promise_Progress_Notify_Cb progress_cb,
137 void* data, Eina_Promise_Free_Cb free_cb) 139 void* data, Eina_Promise_Free_Cb free_cb)
138{ 140{
139 promise->eina_owner->progress_notify(promise->eina_owner, progress_cb, data, free_cb); 141 eina_promise_owner_progress_notify(promise->eina_owner, progress_cb, data, free_cb);
140} 142}
141 143
142static void _ecore_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback, 144static void _ecore_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback,
143 Eina_Promise_Error_Cb error_cb, void* data) 145 Eina_Promise_Error_Cb error_cb, void* data)
144{ 146{
145 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); 147 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
146 v->eina_promise->then(v->eina_promise, callback, error_cb, data); 148 eina_promise_then(v->eina_promise, callback, error_cb, data);
147 v->ref_count++; 149 v->ref_count++;
148 v->then_count++; 150 v->then_count++;
149} 151}
150static void* _ecore_promise_value_get(Eina_Promise const* promise) 152static void* _ecore_promise_value_get(Eina_Promise const* promise)
151{ 153{
152 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); 154 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
153 return v->eina_promise->value_get(v->eina_promise); 155 return eina_promise_value_get(v->eina_promise);
154} 156}
155static Eina_Error _ecore_promise_error_get(Eina_Promise const* promise) 157static Eina_Error _ecore_promise_error_get(Eina_Promise const* promise)
156{ 158{
157 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); 159 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
158 return v->eina_promise->error_get(v->eina_promise); 160 return eina_promise_error_get(v->eina_promise);
159} 161}
160static Eina_Bool _ecore_promise_pending_is(Eina_Promise const* promise) 162static Eina_Bool _ecore_promise_pending_is(Eina_Promise const* promise)
161{ 163{
162 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); 164 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
163 return v->eina_promise->pending_is(v->eina_promise); 165 return eina_promise_pending_is(v->eina_promise);
164} 166}
165static void _ecore_promise_progress_cb_add(Eina_Promise const* promise, Eina_Promise_Progress_Cb callback, void* data, 167static void _ecore_promise_progress_cb_add(Eina_Promise const* promise, Eina_Promise_Progress_Cb callback, void* data,
166 Eina_Promise_Free_Cb free_cb) 168 Eina_Promise_Free_Cb free_cb)
167{ 169{
168 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); 170 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
169 v->eina_promise->progress_cb_add(v->eina_promise, callback, data, free_cb); 171 eina_promise_progress_cb_add(v->eina_promise, callback, data, free_cb);
170} 172}
171static void _ecore_promise_cancel(Eina_Promise const* promise) 173static void _ecore_promise_cancel(Eina_Promise const* promise)
172{ 174{
173 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise); 175 _Ecore_Thread_Promise_Owner* v = ECORE_PROMISE_GET_OWNER(promise);
174 v->eina_promise->cancel(v->eina_promise); 176 eina_promise_cancel(v->eina_promise);
175} 177}
176static void _ecore_promise_ref(Eina_Promise const* promise) 178static void _ecore_promise_ref(Eina_Promise const* promise)
177{ 179{
@@ -204,6 +206,7 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
204 priv->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(&_ecore_thread_promise_owner_progress); 206 priv->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(&_ecore_thread_promise_owner_progress);
205 priv->owner_vtable.progress_notify = EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(&_ecore_thread_promise_owner_progress_notify); 207 priv->owner_vtable.progress_notify = EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(&_ecore_thread_promise_owner_progress_notify);
206 EINA_MAGIC_SET(&priv->owner_vtable, EINA_MAGIC_PROMISE_OWNER); 208 EINA_MAGIC_SET(&priv->owner_vtable, EINA_MAGIC_PROMISE_OWNER);
209 priv->owner_pointer = eina_promise_owner_override(&priv->owner_vtable);
207 210
208 priv->promise_vtable.then = EINA_FUNC_PROMISE_THEN(&_ecore_promise_then); 211 priv->promise_vtable.then = EINA_FUNC_PROMISE_THEN(&_ecore_promise_then);
209 priv->promise_vtable.value_get = EINA_FUNC_PROMISE_VALUE_GET(&_ecore_promise_value_get); 212 priv->promise_vtable.value_get = EINA_FUNC_PROMISE_VALUE_GET(&_ecore_promise_value_get);
@@ -214,14 +217,15 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
214 priv->promise_vtable.ref = EINA_FUNC_PROMISE_REF(&_ecore_promise_ref); 217 priv->promise_vtable.ref = EINA_FUNC_PROMISE_REF(&_ecore_promise_ref);
215 priv->promise_vtable.unref = EINA_FUNC_PROMISE_UNREF(&_ecore_promise_unref); 218 priv->promise_vtable.unref = EINA_FUNC_PROMISE_UNREF(&_ecore_promise_unref);
216 EINA_MAGIC_SET(&priv->promise_vtable, EINA_MAGIC_PROMISE); 219 EINA_MAGIC_SET(&priv->promise_vtable, EINA_MAGIC_PROMISE);
220 priv->promise_pointer = eina_promise_override(&priv->promise_vtable);
217 221
218 priv->thread_callback_data.data = data; 222 priv->thread_callback_data.data = data;
219 priv->thread_callback_data.func_blocking = func_blocking; 223 priv->thread_callback_data.func_blocking = func_blocking;
220 priv->thread_callback_data.func_cancel = func_cancel; 224 priv->thread_callback_data.func_cancel = func_cancel;
221 eina_promise_owner_default_manual_then_set(priv->eina_owner, EINA_TRUE); 225 eina_promise_owner_default_manual_then_set(priv->eina_owner, EINA_TRUE);
222 226
223 priv->eina_promise = priv->eina_owner->promise_get(priv->eina_owner); 227 priv->eina_promise = eina_promise_owner_promise_get(priv->eina_owner);
224 priv->eina_promise->ref(priv->eina_promise); 228 eina_promise_ref(priv->eina_promise);
225 priv->ref_count = 0; 229 priv->ref_count = 0;
226 priv->then_count = 0; 230 priv->then_count = 0;
227 231
@@ -232,6 +236,6 @@ Ecore_Thread* ecore_thread_promise_run(Ecore_Thread_Promise_Cb func_blocking,
232 &_ecore_promise_thread_end, &_ecore_promise_thread_cancel, priv, 236 &_ecore_promise_thread_end, &_ecore_promise_thread_cancel, priv,
233 EINA_FALSE); 237 EINA_FALSE);
234 if(promise) 238 if(promise)
235 *promise = &priv->promise_vtable; 239 *promise = priv->promise_pointer;
236 return priv->thread_callback_data.thread; 240 return priv->thread_callback_data.thread;
237} 241}
diff --git a/src/lib/eina/eina_main.c b/src/lib/eina/eina_main.c
index 4cdb4068a3..7238002eb3 100644
--- a/src/lib/eina/eina_main.c
+++ b/src/lib/eina/eina_main.c
@@ -154,8 +154,8 @@ EAPI Eina_Inlist *_eina_tracking = NULL;
154 S(cpu); 154 S(cpu);
155 S(thread_queue); 155 S(thread_queue);
156 S(rbtree); 156 S(rbtree);
157 S(promise);
158 S(safepointer); 157 S(safepointer);
158 S(promise);
159/* no model for now 159/* no model for now
160 S(model); 160 S(model);
161 */ 161 */
@@ -203,8 +203,8 @@ static const struct eina_desc_setup _eina_desc_setup[] = {
203 S(cpu), 203 S(cpu),
204 S(thread_queue), 204 S(thread_queue),
205 S(rbtree), 205 S(rbtree),
206 S(promise), 206 S(safepointer),
207 S(safepointer) 207 S(promise)
208/* no model for now 208/* no model for now
209 S(model) 209 S(model)
210 */ 210 */
diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c
index 1006f845ec..7664020b34 100644
--- a/src/lib/eina/eina_promise.c
+++ b/src/lib/eina/eina_promise.c
@@ -27,6 +27,9 @@ static int _eina_promise_log_dom = -1;
27#define EINA_MAGIC_CHECK_PROMISE_OWNER(promise) \ 27#define EINA_MAGIC_CHECK_PROMISE_OWNER(promise) \
28 do {if(!EINA_MAGIC_CHECK(promise, EINA_MAGIC_PROMISE_OWNER)) \ 28 do {if(!EINA_MAGIC_CHECK(promise, EINA_MAGIC_PROMISE_OWNER)) \
29 {EINA_MAGIC_FAIL(promise, EINA_MAGIC_PROMISE_OWNER);} } while(0) 29 {EINA_MAGIC_FAIL(promise, EINA_MAGIC_PROMISE_OWNER);} } while(0)
30#define EINA_PROMISE_SAFE_GET_OR_RETURN(x, y, v) \
31 x = eina_safepointer_get((Eina_Safepointer const*)y); \
32 if(!x) return v
30 33
31typedef struct _Eina_Promise_Then_Cb _Eina_Promise_Then_Cb; 34typedef struct _Eina_Promise_Then_Cb _Eina_Promise_Then_Cb;
32typedef struct _Eina_Promise_Progress_Cb _Eina_Promise_Progress_Cb; 35typedef struct _Eina_Promise_Progress_Cb _Eina_Promise_Progress_Cb;
@@ -75,7 +78,7 @@ struct _Eina_Promise_Owner_Progress_Notify_Data
75 78
76struct _Eina_Promise_Default 79struct _Eina_Promise_Default
77{ 80{
78 Eina_Promise vtable; 81 Eina_Promise_VTable vtable;
79 Eina_Error error; 82 Eina_Error error;
80 size_t value_size; 83 size_t value_size;
81 84
@@ -84,6 +87,7 @@ struct _Eina_Promise_Default
84 Eina_Inlist *cancel_callbacks; 87 Eina_Inlist *cancel_callbacks;
85 Eina_Inlist *progress_notify_callbacks; 88 Eina_Inlist *progress_notify_callbacks;
86 Eina_Promise_Free_Cb value_free_cb; 89 Eina_Promise_Free_Cb value_free_cb;
90 Eina_Promise* promise_pointer;
87 91
88 int ref; 92 int ref;
89 93
@@ -97,9 +101,9 @@ struct _Eina_Promise_Default
97 101
98struct _Eina_Promise_Default_Owner 102struct _Eina_Promise_Default_Owner
99{ 103{
100 Eina_Promise_Owner owner_vtable; 104 Eina_Promise_Owner_VTable owner_vtable;
101 _Eina_Promise_Default promise; 105 _Eina_Promise_Default promise;
102 106 Eina_Promise_Owner* owner_pointer;
103 void* pointer_value; 107 void* pointer_value;
104}; 108};
105 109
@@ -290,7 +294,7 @@ _eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback,
290 294
291 EINA_INLIST_FOREACH(promise->promise.progress_notify_callbacks, notify_data) 295 EINA_INLIST_FOREACH(promise->promise.progress_notify_callbacks, notify_data)
292 { 296 {
293 (*notify_data->callback)(notify_data->data, &promise->owner_vtable); 297 (*notify_data->callback)(notify_data->data, promise->owner_pointer);
294 } 298 }
295 _eina_promise_free_callback_list(&promise->promise.progress_notify_callbacks, &free); 299 _eina_promise_free_callback_list(&promise->promise.progress_notify_callbacks, &free);
296 300
@@ -372,7 +376,7 @@ _eina_promise_progress_cb_add(_Eina_Promise_Default* promise, Eina_Promise_Progr
372 promise->progress_callbacks = eina_inlist_append(promise->progress_callbacks, EINA_INLIST_GET(cb)); 376 promise->progress_callbacks = eina_inlist_append(promise->progress_callbacks, EINA_INLIST_GET(cb));
373 EINA_INLIST_FOREACH(owner->promise.progress_notify_callbacks, notify_data) 377 EINA_INLIST_FOREACH(owner->promise.progress_notify_callbacks, notify_data)
374 { 378 {
375 (*notify_data->callback)(notify_data->data, &owner->owner_vtable); 379 (*notify_data->callback)(notify_data->data, owner->owner_pointer);
376 } 380 }
377 _eina_promise_free_callback_list(&owner->promise.progress_notify_callbacks, 381 _eina_promise_free_callback_list(&owner->promise.progress_notify_callbacks,
378 &_eina_promise_free_progress_notify_callback_node); 382 &_eina_promise_free_progress_notify_callback_node);
@@ -417,19 +421,17 @@ _eina_promise_ref_get(_Eina_Promise_Default* p)
417static Eina_Promise * 421static Eina_Promise *
418_eina_promise_owner_promise_get(_Eina_Promise_Default_Owner* p) 422_eina_promise_owner_promise_get(_Eina_Promise_Default_Owner* p)
419{ 423{
420 return &p->promise.vtable; 424 return p->promise.promise_pointer;
421} 425}
422 426
423void 427EAPI void
424eina_promise_owner_default_cancel_cb_add(Eina_Promise_Owner* p, 428eina_promise_owner_default_cancel_cb_add(Eina_Promise_Owner* p,
425 Eina_Promise_Default_Cancel_Cb callback, void* data, 429 Eina_Promise_Default_Cancel_Cb callback, void* data,
426 Eina_Promise_Free_Cb free_cb) 430 Eina_Promise_Free_Cb free_cb)
427{ 431{
428 _Eina_Promise_Default_Owner *promise; 432 _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, p, );
429 _Eina_Promise_Cancel_Cb *cb; 433 _Eina_Promise_Cancel_Cb *cb;
430 434
431 promise = (_Eina_Promise_Default_Owner *)p;
432
433 cb = malloc(sizeof(struct _Eina_Promise_Cancel_Cb)); 435 cb = malloc(sizeof(struct _Eina_Promise_Cancel_Cb));
434 436
435 cb->callback = callback; 437 cb->callback = callback;
@@ -486,6 +488,7 @@ static void eina_promise_add_internal(_Eina_Promise_Default_Owner* p)
486 488
487 p->promise.is_first_then = EINA_TRUE; 489 p->promise.is_first_then = EINA_TRUE;
488 p->promise.ref = 1; 490 p->promise.ref = 1;
491 p->promise.promise_pointer = eina_promise_override(&p->promise.vtable);
489 492
490 p->owner_vtable.version = EINA_PROMISE_VERSION; 493 p->owner_vtable.version = EINA_PROMISE_VERSION;
491 p->owner_vtable.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(_eina_promise_owner_value_set); 494 p->owner_vtable.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(_eina_promise_owner_value_set);
@@ -496,6 +499,7 @@ static void eina_promise_add_internal(_Eina_Promise_Default_Owner* p)
496 p->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(_eina_promise_owner_progress); 499 p->owner_vtable.progress = EINA_FUNC_PROMISE_OWNER_PROGRESS(_eina_promise_owner_progress);
497 p->owner_vtable.progress_notify = EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(_eina_promise_owner_progress_notify); 500 p->owner_vtable.progress_notify = EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(_eina_promise_owner_progress_notify);
498 EINA_MAGIC_SET(&p->owner_vtable, EINA_MAGIC_PROMISE_OWNER); 501 EINA_MAGIC_SET(&p->owner_vtable, EINA_MAGIC_PROMISE_OWNER);
502 p->owner_pointer = eina_promise_owner_override(&p->owner_vtable);
499} 503}
500 504
501EAPI Eina_Promise_Owner * 505EAPI Eina_Promise_Owner *
@@ -504,25 +508,28 @@ eina_promise_add()
504 _Eina_Promise_Default_Owner* p; 508 _Eina_Promise_Default_Owner* p;
505 p = calloc(sizeof(_Eina_Promise_Default_Owner), 1); 509 p = calloc(sizeof(_Eina_Promise_Default_Owner), 1);
506 eina_promise_add_internal(p); 510 eina_promise_add_internal(p);
507 return &p->owner_vtable; 511 return p->owner_pointer;
508} 512}
509 513
510void 514EAPI void
511eina_promise_owner_default_manual_then_set(Eina_Promise_Owner* owner, Eina_Bool is_manual) 515eina_promise_owner_default_manual_then_set(Eina_Promise_Owner* owner, Eina_Bool is_manual)
512{ 516{
513 _Eina_Promise_Default_Owner* p = (_Eina_Promise_Default_Owner*)owner; 517 _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(p, owner, );
518 EINA_MAGIC_CHECK_PROMISE_OWNER(&p->owner_vtable);
514 519
515 p->promise.is_manual_then = is_manual; 520 p->promise.is_manual_then = is_manual;
516} 521}
517 522
518void 523EAPI void
519eina_promise_owner_default_call_then(Eina_Promise_Owner* promise) 524eina_promise_owner_default_call_then(Eina_Promise_Owner* owner)
520{ 525{
521 _Eina_Promise_Default_Owner* owner = (_Eina_Promise_Default_Owner*)promise; 526 _Eina_Promise_Default_Owner* EINA_PROMISE_SAFE_GET_OR_RETURN(p, owner, );
527 EINA_MAGIC_CHECK_PROMISE_OWNER(&p->owner_vtable);
522 528
523 _eina_promise_then_calls(owner); 529 _eina_promise_then_calls(p);
524} 530}
525 531
532// eina_promise_all implementation
526static void 533static void
527_eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED) 534_eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED)
528{ 535{
@@ -538,7 +545,7 @@ _eina_promise_all_compose_then_cb(void *data, void* value EINA_UNUSED)
538 _eina_promise_finish(promise); 545 _eina_promise_finish(promise);
539 } 546 }
540 } 547 }
541 eina_promise_unref(&promise->promise.vtable); 548 eina_promise_unref(promise->promise.promise_pointer);
542} 549}
543 550
544static void 551static void
@@ -553,7 +560,7 @@ _eina_promise_all_compose_error_then_cb(void *data, Eina_Error error)
553 promise->promise.error = error; 560 promise->promise.error = error;
554 _eina_promise_finish(promise); 561 _eina_promise_finish(promise);
555 } 562 }
556 eina_promise_unref(&promise->promise.vtable); 563 eina_promise_unref(promise->promise.promise_pointer);
557} 564}
558 565
559static void 566static void
@@ -572,6 +579,7 @@ _eina_promise_all_free(_Eina_Promise_Iterator* value)
572Eina_Promise * 579Eina_Promise *
573eina_promise_all(Eina_Iterator* it) 580eina_promise_all(Eina_Iterator* it)
574{ 581{
582 Eina_Promise_Owner *safe_promise;
575 _Eina_Promise_Default_Owner *promise; 583 _Eina_Promise_Default_Owner *promise;
576 Eina_Promise* current; 584 Eina_Promise* current;
577 Eina_Array* promises; 585 Eina_Array* promises;
@@ -589,14 +597,12 @@ eina_promise_all(Eina_Iterator* it)
589 597
590 eina_iterator_free(it); 598 eina_iterator_free(it);
591 599
592 promise = (_Eina_Promise_Default_Owner*)eina_promise_add(); 600 promise = eina_safepointer_get((Eina_Safepointer*)(safe_promise = eina_promise_add()));
593 internal_it = malloc(sizeof(_Eina_Promise_Iterator) + 601 internal_it = promise->pointer_value = malloc(sizeof(_Eina_Promise_Iterator) +
594 sizeof(_Eina_Promise_Default_Owner*) * eina_array_count_get(promises)); 602 sizeof(_Eina_Promise_Default_Owner*) * eina_array_count_get(promises));
595 603
596 promise->promise.value_free_cb = (Eina_Promise_Free_Cb)&_eina_promise_all_free; 604 promise->promise.value_free_cb = (Eina_Promise_Free_Cb)&_eina_promise_all_free;
597 605
598 promise->pointer_value = (void*)internal_it;
599
600 _eina_promise_iterator_setup(internal_it, promises); 606 _eina_promise_iterator_setup(internal_it, promises);
601 607
602 cur_promise = internal_it->data.promises; 608 cur_promise = internal_it->data.promises;
@@ -605,13 +611,13 @@ eina_promise_all(Eina_Iterator* it)
605 { 611 {
606 eina_promise_ref(*cur_promise); // We need to keep the value alive until this promise is freed 612 eina_promise_ref(*cur_promise); // We need to keep the value alive until this promise is freed
607 // We need to keep the all promise alive while there are callbacks registered to it 613 // We need to keep the all promise alive while there are callbacks registered to it
608 eina_promise_ref(&promise->promise.vtable); 614 eina_promise_ref(promise->promise.promise_pointer);
609 eina_promise_then(*cur_promise, &_eina_promise_all_compose_then_cb, 615 eina_promise_then(*cur_promise, &_eina_promise_all_compose_then_cb,
610 &_eina_promise_all_compose_error_then_cb, promise); 616 &_eina_promise_all_compose_error_then_cb, promise);
611 } 617 }
612 618
613 eina_array_free(promises); 619 eina_array_free(promises);
614 return &promise->promise.vtable; 620 return promise->promise.promise_pointer;
615} 621}
616 622
617static Eina_Bool 623static Eina_Bool
@@ -686,19 +692,6 @@ _eina_promise_progress_notify_finish(void* data)
686 eina_promise_unref(eina_promise_owner_promise_get(owner)); 692 eina_promise_unref(eina_promise_owner_promise_get(owner));
687} 693}
688 694
689EAPI Eina_Promise*
690eina_promise_progress_notification(Eina_Promise_Owner* promise)
691{
692 Eina_Promise_Owner* owner;
693
694 owner = eina_promise_add();
695
696 eina_promise_owner_progress_notify(promise, &_eina_promise_progress_notify_fulfilled, owner,
697 &_eina_promise_progress_notify_finish);
698
699 return eina_promise_owner_promise_get(owner);
700}
701
702// Race implementation 695// Race implementation
703static void _eina_promise_race_unref(_Eina_Promise_Race* p) 696static void _eina_promise_race_unref(_Eina_Promise_Race* p)
704{ 697{
@@ -721,8 +714,8 @@ _eina_promise_race_compose_then_cb(void *data, void* value EINA_UNUSED)
721 _Eina_Promise_Race* race_promise = info->self; 714 _Eina_Promise_Race* race_promise = info->self;
722 715
723 if (!race_promise->promise_default.promise.has_finished) 716 if (!race_promise->promise_default.promise.has_finished)
724 eina_promise_owner_value_set(&race_promise->promise_default.owner_vtable, value, NULL); 717 eina_promise_owner_value_set(race_promise->promise_default.owner_pointer, value, NULL);
725 eina_promise_unref(&race_promise->promise_default.promise.vtable); 718 eina_promise_unref(race_promise->promise_default.promise.promise_pointer);
726} 719}
727 720
728static void 721static void
@@ -732,8 +725,8 @@ _eina_promise_race_compose_error_then_cb(void *data, Eina_Error error)
732 _Eina_Promise_Race* race_promise = info->self; 725 _Eina_Promise_Race* race_promise = info->self;
733 726
734 if (!race_promise->promise_default.promise.has_finished) 727 if (!race_promise->promise_default.promise.has_finished)
735 eina_promise_owner_error_set(&race_promise->promise_default.owner_vtable, error); 728 eina_promise_owner_error_set(race_promise->promise_default.owner_pointer, error);
736 eina_promise_unref(&race_promise->promise_default.promise.vtable); 729 eina_promise_unref(race_promise->promise_default.promise.promise_pointer);
737} 730}
738 731
739Eina_Promise * 732Eina_Promise *
@@ -771,21 +764,52 @@ eina_promise_race(Eina_Iterator* it)
771 cur_promise->self = promise; 764 cur_promise->self = promise;
772 eina_promise_ref(cur_promise->promise); // We need to keep the value alive until this promise is freed 765 eina_promise_ref(cur_promise->promise); // We need to keep the value alive until this promise is freed
773 // We need to keep the all promise alive while there are callbacks registered to it 766 // We need to keep the all promise alive while there are callbacks registered to it
774 eina_promise_ref(&promise->promise_default.promise.vtable); 767 eina_promise_ref(promise->promise_default.promise.promise_pointer);
775 eina_promise_then(cur_promise->promise, &_eina_promise_race_compose_then_cb, 768 eina_promise_then(cur_promise->promise, &_eina_promise_race_compose_then_cb,
776 &_eina_promise_race_compose_error_then_cb, cur_promise); 769 &_eina_promise_race_compose_error_then_cb, cur_promise);
777 } 770 }
778 771
779 eina_array_free(promises); 772 eina_array_free(promises);
780 return &promise->promise_default.promise.vtable; 773 return promise->promise_default.promise.promise_pointer;
781} 774}
782 775
783// API functions 776// API functions
777EAPI Eina_Promise_Owner* eina_promise_owner_override(Eina_Promise_Owner_VTable* owner)
778{
779 _EINA_PROMISE_NULL_CHECK(owner, NULL);
780 EINA_MAGIC_CHECK_PROMISE_OWNER(owner);
781 Eina_Safepointer const* p = eina_safepointer_register(owner);
782 return (Eina_Promise_Owner*)p;
783}
784
785EAPI Eina_Promise* eina_promise_override(Eina_Promise_VTable* promise)
786{
787 _EINA_PROMISE_NULL_CHECK(promise, NULL);
788 EINA_MAGIC_CHECK_PROMISE(promise);
789 Eina_Safepointer const* p = eina_safepointer_register(promise);
790 return (Eina_Promise*)p;
791}
792
793EAPI Eina_Promise*
794eina_promise_progress_notification(Eina_Promise_Owner* safe_promise)
795{
796 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, NULL);
797 Eina_Promise_Owner* owner;
798
799 owner = eina_promise_add();
800
801 eina_promise_owner_progress_notify(safe_promise, &_eina_promise_progress_notify_fulfilled, owner,
802 &_eina_promise_progress_notify_finish);
803
804 return eina_promise_owner_promise_get(owner);
805}
806
784EAPI void 807EAPI void
785eina_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback, 808eina_promise_then(Eina_Promise* safe_promise, Eina_Promise_Cb callback,
786 Eina_Promise_Error_Cb error_cb, void* data) 809 Eina_Promise_Error_Cb error_cb, void* data)
787{ 810{
788 if(!promise) 811 Eina_Promise_VTable* promise = eina_safepointer_get((void*)safe_promise);
812 if(!safe_promise || !promise)
789 { 813 {
790 if(!error_cb) 814 if(!error_cb)
791 { 815 {
@@ -801,122 +825,137 @@ eina_promise_then(Eina_Promise* promise, Eina_Promise_Cb callback,
801} 825}
802 826
803EAPI void 827EAPI void
804eina_promise_owner_value_set(Eina_Promise_Owner* promise, const void* value, Eina_Promise_Free_Cb free) 828eina_promise_owner_value_set(Eina_Promise_Owner* safe_promise, const void* value, Eina_Promise_Free_Cb free)
805{ 829{
830 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
806 _EINA_PROMISE_NULL_CHECK(promise, ); 831 _EINA_PROMISE_NULL_CHECK(promise, );
807 EINA_MAGIC_CHECK_PROMISE_OWNER(promise); 832 EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
808 promise->value_set(promise, value, free); 833 promise->value_set(promise, value, free);
809} 834}
810 835
811EAPI void 836EAPI void
812eina_promise_owner_error_set(Eina_Promise_Owner* promise, Eina_Error error) 837eina_promise_owner_error_set(Eina_Promise_Owner* safe_promise, Eina_Error error)
813{ 838{
839 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
814 _EINA_PROMISE_NULL_CHECK(promise, ); 840 _EINA_PROMISE_NULL_CHECK(promise, );
815 EINA_MAGIC_CHECK_PROMISE_OWNER(promise); 841 EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
816 promise->error_set(promise, error); 842 promise->error_set(promise, error);
817} 843}
818 844
819EAPI void * 845EAPI void *
820eina_promise_value_get(Eina_Promise const* promise) 846eina_promise_value_get(Eina_Promise const* safe_promise)
821{ 847{
848 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, NULL);
822 _EINA_PROMISE_NULL_CHECK(promise, NULL); 849 _EINA_PROMISE_NULL_CHECK(promise, NULL);
823 EINA_MAGIC_CHECK_PROMISE(promise); 850 EINA_MAGIC_CHECK_PROMISE(promise);
824 return promise->value_get(promise); 851 return promise->value_get(promise);
825} 852}
826 853
827EAPI Eina_Error 854EAPI Eina_Error
828eina_promise_error_get(Eina_Promise const* promise) 855eina_promise_error_get(Eina_Promise const* safe_promise)
829{ 856{
857 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, 0);
830 _EINA_PROMISE_NULL_CHECK(promise, EINA_ERROR_PROMISE_NULL); 858 _EINA_PROMISE_NULL_CHECK(promise, EINA_ERROR_PROMISE_NULL);
831 EINA_MAGIC_CHECK_PROMISE(promise); 859 EINA_MAGIC_CHECK_PROMISE(promise);
832 return promise->error_get(promise); 860 return promise->error_get(promise);
833} 861}
834 862
835EAPI Eina_Bool 863EAPI Eina_Bool
836eina_promise_pending_is(Eina_Promise const* promise) 864eina_promise_pending_is(Eina_Promise const* safe_promise)
837{ 865{
866 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, EINA_FALSE);
838 _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE); 867 _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE);
839 EINA_MAGIC_CHECK_PROMISE(promise); 868 EINA_MAGIC_CHECK_PROMISE(promise);
840 return promise->pending_is(promise); 869 return promise->pending_is(promise);
841} 870}
842 871
843EAPI void 872EAPI void
844eina_promise_progress_cb_add(Eina_Promise* promise, Eina_Promise_Progress_Cb callback, void* data, 873eina_promise_progress_cb_add(Eina_Promise* safe_promise, Eina_Promise_Progress_Cb callback, void* data,
845 Eina_Promise_Free_Cb free_cb) 874 Eina_Promise_Free_Cb free_cb)
846{ 875{
876 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
847 _EINA_PROMISE_NULL_CHECK(promise, ); 877 _EINA_PROMISE_NULL_CHECK(promise, );
848 EINA_MAGIC_CHECK_PROMISE(promise); 878 EINA_MAGIC_CHECK_PROMISE(promise);
849 promise->progress_cb_add(promise, callback, data, free_cb); 879 promise->progress_cb_add(promise, callback, data, free_cb);
850} 880}
851 881
852EAPI void 882EAPI void
853eina_promise_cancel(Eina_Promise* promise) 883eina_promise_cancel(Eina_Promise* safe_promise)
854{ 884{
885 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
855 _EINA_PROMISE_NULL_CHECK(promise, ); 886 _EINA_PROMISE_NULL_CHECK(promise, );
856 EINA_MAGIC_CHECK_PROMISE(promise); 887 EINA_MAGIC_CHECK_PROMISE(promise);
857 promise->cancel(promise); 888 promise->cancel(promise);
858} 889}
859 890
860EAPI void 891EAPI void
861eina_promise_ref(Eina_Promise* promise) 892eina_promise_ref(Eina_Promise* safe_promise)
862{ 893{
894 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
863 _EINA_PROMISE_NULL_CHECK(promise, ); 895 _EINA_PROMISE_NULL_CHECK(promise, );
864 EINA_MAGIC_CHECK_PROMISE(promise); 896 EINA_MAGIC_CHECK_PROMISE(promise);
865 promise->ref(promise); 897 promise->ref(promise);
866} 898}
867 899
868EAPI void 900EAPI void
869eina_promise_unref(Eina_Promise* promise) 901eina_promise_unref(Eina_Promise* safe_promise)
870{ 902{
903 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
871 _EINA_PROMISE_NULL_CHECK(promise, ); 904 _EINA_PROMISE_NULL_CHECK(promise, );
872 EINA_MAGIC_CHECK_PROMISE(promise); 905 EINA_MAGIC_CHECK_PROMISE(promise);
873 promise->unref(promise); 906 promise->unref(promise);
874} 907}
875 908
876EAPI int 909EAPI int
877eina_promise_ref_get(Eina_Promise* promise) 910eina_promise_ref_get(Eina_Promise* safe_promise)
878{ 911{
912 Eina_Promise_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, 0);
879 _EINA_PROMISE_NULL_CHECK(promise, 0); 913 _EINA_PROMISE_NULL_CHECK(promise, 0);
880 EINA_MAGIC_CHECK_PROMISE(promise); 914 EINA_MAGIC_CHECK_PROMISE(promise);
881 return promise->ref_get(promise); 915 return promise->ref_get(promise);
882} 916}
883 917
884EAPI Eina_Promise * 918EAPI Eina_Promise *
885eina_promise_owner_promise_get(Eina_Promise_Owner* promise) 919eina_promise_owner_promise_get(Eina_Promise_Owner* safe_promise)
886{ 920{
921 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, NULL);
887 _EINA_PROMISE_NULL_CHECK(promise, NULL); 922 _EINA_PROMISE_NULL_CHECK(promise, NULL);
888 EINA_MAGIC_CHECK_PROMISE_OWNER(promise); 923 EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
889 return promise->promise_get(promise); 924 return promise->promise_get(promise);
890} 925}
891 926
892EAPI Eina_Bool 927EAPI Eina_Bool
893eina_promise_owner_pending_is(Eina_Promise_Owner const* promise) 928eina_promise_owner_pending_is(Eina_Promise_Owner const* safe_promise)
894{ 929{
930 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, EINA_FALSE);
895 _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE); 931 _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE);
896 EINA_MAGIC_CHECK_PROMISE_OWNER(promise); 932 EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
897 return promise->pending_is(promise); 933 return promise->pending_is(promise);
898} 934}
899 935
900EAPI Eina_Bool 936EAPI Eina_Bool
901eina_promise_owner_cancelled_is(Eina_Promise_Owner const* promise) 937eina_promise_owner_cancelled_is(Eina_Promise_Owner const* safe_promise)
902{ 938{
939 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, EINA_FALSE);
903 _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE); 940 _EINA_PROMISE_NULL_CHECK(promise, EINA_FALSE);
904 EINA_MAGIC_CHECK_PROMISE_OWNER(promise); 941 EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
905 return promise->cancelled_is(promise); 942 return promise->cancelled_is(promise);
906} 943}
907 944
908EAPI void 945EAPI void
909eina_promise_owner_progress(Eina_Promise_Owner const* promise, void* progress) 946eina_promise_owner_progress(Eina_Promise_Owner const* safe_promise, void* progress)
910{ 947{
948 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
911 _EINA_PROMISE_NULL_CHECK(promise, ); 949 _EINA_PROMISE_NULL_CHECK(promise, );
912 EINA_MAGIC_CHECK_PROMISE_OWNER(promise); 950 EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
913 promise->progress(promise, progress); 951 promise->progress(promise, progress);
914} 952}
915 953
916EAPI void 954EAPI void
917eina_promise_owner_progress_notify(Eina_Promise_Owner* promise, Eina_Promise_Progress_Notify_Cb progress_cb, 955eina_promise_owner_progress_notify(Eina_Promise_Owner* safe_promise, Eina_Promise_Progress_Notify_Cb progress_cb,
918 void* data, Eina_Promise_Free_Cb free_cb) 956 void* data, Eina_Promise_Free_Cb free_cb)
919{ 957{
958 Eina_Promise_Owner_VTable* EINA_PROMISE_SAFE_GET_OR_RETURN(promise, safe_promise, );
920 _EINA_PROMISE_NULL_CHECK(promise, ); 959 _EINA_PROMISE_NULL_CHECK(promise, );
921 EINA_MAGIC_CHECK_PROMISE_OWNER(promise); 960 EINA_MAGIC_CHECK_PROMISE_OWNER(promise);
922 promise->progress_notify(promise, progress_cb, data, free_cb); 961 promise->progress_notify(promise, progress_cb, data, free_cb);
diff --git a/src/lib/eina/eina_promise.h b/src/lib/eina/eina_promise.h
index f0120467ea..0d6f779a34 100644
--- a/src/lib/eina/eina_promise.h
+++ b/src/lib/eina/eina_promise.h
@@ -3,20 +3,27 @@
3 3
4#ifdef EFL_BETA_API_SUPPORT 4#ifdef EFL_BETA_API_SUPPORT
5 5
6struct _Eina_Promise;
7struct _Eina_Promise_Default;
8
9/* 6/*
10 * @def Eina_Promise 7 * @def Eina_Promise
11 */ 8 */
12typedef struct _Eina_Promise Eina_Promise; 9typedef struct _Eina_Promise Eina_Promise;
13 10
14/* 11/*
12 * @def Eina_Promise_VTable
13 */
14typedef struct _Eina_Promise_VTable Eina_Promise_VTable;
15
16/*
15 * @def Eina_Promise 17 * @def Eina_Promise
16 */ 18 */
17typedef struct _Eina_Promise_Owner Eina_Promise_Owner; 19typedef struct _Eina_Promise_Owner Eina_Promise_Owner;
18 20
19/* 21/*
22 * @def Eina_Promise
23 */
24typedef struct _Eina_Promise_Owner_VTable Eina_Promise_Owner_VTable;
25
26/*
20 * @brief Callback type for freeing Promise value and void* pointer data for callbacks 27 * @brief Callback type for freeing Promise value and void* pointer data for callbacks
21 */ 28 */
22typedef void(*Eina_Promise_Free_Cb)(void* value); 29typedef void(*Eina_Promise_Free_Cb)(void* value);
@@ -44,7 +51,7 @@ typedef void(*Eina_Promise_Progress_Cb)(void* data, void* value);
44/* 51/*
45 * @brief Function callback type for then function override 52 * @brief Function callback type for then function override
46 */ 53 */
47typedef void(*Eina_Promise_Then_Cb)(Eina_Promise* promise, Eina_Promise_Cb callback, 54typedef void(*Eina_Promise_Then_Cb)(Eina_Promise_VTable* promise, Eina_Promise_Cb callback,
48 Eina_Promise_Error_Cb error_cb, void* data); 55 Eina_Promise_Error_Cb error_cb, void* data);
49 56
50#define EINA_FUNC_PROMISE_THEN(Function) ((Eina_Promise_Then_Cb)Function) 57#define EINA_FUNC_PROMISE_THEN(Function) ((Eina_Promise_Then_Cb)Function)
@@ -52,28 +59,28 @@ typedef void(*Eina_Promise_Then_Cb)(Eina_Promise* promise, Eina_Promise_Cb callb
52/* 59/*
53 * @brief Function callback type for promise's value_get function override 60 * @brief Function callback type for promise's value_get function override
54 */ 61 */
55typedef void*(*Eina_Promise_Value_Get_Cb)(Eina_Promise const* promise); 62typedef void*(*Eina_Promise_Value_Get_Cb)(Eina_Promise_VTable const* promise);
56 63
57#define EINA_FUNC_PROMISE_VALUE_GET(Function) ((Eina_Promise_Value_Get_Cb)Function) 64#define EINA_FUNC_PROMISE_VALUE_GET(Function) ((Eina_Promise_Value_Get_Cb)Function)
58 65
59/* 66/*
60 * @brief Function callback type for promise's error_get function override 67 * @brief Function callback type for promise's error_get function override
61 */ 68 */
62typedef Eina_Error(*Eina_Promise_Error_Get_Cb)(Eina_Promise const* promise); 69typedef Eina_Error(*Eina_Promise_Error_Get_Cb)(Eina_Promise_VTable const* promise);
63 70
64#define EINA_FUNC_PROMISE_ERROR_GET(Function) ((Eina_Promise_Error_Get_Cb)Function) 71#define EINA_FUNC_PROMISE_ERROR_GET(Function) ((Eina_Promise_Error_Get_Cb)Function)
65 72
66/* 73/*
67 * @brief Function callback type for promise's pending function override 74 * @brief Function callback type for promise's pending function override
68 */ 75 */
69typedef Eina_Bool(*Eina_Promise_Pending_Is_Cb)(Eina_Promise const* promise); 76typedef Eina_Bool(*Eina_Promise_Pending_Is_Cb)(Eina_Promise_VTable const* promise);
70 77
71#define EINA_FUNC_PROMISE_PENDING_IS(Function) ((Eina_Promise_Pending_Is_Cb)Function) 78#define EINA_FUNC_PROMISE_PENDING_IS(Function) ((Eina_Promise_Pending_Is_Cb)Function)
72 79
73/* 80/*
74 * @brief Function callback type for promise's progress add function override 81 * @brief Function callback type for promise's progress add function override
75 */ 82 */
76typedef void(*Eina_Promise_Progress_Cb_Add_Cb)(Eina_Promise* promise, Eina_Promise_Progress_Cb callback, void* data 83typedef void(*Eina_Promise_Progress_Cb_Add_Cb)(Eina_Promise_VTable* promise, Eina_Promise_Progress_Cb callback, void* data
77 , Eina_Promise_Free_Cb free_cb); 84 , Eina_Promise_Free_Cb free_cb);
78 85
79#define EINA_FUNC_PROMISE_PROGRESS_CB_ADD(Function) ((Eina_Promise_Progress_Cb_Add_Cb)Function) 86#define EINA_FUNC_PROMISE_PROGRESS_CB_ADD(Function) ((Eina_Promise_Progress_Cb_Add_Cb)Function)
@@ -81,91 +88,91 @@ typedef void(*Eina_Promise_Progress_Cb_Add_Cb)(Eina_Promise* promise, Eina_Promi
81/* 88/*
82 * @brief Function callback type for promise's cancel function override 89 * @brief Function callback type for promise's cancel function override
83 */ 90 */
84typedef void(*Eina_Promise_Cancel_Cb)(Eina_Promise* promise); 91typedef void(*Eina_Promise_Cancel_Cb)(Eina_Promise_VTable* promise);
85 92
86#define EINA_FUNC_PROMISE_CANCEL(Function) ((Eina_Promise_Cancel_Cb)Function) 93#define EINA_FUNC_PROMISE_CANCEL(Function) ((Eina_Promise_Cancel_Cb)Function)
87 94
88/* 95/*
89 * @brief Function callback type for promise's ref function override 96 * @brief Function callback type for promise's ref function override
90 */ 97 */
91typedef void(*Eina_Promise_Ref_Cb)(Eina_Promise* promise); 98typedef void(*Eina_Promise_Ref_Cb)(Eina_Promise_VTable* promise);
92 99
93#define EINA_FUNC_PROMISE_REF(Function) ((Eina_Promise_Ref_Cb)Function) 100#define EINA_FUNC_PROMISE_REF(Function) ((Eina_Promise_Ref_Cb)Function)
94 101
95/* 102/*
96 * @brief Function callback type for promise's unref function override 103 * @brief Function callback type for promise's unref function override
97 */ 104 */
98typedef void(*Eina_Promise_Unref_Cb)(Eina_Promise* promise); 105typedef void(*Eina_Promise_Unref_Cb)(Eina_Promise_VTable* promise);
99 106
100#define EINA_FUNC_PROMISE_UNREF(Function) ((Eina_Promise_Unref_Cb)Function) 107#define EINA_FUNC_PROMISE_UNREF(Function) ((Eina_Promise_Unref_Cb)Function)
101 108
102/* 109/*
103 * @brief Function callback type for promise's ref_get function override 110 * @brief Function callback type for promise's ref_get function override
104 */ 111 */
105typedef int(*Eina_Promise_Ref_Get_Cb)(Eina_Promise* promise); 112typedef int(*Eina_Promise_Ref_Get_Cb)(Eina_Promise_VTable* promise);
106 113
107#define EINA_FUNC_PROMISE_REF_GET(Function) ((Eina_Promise_Ref_Get_Cb)Function) 114#define EINA_FUNC_PROMISE_REF_GET(Function) ((Eina_Promise_Ref_Get_Cb)Function)
108 115
109/* 116/*
110 * @brief Function callback type for promise's buffer_get function override 117 * @brief Function callback type for promise's buffer_get function override
111 */ 118 */
112typedef void*(*Eina_Promise_Buffer_Get_Cb)(Eina_Promise* promise); 119typedef void*(*Eina_Promise_Buffer_Get_Cb)(Eina_Promise_VTable* promise);
113 120
114#define EINA_FUNC_PROMISE_BUFFER_GET(Function) ((Eina_Promise_Buffer_Get_Cb)Function) 121#define EINA_FUNC_PROMISE_BUFFER_GET(Function) ((Eina_Promise_Buffer_Get_Cb)Function)
115 122
116/* 123/*
117 * @brief Function callback type for promise owner's buffer_get function override 124 * @brief Function callback type for promise owner's buffer_get function override
118 */ 125 */
119typedef void*(*Eina_Promise_Owner_Buffer_Get_Cb)(Eina_Promise_Owner* promise); 126typedef void*(*Eina_Promise_Owner_Buffer_Get_Cb)(Eina_Promise_Owner_VTable* promise);
120 127
121#define EINA_FUNC_PROMISE_OWNER_BUFFER_GET(Function) ((Eina_Promise_Owner_Buffer_Get_Cb)Function) 128#define EINA_FUNC_PROMISE_OWNER_BUFFER_GET(Function) ((Eina_Promise_Owner_Buffer_Get_Cb)Function)
122 129
123/* 130/*
124 * @brief Function callback type for promise owner's promise_get function override 131 * @brief Function callback type for promise owner's promise_get function override
125 */ 132 */
126typedef void*(*Eina_Promise_Owner_Promise_Get_Cb)(Eina_Promise_Owner const* promise); 133typedef void*(*Eina_Promise_Owner_Promise_Get_Cb)(Eina_Promise_Owner_VTable const* promise);
127 134
128#define EINA_FUNC_PROMISE_OWNER_PROMISE_GET(Function) ((Eina_Promise_Owner_Promise_Get_Cb)Function) 135#define EINA_FUNC_PROMISE_OWNER_PROMISE_GET(Function) ((Eina_Promise_Owner_Promise_Get_Cb)Function)
129 136
130/* 137/*
131 * @brief Function callback type for promise owner's value_set function override 138 * @brief Function callback type for promise owner's value_set function override
132 */ 139 */
133typedef void(*Eina_Promise_Owner_Value_Set_Cb)(Eina_Promise_Owner* promise, const void* data, Eina_Promise_Free_Cb free_fun); 140typedef void(*Eina_Promise_Owner_Value_Set_Cb)(Eina_Promise_Owner_VTable* promise, const void* data, Eina_Promise_Free_Cb free_fun);
134 141
135#define EINA_FUNC_PROMISE_OWNER_VALUE_SET(Function) ((Eina_Promise_Owner_Value_Set_Cb)Function) 142#define EINA_FUNC_PROMISE_OWNER_VALUE_SET(Function) ((Eina_Promise_Owner_Value_Set_Cb)Function)
136 143
137/* 144/*
138 * @brief Function callback type for promise owner's error_set function override 145 * @brief Function callback type for promise owner's error_set function override
139 */ 146 */
140typedef void(*Eina_Promise_Owner_Error_Set_Cb)(Eina_Promise_Owner* promise, Eina_Error error); 147typedef void(*Eina_Promise_Owner_Error_Set_Cb)(Eina_Promise_Owner_VTable* promise, Eina_Error error);
141 148
142#define EINA_FUNC_PROMISE_OWNER_ERROR_SET(Function) ((Eina_Promise_Owner_Error_Set_Cb)Function) 149#define EINA_FUNC_PROMISE_OWNER_ERROR_SET(Function) ((Eina_Promise_Owner_Error_Set_Cb)Function)
143 150
144/* 151/*
145 * @brief Function callback type for promise owner's pending function override 152 * @brief Function callback type for promise owner's pending function override
146 */ 153 */
147typedef Eina_Bool(*Eina_Promise_Owner_Pending_Is_Cb)(Eina_Promise_Owner const* promise); 154typedef Eina_Bool(*Eina_Promise_Owner_Pending_Is_Cb)(Eina_Promise_Owner_VTable const* promise);
148 155
149#define EINA_FUNC_PROMISE_OWNER_PENDING_IS(Function) ((Eina_Promise_Owner_Pending_Is_Cb)Function) 156#define EINA_FUNC_PROMISE_OWNER_PENDING_IS(Function) ((Eina_Promise_Owner_Pending_Is_Cb)Function)
150 157
151/* 158/*
152 * @brief Function callback type for promise owner's cancelled function override 159 * @brief Function callback type for promise owner's cancelled function override
153 */ 160 */
154typedef Eina_Bool(*Eina_Promise_Owner_Cancelled_Is_Cb)(Eina_Promise_Owner const* promise); 161typedef Eina_Bool(*Eina_Promise_Owner_Cancelled_Is_Cb)(Eina_Promise_Owner_VTable const* promise);
155 162
156#define EINA_FUNC_PROMISE_OWNER_CANCELLED_IS(Function) ((Eina_Promise_Owner_Cancelled_Is_Cb)Function) 163#define EINA_FUNC_PROMISE_OWNER_CANCELLED_IS(Function) ((Eina_Promise_Owner_Cancelled_Is_Cb)Function)
157 164
158/* 165/*
159 * @brief Function callback type for promise owner's progress function override 166 * @brief Function callback type for promise owner's progress function override
160 */ 167 */
161typedef Eina_Bool(*Eina_Promise_Owner_Progress_Cb)(Eina_Promise_Owner const* promise, void* progress); 168typedef Eina_Bool(*Eina_Promise_Owner_Progress_Cb)(Eina_Promise_Owner_VTable const* promise, void* progress);
162 169
163#define EINA_FUNC_PROMISE_OWNER_PROGRESS(Function) ((Eina_Promise_Owner_Progress_Cb)Function) 170#define EINA_FUNC_PROMISE_OWNER_PROGRESS(Function) ((Eina_Promise_Owner_Progress_Cb)Function)
164 171
165/* 172/*
166 * @brief Function callback type for promise owner's progress notify registration function override 173 * @brief Function callback type for promise owner's progress notify registration function override
167 */ 174 */
168typedef Eina_Bool(*Eina_Promise_Owner_Progress_Notify_Cb)(Eina_Promise_Owner* promise, 175typedef Eina_Bool(*Eina_Promise_Owner_Progress_Notify_Cb)(Eina_Promise_Owner_VTable* promise,
169 Eina_Promise_Progress_Notify_Cb progress_cb, void* data, Eina_Promise_Free_Cb free_cb); 176 Eina_Promise_Progress_Notify_Cb progress_cb, void* data, Eina_Promise_Free_Cb free_cb);
170 177
171#define EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(Function) ((Eina_Promise_Owner_Progress_Notify_Cb)Function) 178#define EINA_FUNC_PROMISE_OWNER_PROGRESS_NOTIFY(Function) ((Eina_Promise_Owner_Progress_Notify_Cb)Function)
@@ -173,7 +180,7 @@ typedef Eina_Bool(*Eina_Promise_Owner_Progress_Notify_Cb)(Eina_Promise_Owner* pr
173 180
174#define EINA_PROMISE_VERSION 1 181#define EINA_PROMISE_VERSION 1
175 182
176struct _Eina_Promise 183struct _Eina_Promise_VTable
177{ 184{
178 int version; 185 int version;
179 Eina_Promise_Then_Cb then; 186 Eina_Promise_Then_Cb then;
@@ -189,7 +196,7 @@ struct _Eina_Promise
189 EINA_MAGIC; 196 EINA_MAGIC;
190}; 197};
191 198
192struct _Eina_Promise_Owner 199struct _Eina_Promise_Owner_VTable
193{ 200{
194 int version; 201 int version;
195 Eina_Promise_Owner_Value_Set_Cb value_set; 202 Eina_Promise_Owner_Value_Set_Cb value_set;
@@ -203,6 +210,10 @@ struct _Eina_Promise_Owner
203 EINA_MAGIC; 210 EINA_MAGIC;
204}; 211};
205 212
213EAPI Eina_Promise_Owner* eina_promise_owner_override(Eina_Promise_Owner_VTable* owner);
214
215EAPI Eina_Promise* eina_promise_override(Eina_Promise_VTable* owner);
216
206/* 217/*
207 * @brief Appends a callback to be called when the Eina_Promise is 218 * @brief Appends a callback to be called when the Eina_Promise is
208 * finished. 219 * finished.
diff --git a/src/tests/eina/eina_test_promise.c b/src/tests/eina/eina_test_promise.c
index 5c73dba0da..a236aad51f 100644
--- a/src/tests/eina/eina_test_promise.c
+++ b/src/tests/eina/eina_test_promise.c
@@ -269,6 +269,7 @@ START_TEST(eina_test_pointer_promise_manual_then)
269 eina_promise_owner_default_manual_then_set(promise_owner, EINA_TRUE); 269 eina_promise_owner_default_manual_then_set(promise_owner, EINA_TRUE);
270 270
271 promise = eina_promise_owner_promise_get(promise_owner); 271 promise = eina_promise_owner_promise_get(promise_owner);
272 eina_promise_ref(promise);
272 273
273 eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran); 274 eina_promise_then(promise, &_eina_test_promise_cb, NULL, &ran);
274 275
@@ -277,6 +278,7 @@ START_TEST(eina_test_pointer_promise_manual_then)
277 ck_assert(!ran); 278 ck_assert(!ran);
278 279
279 eina_promise_owner_default_call_then(promise_owner); 280 eina_promise_owner_default_call_then(promise_owner);
281 eina_promise_unref(promise);
280 282
281 ck_assert(ran); 283 ck_assert(ran);
282 284
@@ -685,7 +687,7 @@ END_TEST
685void 687void
686eina_test_promise(TCase *tc) 688eina_test_promise(TCase *tc)
687{ 689{
688 /* // pointer */ 690 // pointer
689 tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime); 691 tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime);
690 tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime_all); 692 tcase_add_test(tc, eina_test_pointer_promise_normal_lifetime_all);
691 tcase_add_test(tc, eina_test_pointer_promise_error_set); 693 tcase_add_test(tc, eina_test_pointer_promise_error_set);