Discussion:
[EGIT] [core/efl] master 01/01: ecore: use efl_future_then to simplify the code logic and reduce potential bugs.
Cedric BAIL
2018-12-07 11:42:32 UTC
Permalink
xartigas pushed a commit to branch master.

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

commit 6b22e6e33d1809a7231ad3cd51d9ff531acdbf4f
Author: Cedric BAIL <***@osg.samsung.com>
Date: Fri Dec 7 12:29:22 2018 +0100

ecore: use efl_future_then to simplify the code logic and reduce potential bugs.

Summary: Depends on D7380

Reviewers: segfaultxavi, felipealmeida, SanghyeonLee, vitor.sousa, bu5hm4n

Reviewed By: bu5hm4n

Subscribers: barbieri, #reviewers, #committers

Tags: #efl

Maniphest Tasks: T7472

Differential Revision: https://phab.enlightenment.org/D7381
---
src/lib/ecore/efl_loop.c | 39 ++++----
src/lib/ecore/efl_model_composite_boolean.c | 22 +++--
src/lib/ecore/efl_model_composite_selection.c | 129 ++++++++++++++------------
src/lib/ecore/efl_thread.c | 15 ++-
4 files changed, 105 insertions(+), 100 deletions(-)

diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c
index 5d24608af3..33b6398fbb 100644
--- a/src/lib/ecore/efl_loop.c
+++ b/src/lib/ecore/efl_loop.c
@@ -365,44 +365,39 @@ _efl_loop_efl_object_destructor(Eo *obj, Efl_Loop_Data *pd)
efl_destructor(efl_super(obj, EFL_LOOP_CLASS));
}

-static void
-_efl_loop_arguments_cleanup(Eina_Array *arga)
-{
- Eina_Stringshare *s;
-
- while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
- eina_array_free(arga);
-}
-
static Eina_Value
-_efl_loop_arguments_send(void *data, const Eina_Value v,
- const Eina_Future *dead EINA_UNUSED)
+_efl_loop_arguments_send(Eo *o EINA_UNUSED, void *data, const Eina_Value v)

{
static Eina_Bool initialization = EINA_TRUE;
Efl_Loop_Arguments arge;
Eina_Array *arga = data;

- if (v.type == EINA_VALUE_TYPE_ERROR) goto on_error;
-
arge.argv = arga;
arge.initialization = initialization;
initialization = EINA_FALSE;

efl_event_callback_call(efl_main_loop_get(),
EFL_LOOP_EVENT_ARGUMENTS, &arge);
-on_error:
- _efl_loop_arguments_cleanup(arga);
return v;
}

+static void
+_efl_loop_arguments_cleanup(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
+{
+ Eina_Array *arga = data;
+ Eina_Stringshare *s;
+
+ while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
+ eina_array_free(arga);
+}
+
// It doesn't make sense to send those argument to any other mainloop
// As it also doesn't make sense to allow anyone to override this, so
// should be internal for sure, not even protected.
EAPI void
ecore_loop_arguments_send(int argc, const char **argv)
{
- Eina_Future *job;
Eina_Array *arga;
int i = 0;

@@ -414,18 +409,18 @@ ecore_loop_arguments_send(int argc, const char **argv)
efl_task_arg_append(efl_main_loop_get(), argv[i]);
}

- job = eina_future_then(efl_loop_job(efl_main_loop_get()),
- _efl_loop_arguments_send, arga, NULL);
- efl_future_then(efl_main_loop_get(), job);
+ efl_future_then(efl_main_loop_get(), efl_loop_job(efl_main_loop_get()),
+ .success = _efl_loop_arguments_send,
+ .free = _efl_loop_arguments_cleanup,
+ .data = arga);
}

static Eina_Future *
_efl_loop_job(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED)
{
- Eina_Future_Scheduler *sched = efl_loop_future_scheduler_get(obj);
// NOTE: Eolian should do efl_future_then() to bind future to object.
- return efl_future_then
- (obj, eina_future_resolved(sched, EINA_VALUE_EMPTY));
+ return efl_future_then(obj,
+ eina_future_resolved(efl_loop_future_scheduler_get(obj), EINA_VALUE_EMPTY));
}

EOLIAN static void
diff --git a/src/lib/ecore/efl_model_composite_boolean.c b/src/lib/ecore/efl_model_composite_boolean.c
index 222329eb3b..2db0bc768e 100644
--- a/src/lib/ecore/efl_model_composite_boolean.c
+++ b/src/lib/ecore/efl_model_composite_boolean.c
@@ -181,16 +181,13 @@ struct _Efl_Model_Slice_Request
};

static Eina_Value
-_efl_model_composite_boolean_then(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
+_efl_model_composite_boolean_then(Eo *o EINA_UNUSED, void *data, const Eina_Value v)
{
Efl_Model_Slice_Request *req = data;
unsigned int i, len;
Eina_Value r = EINA_VALUE_EMPTY;
Eo *target = NULL;

- if (eina_value_type_get(&v) != EINA_VALUE_TYPE_ARRAY)
- goto on_error;
-
eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);

EINA_VALUE_ARRAY_FOREACH(&v, len, i, target)
@@ -206,11 +203,16 @@ _efl_model_composite_boolean_then(void *data, const Eina_Value v, const Eina_Fut
eina_value_array_append(&r, composite);
}

- on_error:
+ return r;
+}
+
+static void
+_efl_model_composite_boolean_clean(Eo *o EINA_UNUSED, void *data, const Eina_Future *dead_future EINA_UNUSED)
+{
+ Efl_Model_Slice_Request *req = data;
+
efl_unref(req->parent);
free(req);
-
- return r;
}

static void
@@ -295,8 +297,10 @@ _efl_model_composite_boolean_efl_model_children_slice_get(Eo *obj,
req->parent = efl_ref(obj);
req->start = start;

- return efl_future_then
- (obj, eina_future_then(f, _efl_model_composite_boolean_then, req, NULL));
+ return efl_future_then(obj, f, .success_type = EINA_VALUE_TYPE_ARRAY,
+ .success = _efl_model_composite_boolean_then,
+ .free = _efl_model_composite_boolean_clean,
+ .data = req);
}

#include "efl_model_composite_boolean.eo.c"
diff --git a/src/lib/ecore/efl_model_composite_selection.c b/src/lib/ecore/efl_model_composite_selection.c
index 25f68c2f5f..ad14b74275 100644
--- a/src/lib/ecore/efl_model_composite_selection.c
+++ b/src/lib/ecore/efl_model_composite_selection.c
@@ -40,10 +40,9 @@ _efl_model_composite_selection_efl_object_constructor(Eo *obj,
}

static Eina_Value
-_commit_change(void *data, const Eina_Value v, const Eina_Future *dead_future EINA_UNUSED)
+_commit_change(Eo *child, void *data EINA_UNUSED, const Eina_Value v)
{
Efl_Model_Composite_Selection_Data *pd;
- Efl_Model *child = data;
Eina_Value *vc = NULL;
Eina_Value *selected = NULL;
Eina_Bool selflag = EINA_FALSE;
@@ -85,16 +84,12 @@ _commit_change(void *data, const Eina_Value v, const Eina_Future *dead_future EI
return v;
}

-static Eina_Value
-_clear_child(void *data,
- const Eina_Value v,
+static void
+_clear_child(Eo *child,
+ void *data EINA_UNUSED,
const Eina_Future *dead_future EINA_UNUSED)
{
- Efl_Model *child = data;
-
efl_del(child);
-
- return v;
}

static Efl_Model *
@@ -131,8 +126,7 @@ _check_child_change(Efl_Model *child, Eina_Bool value)
else
{
r = efl_model_property_set(child, "selected", eina_value_bool_new(!!value));
- r = eina_future_then(r, _commit_change, child, NULL);
- r = eina_future_then(r, _clear_child, child, NULL);
+ r = efl_future_then(child, r, .success = _commit_change, .free = _clear_child);
}

return r;
@@ -151,9 +145,9 @@ _unselect_child(Efl_Model *child)
}

static Eina_Value
-_select_slice_then(void *data EINA_UNUSED,
- const Eina_Value v,
- const Eina_Future *dead_future EINA_UNUSED)
+_select_slice_then(Eo *obj EINA_UNUSED,
+ void *data EINA_UNUSED,
+ const Eina_Value v)
{
Efl_Model *child = NULL;
Eina_Future *r;
@@ -169,9 +163,9 @@ _select_slice_then(void *data EINA_UNUSED,
}

static Eina_Value
-_unselect_slice_then(void *data EINA_UNUSED,
- const Eina_Value v,
- const Eina_Future *dead_future EINA_UNUSED)
+_unselect_slice_then(Eo *obj EINA_UNUSED,
+ void *data EINA_UNUSED,
+ const Eina_Value v)
{
Efl_Model *child = NULL;
Eina_Future *r;
@@ -233,12 +227,13 @@ _efl_model_composite_selection_efl_model_property_set(Eo *obj,
if (!success)
return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);

- return efl_future_then
- (obj, eina_future_then(efl_model_children_slice_get(obj, l, 1),
- _select_slice_then, obj, NULL));
+ return efl_future_then(obj, efl_model_children_slice_get(obj, l, 1),
+ .success = _select_slice_then,
+ .success_type = EINA_VALUE_TYPE_ARRAY);
}

- return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS), property, value);
+ return efl_model_property_set(efl_super(obj, EFL_MODEL_COMPOSITE_SELECTION_CLASS),
+ property, value);
}

static Eina_Value *
@@ -277,29 +272,10 @@ _regenerate_error(void *data,
}

static Eina_Value
-_untangle_array(void *data,
- const Eina_Value v,
- const Eina_Future *dead_future EINA_UNUSED)
+_untangle_array(void *data EINA_UNUSED,
+ const Eina_Value v)
{
- Efl_Model *child = data;
Eina_Value va = EINA_VALUE_EMPTY;
- Eina_Future *f;
-
- if (v.type == EINA_VALUE_TYPE_ERROR)
- {
- // We need to roll back the change, which means in this
- // case to unselect this child as this is the only case
- // where we could end up here.
- Eina_Error *error = calloc(1, sizeof (Eina_Error));
-
- f = efl_model_property_set(efl_super(child, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
- "selected", eina_value_bool_new(EINA_FALSE));
- // Once this is done, we need to repropagate the error
- eina_value_error_get(&v, error);
- f = eina_future_then(f, _regenerate_error, error, NULL);
-
- return eina_future_as_value(f);
- }

// Only return the commit change, not the result of the unselect
eina_value_array_get(&v, 0, &va);
@@ -317,6 +293,26 @@ _efl_model_composite_selection_children_efl_model_properties_get(const Eo *obj,
return props;
}

+static Eina_Value
+_untangle_error(void *data, Eina_Error err)
+{
+ Efl_Model *child = data;
+ Eina_Future *f;
+
+ // We need to roll back the change, which means in this
+ // case to unselect this child as this is the only case
+ // where we could end up here.
+ Eina_Error *error = calloc(1, sizeof (Eina_Error));
+
+ f = efl_model_property_set(efl_super(child, EFL_MODEL_COMPOSITE_SELECTION_CHILDREN_CLASS),
+ "selected", eina_value_bool_new(EINA_FALSE));
+ // Once this is done, we need to repropagate the error
+ *error = err;
+ f = eina_future_then(f, _regenerate_error, error, NULL);
+
+ return eina_future_as_value(f);
+}
+
static Eina_Future *
_efl_model_composite_selection_children_efl_model_property_set(Eo *obj,
Efl_Model_Composite_Selection_Children_Data *pd EINA_UNUSED,
@@ -381,6 +377,7 @@ _efl_model_composite_selection_children_efl_model_property_set(Eo *obj,
}
else
{
+ Eo *parent;
Eina_Value *vs;
unsigned long selected = 0;
Eina_Bool success;
@@ -403,18 +400,23 @@ _efl_model_composite_selection_children_efl_model_property_set(Eo *obj,
return efl_loop_future_rejected(obj, EFL_MODEL_ERROR_INCORRECT_VALUE);

// There was, need to unselect the previous one along setting the new value
+ parent = efl_parent_get(obj);
chain = eina_future_all(chain,
- eina_future_then(efl_model_children_slice_get(efl_parent_get(obj), selected, 1),
- _unselect_slice_then, NULL, NULL));
-
- chain = eina_future_then(chain, _untangle_array, obj, NULL);
+ efl_future_then(parent, efl_model_children_slice_get(parent, selected, 1),
+ .success = _unselect_slice_then,
+ .success_type = EINA_VALUE_TYPE_ARRAY));
+
+ chain = eina_future_then_easy(chain,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
+ .success = _untangle_array,
+ .data = obj,
+ .error = _untangle_error);
}
}

commit_change:
- chain = eina_future_then(chain, _commit_change, obj, NULL);
-
- return efl_future_then(obj, chain);
+ return efl_future_then(obj, chain,
+ .success = _commit_change);
}

typedef struct _Selection_Children_Request Selection_Children_Request;
@@ -426,18 +428,15 @@ struct _Selection_Children_Request
};

static Eina_Value
-_slice_get(void *data,
- const Eina_Value v,
- const Eina_Future *dead_future EINA_UNUSED)
+_slice_get(Eo *o EINA_UNUSED,
+ void *data,
+ const Eina_Value v)
{
Selection_Children_Request *req = data;
unsigned int length, it;
Eo *composited = NULL;
Eina_Value r = EINA_VALUE_EMPTY;

- if (v.type == EINA_VALUE_TYPE_ERROR)
- goto error;
-
eina_value_array_setup(&r, EINA_VALUE_TYPE_OBJECT, 4);

EINA_VALUE_ARRAY_FOREACH(&v, length, it, composited)
@@ -450,11 +449,18 @@ _slice_get(void *data,
eina_value_array_append(&r, compositing);
}

- error:
+ return r;
+}
+
+static void
+_slice_clean(Eo *o EINA_UNUSED,
+ void *data,
+ const Eina_Future *dead_future EINA_UNUSED)
+{
+ Selection_Children_Request *req = data;
+
efl_unref(req->parent);
free(req);
-
- return r;
}

static Eina_Future *
@@ -473,9 +479,12 @@ _efl_model_composite_selection_efl_model_children_slice_get(Eo *obj,
// NOTE: We do jump on purpose EFL_MODEL_COMPOSITE_BOOLEAN_CLASS here
f = efl_model_children_slice_get(efl_super(obj, EFL_MODEL_COMPOSITE_BOOLEAN_CLASS),
start, count);
- f = eina_future_then(f, _slice_get, req, NULL);

- return efl_future_then(obj, f);
+ return efl_future_then(obj, f,
+ .success_type = EINA_VALUE_TYPE_ARRAY,
+ .success = _slice_get,
+ .free = _slice_clean,
+ .data = req);
}

#include "efl_model_composite_selection.eo.c"
diff --git a/src/lib/ecore/efl_thread.c b/src/lib/ecore/efl_thread.c
index 3a650a7d45..f72aa07231 100644
--- a/src/lib/ecore/efl_thread.c
+++ b/src/lib/ecore/efl_thread.c
@@ -145,19 +145,16 @@ _cb_thread_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED)
}

static Eina_Value
-_efl_loop_arguments_send(void *data, const Eina_Value v,
- const Eina_Future *dead EINA_UNUSED)
+_efl_loop_arguments_send(Eo *obj, void *data EINA_UNUSED, const Eina_Value v)

{
Efl_Loop_Arguments arge;
- Eo *obj = data;
Eina_Array *arga;
Eina_Stringshare *s;
unsigned int argc = efl_task_arg_count_get(obj);
unsigned int i;

arga = eina_array_new(argc);
- if (v.type == EINA_VALUE_TYPE_ERROR) goto on_error;

for (i = 0; i < argc; i++)
{
@@ -169,9 +166,10 @@ _efl_loop_arguments_send(void *data, const Eina_Value v,
arge.initialization = EINA_TRUE;
efl_event_callback_call(obj,
EFL_LOOP_EVENT_ARGUMENTS, &arge);
-on_error:
+
while ((s = eina_array_pop(arga))) eina_stringshare_del(s);
eina_array_free(arga);
+
return v;
}

@@ -285,8 +283,8 @@ _efl_thread_main(void *data, Eina_Thread t)
}
for (i = 0; i < thdat->args.argc; i++)
efl_task_arg_append(obj, thdat->args.argv[i]);
- job = eina_future_then(efl_loop_job(obj), _efl_loop_arguments_send, obj);
- efl_future_then(obj, job);
+ efl_future_then(obj, efl_loop_job(obj),
+ .success = _efl_loop_arguments_send);

for (i = 0; i < thdat->args.argc; i++)
eina_stringshare_del(thdat->args.argv[i]);
@@ -780,8 +778,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd)
pd->thdat = thdat;
pd->run = EINA_TRUE;
pd->promise = efl_loop_promise_new(obj, _run_cancel_cb, obj);
- Eina_Future *f = eina_future_new(pd->promise);
- return efl_future_then(obj, f);
+ return efl_future_then(obj, eina_future_new(pd->promise));
}

EOLIAN static void

--

Loading...