efl.task - move to returning future insead of bool + exit event
title says it all...
This commit is contained in:
parent
2a14a283e8
commit
6391a13558
|
@ -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
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -400,6 +390,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)
|
||||
{
|
||||
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue