summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-04-13 14:43:43 -0300
committerFelipe Magno de Almeida <felipe@expertisesolutions.com.br>2016-04-13 14:44:19 -0300
commit35dd5b5cab8fa483b24de4dc1cffa5edc70bbd97 (patch)
tree7a615e82fd658b914f8f6cbf37904206cb4594c1
parentacc1a5dcc033733b6085d1b5c2595fe54a042829 (diff)
eina: Fix promise error with eina_promise_all
Fix value_set and error_set signatures which were receiving a owner. They actually receive the promise and not the owner, this caused wrong access to memory and were not visible by warnings because the functions are casted. This problem caused errors in which it seemed that promise had actually error'ed when questioned it.
-rw-r--r--src/lib/eina/eina_promise.c37
-rw-r--r--src/tests/eina/eina_test_promise.c52
2 files changed, 73 insertions, 16 deletions
diff --git a/src/lib/eina/eina_promise.c b/src/lib/eina/eina_promise.c
index 9a7c259474..459f686e84 100644
--- a/src/lib/eina/eina_promise.c
+++ b/src/lib/eina/eina_promise.c
@@ -108,7 +108,6 @@ _eina_promise_then_calls(_Eina_Promise_Default_Owner* promise)
108 } 108 }
109 else if (callback->callback) 109 else if (callback->callback)
110 { 110 {
111 fprintf(stderr, "then callback\n");
112 (*callback->callback)(callback->data, &promise->value[0]); 111 (*callback->callback)(callback->data, &promise->value[0]);
113 } 112 }
114 _eina_promise_unref(&promise->promise); 113 _eina_promise_unref(&promise->promise);
@@ -151,18 +150,18 @@ _eina_promise_del(_Eina_Promise_Default_Owner* promise)
151} 150}
152 151
153static void * 152static void *
154_eina_promise_buffer_get(_Eina_Promise_Default_Owner* promise) 153_eina_promise_owner_buffer_get(_Eina_Promise_Default_Owner* promise)
155{ 154{
156 return &promise->value[0]; 155 return &promise->value[0];
157} 156}
158 157
159static void * 158static void *
160_eina_promise_value_get(_Eina_Promise_Default_Owner const* promise) 159_eina_promise_value_get(_Eina_Promise_Default const* p)
161{ 160{
162 if (promise->promise.has_finished) 161 _Eina_Promise_Default_Owner const* promise = EINA_PROMISE_GET_OWNER(p);
162 if (promise->promise.has_finished && !promise->promise.has_errored)
163 { 163 {
164 return (void*)(promise->promise.value_size && !promise->promise.has_errored ? 164 return (void*)&promise->value[0];
165 &promise->value[0] : NULL);
166 } 165 }
167 else 166 else
168 { 167 {
@@ -171,7 +170,7 @@ _eina_promise_value_get(_Eina_Promise_Default_Owner const* promise)
171} 170}
172 171
173static void 172static void
174_eina_promise_value_set(_Eina_Promise_Default_Owner* promise, void* data, Eina_Promise_Free_Cb free) 173_eina_promise_owner_value_set(_Eina_Promise_Default_Owner* promise, void* data, Eina_Promise_Free_Cb free)
175{ 174{
176 if (data && promise->promise.value_size) 175 if (data && promise->promise.value_size)
177 { 176 {
@@ -198,7 +197,6 @@ _eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback,
198 cb->error_cb = error_cb; 197 cb->error_cb = error_cb;
199 cb->data = data; 198 cb->data = data;
200 promise->promise.then_callbacks = eina_inlist_append(promise->promise.then_callbacks, EINA_INLIST_GET(cb)); 199 promise->promise.then_callbacks = eina_inlist_append(promise->promise.then_callbacks, EINA_INLIST_GET(cb));
201 fprintf(stderr, "appending then callback\n");
202 200
203 if (!promise->promise.is_first_then) 201 if (!promise->promise.is_first_then)
204 { 202 {
@@ -212,7 +210,7 @@ _eina_promise_then(_Eina_Promise_Default* p, Eina_Promise_Cb callback,
212} 210}
213 211
214static void 212static void
215_eina_promise_error_set(_Eina_Promise_Default_Owner* promise, Eina_Error error) 213_eina_promise_owner_error_set(_Eina_Promise_Default_Owner* promise, Eina_Error error)
216{ 214{
217 promise->promise.error = error; 215 promise->promise.error = error;
218 promise->promise.has_errored = EINA_TRUE; 216 promise->promise.has_errored = EINA_TRUE;
@@ -231,11 +229,11 @@ _eina_promise_finish(_Eina_Promise_Default_Owner* promise)
231} 229}
232 230
233static Eina_Error 231static Eina_Error
234_eina_promise_error_get(_Eina_Promise_Default_Owner const* promise) 232_eina_promise_error_get(_Eina_Promise_Default const* promise)
235{ 233{
236 if (promise->promise.has_errored) 234 if (promise->has_errored)
237 { 235 {
238 return promise->promise.error; 236 return promise->error;
239 } 237 }
240 else 238 else
241 { 239 {
@@ -292,6 +290,12 @@ _eina_promise_value_size_get(_Eina_Promise_Default_Owner const* promise)
292 return promise->promise.value_size; 290 return promise->promise.value_size;
293} 291}
294 292
293static size_t
294_eina_promise_owner_value_size_get(_Eina_Promise_Default_Owner const* promise)
295{
296 return promise->promise.value_size;
297}
298
295static void 299static void
296_eina_promise_ref(_Eina_Promise_Default* p) 300_eina_promise_ref(_Eina_Promise_Default* p)
297{ 301{
@@ -377,12 +381,13 @@ eina_promise_default_add(int value_size)
377 memset(&p->promise.cancel_callbacks, 0, sizeof(p->promise.cancel_callbacks)); 381 memset(&p->promise.cancel_callbacks, 0, sizeof(p->promise.cancel_callbacks));
378 p->promise.value_size = value_size; 382 p->promise.value_size = value_size;
379 p->promise.value_free_cb = NULL; 383 p->promise.value_free_cb = NULL;
384 p->promise.error = 0;
380 385
381 p->owner_vtable.version = EINA_PROMISE_VERSION; 386 p->owner_vtable.version = EINA_PROMISE_VERSION;
382 p->owner_vtable.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(_eina_promise_value_set); 387 p->owner_vtable.value_set = EINA_FUNC_PROMISE_OWNER_VALUE_SET(_eina_promise_owner_value_set);
383 p->owner_vtable.error_set = EINA_FUNC_PROMISE_OWNER_ERROR_SET(_eina_promise_error_set); 388 p->owner_vtable.error_set = EINA_FUNC_PROMISE_OWNER_ERROR_SET(_eina_promise_owner_error_set);
384 p->owner_vtable.buffer_get = EINA_FUNC_PROMISE_OWNER_BUFFER_GET(_eina_promise_buffer_get); 389 p->owner_vtable.buffer_get = EINA_FUNC_PROMISE_OWNER_BUFFER_GET(_eina_promise_owner_buffer_get);
385 p->owner_vtable.value_size_get = EINA_FUNC_PROMISE_OWNER_VALUE_SIZE_GET(_eina_promise_value_size_get); 390 p->owner_vtable.value_size_get = EINA_FUNC_PROMISE_OWNER_VALUE_SIZE_GET(_eina_promise_owner_value_size_get);
386 p->owner_vtable.promise_get = EINA_FUNC_PROMISE_OWNER_PROMISE_GET(_eina_promise_owner_promise_get); 391 p->owner_vtable.promise_get = EINA_FUNC_PROMISE_OWNER_PROMISE_GET(_eina_promise_owner_promise_get);
387 p->owner_vtable.pending_is = EINA_FUNC_PROMISE_OWNER_PENDING_IS(_eina_promise_owner_pending_is); 392 p->owner_vtable.pending_is = EINA_FUNC_PROMISE_OWNER_PENDING_IS(_eina_promise_owner_pending_is);
388 p->owner_vtable.cancelled_is = EINA_FUNC_PROMISE_OWNER_CANCELLED_IS(_eina_promise_owner_cancelled_is); 393 p->owner_vtable.cancelled_is = EINA_FUNC_PROMISE_OWNER_CANCELLED_IS(_eina_promise_owner_cancelled_is);
diff --git a/src/tests/eina/eina_test_promise.c b/src/tests/eina/eina_test_promise.c
index 898a4ba9c9..59ed7d7b0f 100644
--- a/src/tests/eina/eina_test_promise.c
+++ b/src/tests/eina/eina_test_promise.c
@@ -122,6 +122,57 @@ START_TEST(eina_test_promise_immediate_set_lifetime_all)
122} 122}
123END_TEST 123END_TEST
124 124
125static void _eina_test_promise_value_all_cb(void* data, void* value)
126{
127 Eina_Iterator** iterator = value;
128 int *i, *j;
129 Eina_Bool b;
130
131 b = eina_iterator_next(*iterator, (void**)&i);
132 ck_assert(!!b);
133
134 b = eina_iterator_next(*iterator, (void**)&j);
135 ck_assert(!!b);
136
137 ck_assert(i != NULL);
138 ck_assert(j != NULL);
139 ck_assert(*i == 10);
140 ck_assert(*j == 15);
141
142 *(Eina_Bool*)data = EINA_TRUE;
143}
144
145START_TEST(eina_test_promise_values_all)
146{
147 Eina_Promise_Owner* owners[2];
148 Eina_Promise* promises[3] = {NULL, NULL, NULL};
149 Eina_Promise* promise_all;
150 Eina_Bool ran = EINA_FALSE;
151
152 eina_init();
153
154 int i = 10, j = 15;
155
156 owners[0] = eina_promise_default_add(sizeof(int));
157 owners[1] = eina_promise_default_add(sizeof(int));
158
159 promises[0] = eina_promise_owner_promise_get(owners[0]);
160 promises[1] = eina_promise_owner_promise_get(owners[1]);
161
162
163 promise_all = eina_promise_all(eina_carray_iterator_new((void**)&promises[0]));
164
165 eina_promise_owner_value_set(owners[0], &i, NULL);
166 eina_promise_owner_value_set(owners[1], &j, NULL);
167
168 eina_promise_then(promise_all, &_eina_test_promise_value_all_cb, NULL, &ran);
169
170 ck_assert(ran == EINA_TRUE);
171
172 eina_shutdown();
173}
174END_TEST
175
125static void cancel_callback(void* data, Eina_Promise_Owner* promise EINA_UNUSED) 176static void cancel_callback(void* data, Eina_Promise_Owner* promise EINA_UNUSED)
126{ 177{
127 *(Eina_Bool*)data = EINA_TRUE; 178 *(Eina_Bool*)data = EINA_TRUE;
@@ -192,6 +243,7 @@ eina_test_promise(TCase *tc)
192 tcase_add_test(tc, eina_test_promise_normal_lifetime_all); 243 tcase_add_test(tc, eina_test_promise_normal_lifetime_all);
193 tcase_add_test(tc, eina_test_promise_immediate_set_lifetime); 244 tcase_add_test(tc, eina_test_promise_immediate_set_lifetime);
194 tcase_add_test(tc, eina_test_promise_immediate_set_lifetime_all); 245 tcase_add_test(tc, eina_test_promise_immediate_set_lifetime_all);
246 tcase_add_test(tc, eina_test_promise_values_all);
195 tcase_add_test(tc, eina_test_promise_cancel_promise); 247 tcase_add_test(tc, eina_test_promise_cancel_promise);
196 tcase_add_test(tc, eina_test_promise_progress); 248 tcase_add_test(tc, eina_test_promise_progress);
197} 249}