summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCedric BAIL <cedric@osg.samsung.com>2018-12-07 12:15:16 +0100
committerXavi Artigas <xavierartigas@yahoo.es>2018-12-07 12:23:11 +0100
commit33c00de365ab8ed2adebd86e5e3dc6091afc0fa9 (patch)
treefe0abdfc084f80f3c2c997f0ccfab2d5d45f3b25
parente6f66e56fdc0989e73fc54809dea5368df68cfab (diff)
eo: make efl_future_then have a data pointer in addition of the object pointer.
Summary: In the case when you have multiple future in flight related to one object, you couldn't use the previous version of efl_future_then. Now all function calls take a void* pointer that allow multiple future to have their private data request data accessible in all the callback. This should not break released API as Eo.h is not released yet and so was efl_future_Eina_FutureXXX_then. Depends on D7332 Reviewers: felipealmeida, segfaultxavi, vitor.sousa, SanghyeonLee, bu5hm4n Reviewed By: segfaultxavi Subscribers: #reviewers, #committers Tags: #efl Maniphest Tasks: T7472 Differential Revision: https://phab.enlightenment.org/D7379
-rw-r--r--src/lib/ecore/efl_io_copier.c14
-rw-r--r--src/lib/ecore_con/efl_net_dialer_http.c8
-rw-r--r--src/lib/ecore_con/efl_net_dialer_ssl.c6
-rw-r--r--src/lib/ecore_con/efl_net_dialer_tcp.c6
-rw-r--r--src/lib/ecore_con/efl_net_dialer_udp.c6
-rw-r--r--src/lib/ecore_con/efl_net_dialer_unix.c6
-rw-r--r--src/lib/ecore_con/efl_net_dialer_websocket.c12
-rw-r--r--src/lib/ecore_con/efl_net_server_windows.c6
-rw-r--r--src/lib/eina/eina_promise_private.h18
-rw-r--r--src/lib/eo/Eo.h19
-rw-r--r--src/lib/eo/eo_base_class.c6
-rw-r--r--src/tests/ecore/efl_app_test_promise.c14
12 files changed, 64 insertions, 57 deletions
diff --git a/src/lib/ecore/efl_io_copier.c b/src/lib/ecore/efl_io_copier.c
index 28f5ab68aa..a03168807c 100644
--- a/src/lib/ecore/efl_io_copier.c
+++ b/src/lib/ecore/efl_io_copier.c
@@ -72,7 +72,7 @@ static void _efl_io_copier_read(Eo *o, Efl_Io_Copier_Data *pd);
72 while (0) 72 while (0)
73 73
74static Eina_Value 74static Eina_Value
75_efl_io_copier_timeout_inactivity_cb(Eo *o, const Eina_Value v) 75_efl_io_copier_timeout_inactivity_cb(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
76{ 76{
77 Eina_Error err = ETIMEDOUT; 77 Eina_Error err = ETIMEDOUT;
78 efl_event_callback_call(o, EFL_IO_COPIER_EVENT_ERROR, &err); 78 efl_event_callback_call(o, EFL_IO_COPIER_EVENT_ERROR, &err);
@@ -86,12 +86,12 @@ _efl_io_copier_timeout_inactivity_reschedule(Eo *o, Efl_Io_Copier_Data *pd)
86 if (pd->timeout_inactivity <= 0.0) return; 86 if (pd->timeout_inactivity <= 0.0) return;
87 87
88 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_inactivity), 88 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_inactivity),
89 .success = _efl_io_copier_timeout_inactivity_cb, 89 .success = _efl_io_copier_timeout_inactivity_cb,
90 .storage = &pd->inactivity_timer); 90 .storage = &pd->inactivity_timer);
91} 91}
92 92
93static Eina_Value 93static Eina_Value
94_efl_io_copier_job(Eo *o, const Eina_Value v) 94_efl_io_copier_job(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
95{ 95{
96 Efl_Io_Copier_Data *pd = efl_data_scope_get(o, MY_CLASS); 96 Efl_Io_Copier_Data *pd = efl_data_scope_get(o, MY_CLASS);
97 uint64_t old_read = pd->progress.read; 97 uint64_t old_read = pd->progress.read;
@@ -138,14 +138,14 @@ _efl_io_copier_job_schedule(Eo *o, Efl_Io_Copier_Data *pd)
138 { 138 {
139 Eina_Value v = EINA_VALUE_EMPTY; 139 Eina_Value v = EINA_VALUE_EMPTY;
140 140
141 v = _efl_io_copier_job(o, v); 141 v = _efl_io_copier_job(o, NULL, v);
142 eina_value_flush(&v); 142 eina_value_flush(&v);
143 } 143 }
144 else 144 else
145 { 145 {
146 efl_future_then(o, efl_loop_job(efl_loop_get(o)), 146 efl_future_then(o, efl_loop_job(efl_loop_get(o)),
147 .success = _efl_io_copier_job, 147 .success = _efl_io_copier_job,
148 .storage = &pd->job); 148 .storage = &pd->job);
149 } 149 }
150} 150}
151 151
diff --git a/src/lib/ecore_con/efl_net_dialer_http.c b/src/lib/ecore_con/efl_net_dialer_http.c
index bc004ba264..8bfe967c32 100644
--- a/src/lib/ecore_con/efl_net_dialer_http.c
+++ b/src/lib/ecore_con/efl_net_dialer_http.c
@@ -1717,7 +1717,7 @@ _efl_net_dialer_http_efl_io_writer_can_write_set(Eo *o, Efl_Net_Dialer_Http_Data
1717 efl_event_callback_call(o, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL); 1717 efl_event_callback_call(o, EFL_IO_WRITER_EVENT_CAN_WRITE_CHANGED, NULL);
1718} 1718}
1719 1719
1720static Eina_Value _efl_net_dialer_http_pending_close(Eo *o, Eina_Value value); 1720static Eina_Value _efl_net_dialer_http_pending_close(Eo *o, void *data, Eina_Value value);
1721 1721
1722EOLIAN static Eina_Error 1722EOLIAN static Eina_Error
1723_efl_net_dialer_http_efl_io_closer_close(Eo *o, Efl_Net_Dialer_Http_Data *pd) 1723_efl_net_dialer_http_efl_io_closer_close(Eo *o, Efl_Net_Dialer_Http_Data *pd)
@@ -1733,8 +1733,8 @@ _efl_net_dialer_http_efl_io_closer_close(Eo *o, Efl_Net_Dialer_Http_Data *pd)
1733 if ((!pd->pending_close) && (pd->easy)) 1733 if ((!pd->pending_close) && (pd->easy))
1734 { 1734 {
1735 efl_future_then(o, efl_loop_job(efl_loop_get(o)), 1735 efl_future_then(o, efl_loop_job(efl_loop_get(o)),
1736 .success = _efl_net_dialer_http_pending_close, 1736 .success = _efl_net_dialer_http_pending_close,
1737 .storage = &pd->pending_close); 1737 .storage = &pd->pending_close);
1738 DBG("dialer=%p closed from CURL callback, schedule close job=%p", o, pd->pending_close); 1738 DBG("dialer=%p closed from CURL callback, schedule close job=%p", o, pd->pending_close);
1739 } 1739 }
1740 return 0; 1740 return 0;
@@ -1766,7 +1766,7 @@ _efl_net_dialer_http_efl_io_closer_close(Eo *o, Efl_Net_Dialer_Http_Data *pd)
1766} 1766}
1767 1767
1768static Eina_Value 1768static Eina_Value
1769_efl_net_dialer_http_pending_close(Eo *o, const Eina_Value value EINA_UNUSED) 1769_efl_net_dialer_http_pending_close(Eo *o, void *data EINA_UNUSED, const Eina_Value value EINA_UNUSED)
1770{ 1770{
1771 Efl_Net_Dialer_Http_Data *pd = efl_data_scope_get(o, MY_CLASS); 1771 Efl_Net_Dialer_Http_Data *pd = efl_data_scope_get(o, MY_CLASS);
1772 1772
diff --git a/src/lib/ecore_con/efl_net_dialer_ssl.c b/src/lib/ecore_con/efl_net_dialer_ssl.c
index d3e83f69c0..78b587973a 100644
--- a/src/lib/ecore_con/efl_net_dialer_ssl.c
+++ b/src/lib/ecore_con/efl_net_dialer_ssl.c
@@ -128,7 +128,7 @@ _efl_net_dialer_ssl_ssl_context_get(const Eo *o EINA_UNUSED, Efl_Net_Dialer_Ssl_
128} 128}
129 129
130static Eina_Value 130static Eina_Value
131_efl_net_dialer_ssl_connect_timeout(Eo *o, const Eina_Value v) 131_efl_net_dialer_ssl_connect_timeout(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
132{ 132{
133 Eina_Error err = ETIMEDOUT; 133 Eina_Error err = ETIMEDOUT;
134 134
@@ -143,8 +143,8 @@ static void
143_timeout_schedule(Eo *o, Efl_Net_Dialer_Ssl_Data *pd, double timeout) 143_timeout_schedule(Eo *o, Efl_Net_Dialer_Ssl_Data *pd, double timeout)
144{ 144{
145 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), timeout), 145 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), timeout),
146 .success = _efl_net_dialer_ssl_connect_timeout, 146 .success = _efl_net_dialer_ssl_connect_timeout,
147 .storage = &pd->connect_timeout); 147 .storage = &pd->connect_timeout);
148} 148}
149 149
150EOLIAN static Eina_Error 150EOLIAN static Eina_Error
diff --git a/src/lib/ecore_con/efl_net_dialer_tcp.c b/src/lib/ecore_con/efl_net_dialer_tcp.c
index 57f5cf93cd..9a7a795faa 100644
--- a/src/lib/ecore_con/efl_net_dialer_tcp.c
+++ b/src/lib/ecore_con/efl_net_dialer_tcp.c
@@ -90,7 +90,7 @@ _efl_net_dialer_tcp_efl_object_destructor(Eo *o, Efl_Net_Dialer_Tcp_Data *pd)
90} 90}
91 91
92static Eina_Value 92static Eina_Value
93_efl_net_dialer_tcp_connect_timeout(Eo *o, const Eina_Value v) 93_efl_net_dialer_tcp_connect_timeout(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
94{ 94{
95 Efl_Net_Dialer_Tcp_Data *pd = efl_data_scope_get(o, MY_CLASS); 95 Efl_Net_Dialer_Tcp_Data *pd = efl_data_scope_get(o, MY_CLASS);
96 Eina_Error err = ETIMEDOUT; 96 Eina_Error err = ETIMEDOUT;
@@ -108,8 +108,8 @@ static void
108_timeout_schedule(Eo *o, Efl_Net_Dialer_Tcp_Data *pd) 108_timeout_schedule(Eo *o, Efl_Net_Dialer_Tcp_Data *pd)
109{ 109{
110 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_dial), 110 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_dial),
111 .success = _efl_net_dialer_tcp_connect_timeout, 111 .success = _efl_net_dialer_tcp_connect_timeout,
112 .storage = &pd->connect.timeout); 112 .storage = &pd->connect.timeout);
113} 113}
114 114
115static void 115static void
diff --git a/src/lib/ecore_con/efl_net_dialer_udp.c b/src/lib/ecore_con/efl_net_dialer_udp.c
index f3e7ef2166..351d077909 100644
--- a/src/lib/ecore_con/efl_net_dialer_udp.c
+++ b/src/lib/ecore_con/efl_net_dialer_udp.c
@@ -82,7 +82,7 @@ _efl_net_dialer_udp_efl_object_destructor(Eo *o, Efl_Net_Dialer_Udp_Data *pd)
82} 82}
83 83
84static Eina_Value 84static Eina_Value
85_efl_net_dialer_udp_resolver_timeout(Eo *o, const Eina_Value v) 85_efl_net_dialer_udp_resolver_timeout(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
86{ 86{
87 Efl_Net_Dialer_Udp_Data *pd = efl_data_scope_get(o, MY_CLASS); 87 Efl_Net_Dialer_Udp_Data *pd = efl_data_scope_get(o, MY_CLASS);
88 Eina_Error err = ETIMEDOUT; 88 Eina_Error err = ETIMEDOUT;
@@ -104,8 +104,8 @@ static void
104_timeout_schedule(Eo *o, Efl_Net_Dialer_Udp_Data *pd) 104_timeout_schedule(Eo *o, Efl_Net_Dialer_Udp_Data *pd)
105{ 105{
106 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_dial), 106 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_dial),
107 .success = _efl_net_dialer_udp_resolver_timeout, 107 .success = _efl_net_dialer_udp_resolver_timeout,
108 .storage = &pd->resolver.timeout); 108 .storage = &pd->resolver.timeout);
109} 109}
110 110
111static Eina_Error 111static Eina_Error
diff --git a/src/lib/ecore_con/efl_net_dialer_unix.c b/src/lib/ecore_con/efl_net_dialer_unix.c
index d644d5d629..95e2b06457 100644
--- a/src/lib/ecore_con/efl_net_dialer_unix.c
+++ b/src/lib/ecore_con/efl_net_dialer_unix.c
@@ -71,7 +71,7 @@ _efl_net_dialer_unix_efl_object_destructor(Eo *o, Efl_Net_Dialer_Unix_Data *pd)
71} 71}
72 72
73static Eina_Value 73static Eina_Value
74_efl_net_dialer_unix_connect_timeout(Eo *o, const Eina_Value v) 74_efl_net_dialer_unix_connect_timeout(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
75{ 75{
76 Efl_Net_Dialer_Unix_Data *pd = efl_data_scope_get(o, MY_CLASS); 76 Efl_Net_Dialer_Unix_Data *pd = efl_data_scope_get(o, MY_CLASS);
77 Eina_Error err = ETIMEDOUT; 77 Eina_Error err = ETIMEDOUT;
@@ -130,8 +130,8 @@ static void
130_timeout_schedule(Eo *o, Efl_Net_Dialer_Unix_Data *pd) 130_timeout_schedule(Eo *o, Efl_Net_Dialer_Unix_Data *pd)
131{ 131{
132 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_dial), 132 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), pd->timeout_dial),
133 .success = _efl_net_dialer_unix_connect_timeout, 133 .success = _efl_net_dialer_unix_connect_timeout,
134 .storage = &pd->connect.timeout); 134 .storage = &pd->connect.timeout);
135} 135}
136 136
137EOLIAN static Eina_Error 137EOLIAN static Eina_Error
diff --git a/src/lib/ecore_con/efl_net_dialer_websocket.c b/src/lib/ecore_con/efl_net_dialer_websocket.c
index 3c5339d3a2..30545f23c9 100644
--- a/src/lib/ecore_con/efl_net_dialer_websocket.c
+++ b/src/lib/ecore_con/efl_net_dialer_websocket.c
@@ -735,7 +735,7 @@ _efl_net_dialer_websocket_job_receive(Eo *o, Efl_Net_Dialer_Websocket_Data *pd)
735} 735}
736 736
737static Eina_Value 737static Eina_Value
738_efl_net_dialer_websocket_job(Eo *o, const Eina_Value v) 738_efl_net_dialer_websocket_job(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
739{ 739{
740 Efl_Net_Dialer_Websocket_Data *pd = efl_data_scope_get(o, MY_CLASS); 740 Efl_Net_Dialer_Websocket_Data *pd = efl_data_scope_get(o, MY_CLASS);
741 741
@@ -765,8 +765,8 @@ _efl_net_dialer_websocket_job_schedule(Eo *o, Efl_Net_Dialer_Websocket_Data *pd)
765 if (!loop) return; 765 if (!loop) return;
766 766
767 efl_future_then(o, efl_loop_job(loop), 767 efl_future_then(o, efl_loop_job(loop),
768 .success = _efl_net_dialer_websocket_job, 768 .success = _efl_net_dialer_websocket_job,
769 .storage = &pd->job); 769 .storage = &pd->job);
770} 770}
771 771
772static void 772static void
@@ -1486,7 +1486,7 @@ _efl_net_dialer_websocket_binary_send(Eo *o, Efl_Net_Dialer_Websocket_Data *pd,
1486} 1486}
1487 1487
1488static Eina_Value 1488static Eina_Value
1489_efl_net_dialer_websocket_close_request_timeout(Eo *o, const Eina_Value v) 1489_efl_net_dialer_websocket_close_request_timeout(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
1490{ 1490{
1491 DBG("server did not close the TCP socket, timeout"); 1491 DBG("server did not close the TCP socket, timeout");
1492 efl_event_callback_call(o, EFL_IO_CLOSER_EVENT_CLOSED, NULL); 1492 efl_event_callback_call(o, EFL_IO_CLOSER_EVENT_CLOSED, NULL);
@@ -1505,8 +1505,8 @@ _efl_net_dialer_websocket_close_request(Eo *o, Efl_Net_Dialer_Websocket_Data *pd
1505 eina_future_cancel(pd->close_timeout); 1505 eina_future_cancel(pd->close_timeout);
1506 1506
1507 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), 2.0), 1507 efl_future_then(o, efl_loop_timeout(efl_loop_get(o), 2.0),
1508 .success = _efl_net_dialer_websocket_close_request_timeout, 1508 .success = _efl_net_dialer_websocket_close_request_timeout,
1509 .storage = &pd->close_timeout); 1509 .storage = &pd->close_timeout);
1510 1510
1511 efl_io_writer_can_write_set(o, EINA_FALSE); 1511 efl_io_writer_can_write_set(o, EINA_FALSE);
1512 1512
diff --git a/src/lib/ecore_con/efl_net_server_windows.c b/src/lib/ecore_con/efl_net_server_windows.c
index 8859036ad2..68e7fe9906 100644
--- a/src/lib/ecore_con/efl_net_server_windows.c
+++ b/src/lib/ecore_con/efl_net_server_windows.c
@@ -312,7 +312,7 @@ _efl_net_server_windows_efl_net_server_address_get(const Eo *o EINA_UNUSED, Efl_
312} 312}
313 313
314static Eina_Value 314static Eina_Value
315_efl_net_server_windows_pending_announce_job(Eo *o, const Eina_Value v) 315_efl_net_server_windows_pending_announce_job(Eo *o, void *data EINA_UNUSED, const Eina_Value v)
316{ 316{
317 Efl_Net_Server_Windows_Data *pd = efl_data_scope_get(o, MY_CLASS); 317 Efl_Net_Server_Windows_Data *pd = efl_data_scope_get(o, MY_CLASS);
318 Eo *client; 318 Eo *client;
@@ -339,8 +339,8 @@ _efl_net_server_windows_pending_announce_job_schedule(Eo *o, Efl_Net_Server_Wind
339 loop = efl_loop_get(o); 339 loop = efl_loop_get(o);
340 if (!loop) return; 340 if (!loop) return;
341 efl_future_then(o, efl_loop_job(loop), 341 efl_future_then(o, efl_loop_job(loop),
342 .success = _efl_net_server_windows_pending_announce_job, 342 .success = _efl_net_server_windows_pending_announce_job,
343 .storage = &pd->pending_announcer_job); 343 .storage = &pd->pending_announcer_job);
344} 344}
345 345
346EOLIAN static void 346EOLIAN static void
diff --git a/src/lib/eina/eina_promise_private.h b/src/lib/eina/eina_promise_private.h
index 31375b5794..1aeb2e7e6e 100644
--- a/src/lib/eina/eina_promise_private.h
+++ b/src/lib/eina/eina_promise_private.h
@@ -1,38 +1,38 @@
1#ifndef __EINA_PROMISE_PRIVATE_H__ 1#ifndef __EINA_PROMISE_PRIVATE_H__
2#define __EINA_PROMISE_PRIVATE_H__ 2#define __EINA_PROMISE_PRIVATE_H__
3 3
4#define ERROR_DISPATCH(_cbs, _ret, _value, _data) \ 4#define ERROR_DISPATCH(_cbs, _ret, _value, ...) \
5 do { \ 5 do { \
6 Eina_Error ERROR_DISPATCH__err; \ 6 Eina_Error ERROR_DISPATCH__err; \
7 if (!(_cbs)->error) (_ret) = (_value); \ 7 if (!(_cbs)->error) (_ret) = (_value); \
8 else \ 8 else \
9 { \ 9 { \
10 eina_value_get(&(_value), &ERROR_DISPATCH__err); \ 10 eina_value_get(&(_value), &ERROR_DISPATCH__err); \
11 (_ret) = (_cbs)->error((_data), ERROR_DISPATCH__err); \ 11 (_ret) = (_cbs)->error(__VA_ARGS__, ERROR_DISPATCH__err); \
12 } \ 12 } \
13 } while (0) 13 } while (0)
14 14
15#define EASY_FUTURE_DISPATCH(_ret, _value, _dead_future, _cbs, _data) \ 15#define EASY_FUTURE_DISPATCH(_ret, _value, _dead_future, _cbs, ...) \
16 do { \ 16 do { \
17 if ((_value).type == EINA_VALUE_TYPE_ERROR) ERROR_DISPATCH((_cbs), (_ret), (_value), (_data)); \ 17 if ((_value).type == EINA_VALUE_TYPE_ERROR) ERROR_DISPATCH((_cbs), (_ret), (_value), __VA_ARGS__); \
18 else \ 18 else \
19 { \ 19 { \
20 if ((!(_cbs)->success_type) || ((_cbs)->success_type && (_value).type == (_cbs)->success_type)) \ 20 if ((!(_cbs)->success_type) || ((_cbs)->success_type && (_value).type == (_cbs)->success_type)) \
21 { \ 21 { \
22 if (!(_cbs)->success) (_ret) = (_value); /* pass thru */ \ 22 if (!(_cbs)->success) (_ret) = (_value); /* pass thru */ \
23 else (_ret) = (_cbs)->success((_data), (_value)); \ 23 else (_ret) = (_cbs)->success(__VA_ARGS__, (_value)); \
24 } \ 24 } \
25 else \ 25 else \
26 { \ 26 { \
27 Eina_Value EASY_FUTURE_DISPATCH__err = EINA_VALUE_EMPTY; \ 27 Eina_Value EASY_FUTURE_DISPATCH__err = EINA_VALUE_EMPTY; \
28 ERR("Future %p, success cb: %p data: %p, expected success_type %p (%s), got %p (%s)", \ 28 ERR("Future %p, success cb: %p, expected success_type %p (%s), got %p (%s)", \
29 _dead_future, (_cbs)->success, (_data), \ 29 _dead_future, (_cbs)->success, \
30 (_cbs)->success_type, eina_value_type_name_get((_cbs)->success_type), \ 30 (_cbs)->success_type, eina_value_type_name_get((_cbs)->success_type), \
31 (_value).type, (_value).type ? eina_value_type_name_get((_value).type) : NULL); \ 31 (_value).type, (_value).type ? eina_value_type_name_get((_value).type) : NULL); \
32 if (eina_value_setup(&EASY_FUTURE_DISPATCH__err, EINA_VALUE_TYPE_ERROR)) eina_value_set(&EASY_FUTURE_DISPATCH__err, EINVAL); \ 32 if (eina_value_setup(&EASY_FUTURE_DISPATCH__err, EINA_VALUE_TYPE_ERROR)) eina_value_set(&EASY_FUTURE_DISPATCH__err, EINVAL); \
33 ERROR_DISPATCH((_cbs), (_ret), EASY_FUTURE_DISPATCH__err, (_data)); \ 33 ERROR_DISPATCH((_cbs), (_ret), EASY_FUTURE_DISPATCH__err, __VA_ARGS__); \
34 } \ 34 } \
35 } \ 35 } \
36 if ((_cbs)->free) (_cbs)->free((_data), _dead_future); \ 36 if ((_cbs)->free) (_cbs)->free(__VA_ARGS__, _dead_future); \
37 } while(0) 37 } while(0)
38#endif 38#endif
diff --git a/src/lib/eo/Eo.h b/src/lib/eo/Eo.h
index 8cd9f63d07..e953ac2709 100644
--- a/src/lib/eo/Eo.h
+++ b/src/lib/eo/Eo.h
@@ -379,7 +379,7 @@ typedef struct _Efl_Future_Cb_Desc {
379 * using @c eina_value_flush() once they are unused (no more future or futures 379 * using @c eina_value_flush() once they are unused (no more future or futures
380 * returned a new value). 380 * returned a new value).
381 */ 381 */
382 Eina_Value (*success)(Eo *o, const Eina_Value value); 382 Eina_Value (*success)(Eo *o, void *data, const Eina_Value value);
383 /** 383 /**
384 * Called on error (value.type is @c EINA_VALUE_TYPE_ERROR). 384 * Called on error (value.type is @c EINA_VALUE_TYPE_ERROR).
385 * 385 *
@@ -417,7 +417,7 @@ typedef struct _Efl_Future_Cb_Desc {
417 * using @c eina_value_flush() once they are unused (no more future or futures 417 * using @c eina_value_flush() once they are unused (no more future or futures
418 * returned a new value). 418 * returned a new value).
419 */ 419 */
420 Eina_Value (*error)(Eo *o, Eina_Error error); 420 Eina_Value (*error)(Eo *o, void *data, Eina_Error error);
421 /** 421 /**
422 * Called on @b all situations to notify future destruction. 422 * Called on @b all situations to notify future destruction.
423 * 423 *
@@ -431,7 +431,7 @@ typedef struct _Efl_Future_Cb_Desc {
431 * @param o The object used to create the link in efl_future_cb_from_desc() or efl_future_chain_array(). 431 * @param o The object used to create the link in efl_future_cb_from_desc() or efl_future_chain_array().
432 * @param dead_future The future that's been freed. 432 * @param dead_future The future that's been freed.
433 */ 433 */
434 void (*free)(Eo *o, const Eina_Future *dead_future); 434 void (*free)(Eo *o, void *data, const Eina_Future *dead_future);
435 /** 435 /**
436 * If provided, then @c success will only be called if the value type matches the given pointer. 436 * If provided, then @c success will only be called if the value type matches the given pointer.
437 * 437 *
@@ -440,6 +440,13 @@ typedef struct _Efl_Future_Cb_Desc {
440 */ 440 */
441 const Eina_Value_Type *success_type; 441 const Eina_Value_Type *success_type;
442 /** 442 /**
443 * Context data given to every callback.
444 *
445 * This must be freed @b only by @c free callback as it's called from every case,
446 * otherwise it may lead to memory leaks.
447 */
448 const void *data;
449 /**
443 * This is used by Eo to cancel pending futures in case 450 * This is used by Eo to cancel pending futures in case
444 * an Eo object is deleted. It can be @c NULL. 451 * an Eo object is deleted. It can be @c NULL.
445 */ 452 */
@@ -476,7 +483,7 @@ typedef struct _Efl_Future_Cb_Desc {
476 * } 483 * }
477 * 484 *
478 * static Eina_Value 485 * static Eina_Value
479 * _file_ok(Eo *o EINA_UNUSED, const Eina_Value value) 486 * _file_ok(Eo *o EINA_UNUSED, void *data EINA_UNUSED, const Eina_Value value)
480 * { 487 * {
481 * const char *data; 488 * const char *data;
482 * //There's no need to check the value type since EO infra already has done so. 489 * //There's no need to check the value type since EO infra already has done so.
@@ -487,7 +494,7 @@ typedef struct _Efl_Future_Cb_Desc {
487 * } 494 * }
488 * 495 *
489 * static Eina_Value 496 * static Eina_Value
490 * _file_err(Eo *o EINA_UNUSED, Eina_Error error) 497 * _file_err(Eo *o EINA_UNUSED, void *data EINA_UNUSED, Eina_Error error)
491 * { 498 * {
492 * //In case the downloader is deleted before the future is resolved, the future will be canceled thus this callback will be called. 499 * //In case the downloader is deleted before the future is resolved, the future will be canceled thus this callback will be called.
493 * fprintf(stderr, "Could not download the file. Reason: %s\n", eina_error_msg_get(error)); 500 * fprintf(stderr, "Could not download the file. Reason: %s\n", eina_error_msg_get(error));
@@ -495,7 +502,7 @@ typedef struct _Efl_Future_Cb_Desc {
495 * } 502 * }
496 * 503 *
497 * static void 504 * static void
498 * _downlader_free(Eo *o, const Eina_Future *dead_future EINA_UNUSED) 505 * _downlader_free(Eo *o, void *data EINA_UNUSED, const Eina_Future *dead_future EINA_UNUSED)
499 * { 506 * {
500 * Ecore_Timer *t = efl_key_data_get(o, "timer"); 507 * Ecore_Timer *t = efl_key_data_get(o, "timer");
501 * //The download finished before the timer expired. Cancel it... 508 * //The download finished before the timer expired. Cancel it...
diff --git a/src/lib/eo/eo_base_class.c b/src/lib/eo/eo_base_class.c
index 928811abcb..3ca8591b41 100644
--- a/src/lib/eo/eo_base_class.c
+++ b/src/lib/eo/eo_base_class.c
@@ -2080,7 +2080,7 @@ _efl_future_cb(void *data, const Eina_Value value, const Eina_Future *dead_futur
2080 pd->pending_futures = eina_inlist_remove(pd->pending_futures, 2080 pd->pending_futures = eina_inlist_remove(pd->pending_futures,
2081 EINA_INLIST_GET(pending)); 2081 EINA_INLIST_GET(pending));
2082 efl_ref(o); 2082 efl_ref(o);
2083 EASY_FUTURE_DISPATCH(ret, value, dead_future, &pending->desc, (void*) o); 2083 EASY_FUTURE_DISPATCH(ret, value, dead_future, &pending->desc, (void*) o, (void*) pending->desc.data);
2084 efl_unref(o); 2084 efl_unref(o);
2085 _efl_pending_future_free(pending); 2085 _efl_pending_future_free(pending);
2086 2086
@@ -2147,10 +2147,10 @@ efl_future_chain_array(Eo *obj,
2147 { 2147 {
2148 if (descs[i].error) 2148 if (descs[i].error)
2149 { 2149 {
2150 Eina_Value r = descs[i].error(obj, ENOMEM); 2150 Eina_Value r = descs[i].error(obj, (void*) descs[i].data, ENOMEM);
2151 eina_value_flush(&r); 2151 eina_value_flush(&r);
2152 } 2152 }
2153 if (descs[i].free) descs[i].free(obj, NULL); 2153 if (descs[i].free) descs[i].free(obj, (void*) descs[i].data, NULL);
2154 } 2154 }
2155 return NULL; 2155 return NULL;
2156} 2156}
diff --git a/src/tests/ecore/efl_app_test_promise.c b/src/tests/ecore/efl_app_test_promise.c
index fde88793b4..e68f74d60a 100644
--- a/src/tests/ecore/efl_app_test_promise.c
+++ b/src/tests/ecore/efl_app_test_promise.c
@@ -808,7 +808,7 @@ EFL_START_TEST(efl_test_promise_future_race)
808EFL_END_TEST 808EFL_END_TEST
809 809
810static Eina_Value 810static Eina_Value
811_eo_future1_ok(Eo *eo EINA_UNUSED, const Eina_Value v) 811_eo_future1_ok(Eo *eo EINA_UNUSED, void *data EINA_UNUSED, const Eina_Value v)
812{ 812{
813 const char *number; 813 const char *number;
814 814
@@ -819,14 +819,14 @@ _eo_future1_ok(Eo *eo EINA_UNUSED, const Eina_Value v)
819} 819}
820 820
821static Eina_Value 821static Eina_Value
822_eo_future1_err(Eo *eo EINA_UNUSED, Eina_Error err EINA_UNUSED) 822_eo_future1_err(Eo *eo EINA_UNUSED, void *data EINA_UNUSED, Eina_Error err EINA_UNUSED)
823{ 823{
824 //Should not happen 824 //Should not happen
825 fail_if(EINA_TRUE); 825 fail_if(EINA_TRUE);
826} 826}
827 827
828static Eina_Value 828static Eina_Value
829_eo_future2_ok(Eo *eo EINA_UNUSED, const Eina_Value v) 829_eo_future2_ok(Eo *eo EINA_UNUSED, void *data EINA_UNUSED, const Eina_Value v)
830{ 830{
831 //Should not happen 831 //Should not happen
832 fail_if(EINA_TRUE); 832 fail_if(EINA_TRUE);
@@ -834,7 +834,7 @@ _eo_future2_ok(Eo *eo EINA_UNUSED, const Eina_Value v)
834} 834}
835 835
836static Eina_Value 836static Eina_Value
837_eo_future2_err(Eo *eo EINA_UNUSED, Eina_Error err) 837_eo_future2_err(Eo *eo EINA_UNUSED, void *data EINA_UNUSED, Eina_Error err)
838{ 838{
839 Eina_Value v; 839 Eina_Value v;
840 840
@@ -845,7 +845,7 @@ _eo_future2_err(Eo *eo EINA_UNUSED, Eina_Error err)
845} 845}
846 846
847static void 847static void
848_eo_future_free(Eo *eo, const Eina_Future *dead EINA_UNUSED) 848_eo_future_free(Eo *eo, void *data EINA_UNUSED, const Eina_Future *dead EINA_UNUSED)
849{ 849{
850 int *free_called = efl_key_data_get(eo, "free_called"); 850 int *free_called = efl_key_data_get(eo, "free_called");
851 (*free_called)++; 851 (*free_called)++;
@@ -890,7 +890,7 @@ EFL_START_TEST(efl_test_promise_eo)
890EFL_END_TEST 890EFL_END_TEST
891 891
892static Eina_Value 892static Eina_Value
893_eo_future_link_success(Eo *eo EINA_UNUSED, const Eina_Value v) 893_eo_future_link_success(Eo *eo EINA_UNUSED, void *data EINA_UNUSED, const Eina_Value v)
894{ 894{
895 //This should never happen 895 //This should never happen
896 fail_if(EINA_TRUE); 896 fail_if(EINA_TRUE);
@@ -898,7 +898,7 @@ _eo_future_link_success(Eo *eo EINA_UNUSED, const Eina_Value v)
898} 898}
899 899
900static Eina_Value 900static Eina_Value
901_eo_future_link_err(Eo *eo, Eina_Error err) 901_eo_future_link_err(Eo *eo, void *data EINA_UNUSED, Eina_Error err)
902{ 902{
903 int *err_called = efl_key_data_get(eo, "err_called"); 903 int *err_called = efl_key_data_get(eo, "err_called");
904 Eina_Value v; 904 Eina_Value v;