raster pushed a commit to branch master. http://git.enlightenment.org/core/efl.git/commit/?id=6391a135583eec3e785da0fbe505ec963019aa1e
commit 6391a135583eec3e785da0fbe505ec963019aa1e Author: Carsten Haitzler (Rasterman) <[email protected]> Date: Tue Mar 20 20:43:47 2018 +0900 efl.task - move to returning future insead of bool + exit event title says it all... --- src/lib/ecore/ecore_signal.c | 2 +- src/lib/ecore/efl_exe.c | 58 ++++++++++++++++++++++--------------------- src/lib/ecore/efl_loop.c | 11 ++++++--- src/lib/ecore/efl_loop.eo | 1 + src/lib/ecore/efl_task.c | 4 +-- src/lib/ecore/efl_task.eo | 3 +-- src/lib/ecore/efl_thread.c | 59 ++++++++++++++++++++++---------------------- 7 files changed, 73 insertions(+), 65 deletions(-) diff --git a/src/lib/ecore/ecore_signal.c b/src/lib/ecore/ecore_signal.c index 616f22b4ee..f415c45453 100644 --- a/src/lib/ecore/ecore_signal.c +++ b/src/lib/ecore/ecore_signal.c @@ -114,7 +114,7 @@ _ecore_signal_pipe_read(Eo *obj) } Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); if (loop) - efl_event_callback_call(loop, EFL_TASK_EVENT_EXIT, NULL); + efl_event_callback_call(loop, EFL_LOOP_EVENT_QUIT, NULL); } break; #ifdef SIGPWR diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c index 273b97532e..581c570100 100644 --- a/src/lib/ecore/efl_exe.c +++ b/src/lib/ecore/efl_exe.c @@ -50,6 +50,7 @@ struct _Efl_Exe_Data Eina_Bool can_write : 1; } fd; #else + Eina_Promise *promise; Eo *exit_handler; pid_t pid; struct { @@ -180,30 +181,20 @@ _foreach_env(const Eina_Hash *hash EINA_UNUSED, const void *key, void *data, voi return EINA_TRUE; } -static Eina_Value -_efl_loop_task_exit(void *data, const Eina_Value v, - const Eina_Future *dead EINA_UNUSED) -{ - Eo *obj = data; - - efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); - efl_unref(obj); - return v; -} - static void _exe_exit_eval(Eo *obj, Efl_Exe_Data *pd) { if ((pd->fd.out == -1) && /*(pd->fd.in == -1) &&*/ (pd->fd.exited_read == -1) && (!pd->exit_called)) { - Eina_Future *job; - Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); - pd->exit_called = EINA_TRUE; - efl_ref(obj); - job = eina_future_then(efl_loop_job(loop), _efl_loop_task_exit, obj); - efl_future_Eina_FutureXXX_then(obj, job); + if (pd->promise) + { + int exit_code = efl_task_exit_code_get(obj); + if (exit_code != 0) eina_promise_reject(pd->promise, exit_code + 1000000); + else eina_promise_resolve(pd->promise, eina_value_int_init(0)); + pd->promise = NULL; + } } } @@ -253,6 +244,15 @@ _cb_exe_in(void *data, const Efl_Event *event EINA_UNUSED) Eo *obj = data; efl_io_writer_can_write_set(obj, EINA_TRUE); } + +static void +_run_cancel_cb(void *data, const Eina_Promise *dead_promise EINA_UNUSED) +{ + Eo *obj = data; + Efl_Exe_Data *pd = efl_data_scope_get(obj, MY_CLASS); + pd->promise = NULL; + efl_task_end(obj); +} #endif ////////////////////////////////////////////////////////////////////////// @@ -347,7 +347,7 @@ _efl_exe_efl_task_priority_get(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) return pri; } -EOLIAN static Eina_Bool +EOLIAN static Eina_Future * _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) { #ifdef _WIN32 @@ -362,20 +362,20 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) int pipe_exited[2]; int ret; - if (pd->run) return EINA_FALSE; - if (pd->pid != -1) return EINA_FALSE; - if (!td) return EINA_FALSE; + if (pd->run) return NULL; + if (pd->pid != -1) return NULL; + if (!td) return NULL; // get a cmdline to run cmd = efl_task_command_get(obj); - if (!cmd) return EINA_FALSE; + if (!cmd) return NULL; ret = pipe(pipe_exited); if (EINA_UNLIKELY(ret != 0)) { const int error = errno; ERR("pipe() failed: %s", strerror(error)); - return EINA_FALSE; + return NULL; } pd->fd.exited_read = pipe_exited[0]; @@ -390,7 +390,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) { const int error = errno; ERR("pipe() failed: %s", strerror(error)); - return EINA_FALSE; + return NULL; } pd->fd.in = pipe_stdin[1]; fcntl(pd->fd.in, F_SETFL, O_NONBLOCK); @@ -408,7 +408,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) { const int error = errno; ERR("pipe() failed: %s", strerror(error)); - return EINA_FALSE; + return NULL; } pd->fd.out = pipe_stdout[0]; fcntl(pd->fd.out, F_SETFL, O_NONBLOCK); @@ -434,7 +434,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) { _close_fds(pd); _ecore_signal_pid_unlock(); - return EINA_FALSE; + return NULL; } // register this pid in the core sigchild/pid exit code watcher _ecore_signal_pid_register(pd->pid, pd->fd.exited_write); @@ -448,7 +448,9 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) EFL_LOOP_HANDLER_FLAGS_READ)); _ecore_signal_pid_unlock(); pd->run = EINA_TRUE; - return EINA_TRUE; + pd->promise = efl_loop_promise_new(obj, _run_cancel_cb, obj); + Eina_Future *f = eina_future_new(pd->promise); + return efl_future_Eina_FutureXXX_then(obj, f); } // this code is in the child here, and is temporary setup until we // exec() the child to replace everything. @@ -531,7 +533,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) _exec(cmd, pd->flags); // we couldn't exec... uh oh. HAAAAAAAALP! exit(-122); - return EINA_FALSE; + return NULL; #endif } diff --git a/src/lib/ecore/efl_loop.c b/src/lib/ecore/efl_loop.c index 3dc22ea5da..bd98def518 100644 --- a/src/lib/ecore/efl_loop.c +++ b/src/lib/ecore/efl_loop.c @@ -893,7 +893,7 @@ _efl_loop_efl_task_env_reset(Eo *obj EINA_UNUSED, Efl_Loop_Data *pd) eina_lock_release(&_environ_lock); } -EOLIAN static Eina_Bool +EOLIAN static Eina_Future * _efl_loop_efl_task_run(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) { Eina_Value *ret; @@ -901,8 +901,13 @@ _efl_loop_efl_task_run(Eo *obj, Efl_Loop_Data *pd EINA_UNUSED) ret = efl_loop_begin(obj); real = efl_loop_exit_code_process(ret); - if (real == 0) return EINA_TRUE; - return EINA_FALSE; + if (real == 0) + { + // we never return a valid future here because there is no loop + // any more to process the future callback as we would have quit + return NULL; + } + return NULL; } EOLIAN static void diff --git a/src/lib/ecore/efl_loop.eo b/src/lib/ecore/efl_loop.eo index 6531086fd8..5ff89fe3ed 100644 --- a/src/lib/ecore/efl_loop.eo +++ b/src/lib/ecore/efl_loop.eo @@ -121,6 +121,7 @@ class Efl.Loop (Efl.Task) poll,high; [[Event occurs multiple times per second. The exact tick is undefined and can be adjusted system wide.]] poll,medium; [[Event occurs multiple times per minute. The exact tick is undefined and can be adjusted system wide.]] poll,low; [[Event occurs multiple times every 15 minutes. The exact tick is undefined and can be adjusted system wide.]] + quit; [[Event occurs when the loop was requested to quit externally e.g. by a ctrl+c signal or a request from a parent loop/thread to have the child exit.]] } implements { Efl.Object.constructor; diff --git a/src/lib/ecore/efl_task.c b/src/lib/ecore/efl_task.c index 3a20636cea..b4d3c188fd 100644 --- a/src/lib/ecore/efl_task.c +++ b/src/lib/ecore/efl_task.c @@ -380,11 +380,11 @@ _efl_task_flags_get(Eo *obj EINA_UNUSED, Efl_Task_Data *pd) return pd->flags; } -EOLIAN static Eina_Bool +EOLIAN static Eina_Future * _efl_task_run(Eo *obj EINA_UNUSED, Efl_Task_Data *pd EINA_UNUSED) { // NOP - return EINA_FALSE; + return NULL; } EOLIAN static void diff --git a/src/lib/ecore/efl_task.eo b/src/lib/ecore/efl_task.eo index ae9afcbc44..5fbcff6e84 100644 --- a/src/lib/ecore/efl_task.eo +++ b/src/lib/ecore/efl_task.eo @@ -142,7 +142,7 @@ class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) } run { [[ Actually run the task ]] - return: bool; [[ True if ir started to run, false otherwise ]] + return: ptr(Eina.Future) @owned; [[ A future triggered when task exits and is passed int exit code ]] } end { [[ Request the task end (may send a signal or interrupt @@ -151,7 +151,6 @@ class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) } } events { - exit; [[ When the task exits and there is an exit code to get and all IO is finished and can't work anymore ]] } implements { Efl.Object.constructor; diff --git a/src/lib/ecore/efl_thread.c b/src/lib/ecore/efl_thread.c index 6e59602ca9..048a75e967 100644 --- a/src/lib/ecore/efl_thread.c +++ b/src/lib/ecore/efl_thread.c @@ -68,6 +68,7 @@ struct _Efl_Thread_Data Eina_Bool can_write : 1; } fd, ctrl; int read_listeners; + Eina_Promise *promise; Eo *loop; Thread_Data *thdat; Efl_Callback_Array_Item_Full *event_cb; @@ -109,7 +110,7 @@ _cb_thread_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED) { if (cmd.d.command == CMD_EXIT) { - efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); + efl_event_callback_call(obj, EFL_LOOP_EVENT_QUIT, NULL); efl_loop_quit(obj, eina_value_int_init(0)); } else if (cmd.d.command == CMD_CALL) @@ -309,32 +310,21 @@ _efl_thread_main(void *data, Eina_Thread t) ////////////////////////////////////////////////////////////////////////// -static Eina_Value -_efl_loop_task_exit(void *data, const Eina_Value v, - const Eina_Future *dead EINA_UNUSED) - -{ - Eo *obj = data; - - efl_event_callback_call(obj, EFL_TASK_EVENT_EXIT, NULL); - efl_unref(obj); - return v; -} - static void _thread_exit_eval(Eo *obj, Efl_Thread_Data *pd) { if ((pd->fd.out == -1) && /*(pd->fd.in == -1) &&*/ (pd->exit_read) && (!pd->exit_called)) { - Eina_Future *job; - Eo *loop = efl_provider_find(obj, EFL_LOOP_CLASS); - pd->exit_called = EINA_TRUE; - efl_ref(obj); if (pd->thdat) efl_threadio_outdata_set(obj, pd->thdat->outdata); - job = eina_future_then(efl_loop_job(loop), _efl_loop_task_exit, obj); - efl_future_Eina_FutureXXX_then(loop, job); + if (pd->promise) + { + int exit_code = efl_task_exit_code_get(obj); + if (exit_code != 0) eina_promise_reject(pd->promise, exit_code + 1000000); + else eina_promise_resolve(pd->promise, eina_value_int_init(0)); + pd->promise = NULL; + } } } @@ -401,6 +391,15 @@ _cb_thread_parent_ctrl_out(void *data, const Efl_Event *event EINA_UNUSED) ////////////////////////////////////////////////////////////////////////// static void +_run_cancel_cb(void *data, const Eina_Promise *dead_promise EINA_UNUSED) +{ + Eo *obj = data; + Efl_Thread_Data *pd = efl_data_scope_get(obj, MY_CLASS); + pd->promise = NULL; + efl_task_end(obj); +} + +static void _thread_parent_read_listeners_modify(Efl_Thread_Data *pd, int mod) { pd->read_listeners += mod; @@ -571,7 +570,7 @@ _efl_thread_efl_object_parent_set(Eo *obj, Efl_Thread_Data *pd, Efl_Object *pare pd->loop = efl_provider_find(parent, EFL_LOOP_CLASS); } -EOLIAN static Eina_Bool +EOLIAN static Eina_Future * _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) { Eina_Thread_Priority pri; @@ -583,10 +582,10 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) Efl_Callback_Array_Item_Full *it; Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); - if (pd->run) return EINA_FALSE; - if (!td) return EINA_FALSE; + if (pd->run) return NULL; + if (!td) return NULL; thdat = calloc(1, sizeof(Thread_Data)); - if (!thdat) return EINA_FALSE; + if (!thdat) return NULL; thdat->fd.in = -1; thdat->fd.out = -1; thdat->ctrl.in = -1; @@ -602,7 +601,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) { ERR("Can't create to_thread pipe"); free(thdat); - return EINA_FALSE; + return NULL; } } if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) @@ -613,7 +612,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) close(pipe_to_thread[0]); close(pipe_to_thread[1]); free(thdat); - return EINA_FALSE; + return NULL; } } if (td->flags & EFL_TASK_FLAGS_USE_STDIN) @@ -662,7 +661,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) pd->fd.in = -1; pd->fd.out = -1; free(thdat); - return EINA_FALSE; + return NULL; } if (pipe(pipe_from_thread) != 0) { @@ -680,7 +679,7 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) pd->fd.in = -1; pd->fd.out = -1; free(thdat); - return EINA_FALSE; + return NULL; } thdat->ctrl.in = pipe_from_thread[1]; // write - input to parent thdat->ctrl.out = pipe_to_thread [0]; // read - output from parent @@ -782,11 +781,13 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) pd->fd.out = -1; pd->ctrl.in = -1; pd->ctrl.out = -1; - return EINA_FALSE; + return NULL; } pd->thdat = thdat; pd->run = EINA_TRUE; - return EINA_TRUE; + pd->promise = efl_loop_promise_new(obj, _run_cancel_cb, obj); + Eina_Future *f = eina_future_new(pd->promise); + return efl_future_Eina_FutureXXX_then(obj, f); } EOLIAN static void --
