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

-- 


Reply via email to