From 1ac60fe022b1cf8f5ebd8c9a016af1a4367be541 Mon Sep 17 00:00:00 2001 From: "Carsten Haitzler (Rasterman)" Date: Tue, 6 Mar 2018 18:31:48 +0900 Subject: [PATCH] ecore efl exe/task/thread - move stdin/out flags to task class also use them in efl thread to determine if io handlers are set up and pipes created at all etc. --- src/lib/ecore/ecore_private.h | 1 + src/lib/ecore/efl_exe.c | 30 ++++++------- src/lib/ecore/efl_exe.eo | 6 +-- src/lib/ecore/efl_task.c | 12 +++++ src/lib/ecore/efl_task.eo | 14 ++++++ src/lib/ecore/efl_thread.c | 84 +++++++++++++++++++++-------------- 6 files changed, 94 insertions(+), 53 deletions(-) diff --git a/src/lib/ecore/ecore_private.h b/src/lib/ecore/ecore_private.h index 7e44bf4acb..847a8b42b0 100644 --- a/src/lib/ecore/ecore_private.h +++ b/src/lib/ecore/ecore_private.h @@ -190,6 +190,7 @@ struct _Efl_Task_Data Eina_Hash *env; Efl_Task_Priority priority; int exit_code; + Efl_Task_Flags flags; Eina_Bool command_dirty : 1; Eina_Bool exited : 1; }; diff --git a/src/lib/ecore/efl_exe.c b/src/lib/ecore/efl_exe.c index 0df9ede462..4ef0aee967 100644 --- a/src/lib/ecore/efl_exe.c +++ b/src/lib/ecore/efl_exe.c @@ -41,6 +41,7 @@ typedef struct _Efl_Exe_Data Efl_Exe_Data; struct _Efl_Exe_Data { int exit_signal; + Efl_Exe_Flags flags; #ifdef _WIN32 struct { Eo *in_handler, *out_handler; @@ -60,7 +61,6 @@ struct _Efl_Exe_Data } fd; #endif Eina_Bool exit_called : 1; - Efl_Exe_Flags flags; }; ////////////////////////////////////////////////////////////////////////// @@ -282,13 +282,13 @@ _efl_exe_signal(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd, Efl_Exe_Signal sig) } EOLIAN static void -_efl_exe_flags_set(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd, Efl_Exe_Flags flags) +_efl_exe_exe_flags_set(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd, Efl_Exe_Flags flags) { pd->flags = flags; } EOLIAN static Efl_Exe_Flags -_efl_exe_flags_get(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) +_efl_exe_exe_flags_get(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) { return pd->flags; } @@ -381,7 +381,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) pd->fd.exited_write = pipe_exited[1]; eina_file_close_on_exec(pd->fd.exited_read, EINA_TRUE); - if (pd->flags & EFL_EXE_FLAGS_USE_STDIN) + if (td->flags & EFL_TASK_FLAGS_USE_STDIN) { ret = pipe(pipe_stdin); if (EINA_UNLIKELY(ret != 0)) @@ -399,7 +399,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) efl_event_callback_add (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_exe_in, obj)); } - if (pd->flags & EFL_EXE_FLAGS_USE_STDOUT) + if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) { ret = pipe(pipe_stdout); if (EINA_UNLIKELY(ret != 0)) @@ -425,8 +425,8 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) if (pd->pid != 0) { // parent process is here inside this if block - if (pd->flags & EFL_EXE_FLAGS_USE_STDIN) close(pipe_stdin[0]); - if (pd->flags & EFL_EXE_FLAGS_USE_STDOUT) close(pipe_stdout[1]); + if (td->flags & EFL_TASK_FLAGS_USE_STDIN) close(pipe_stdin[0]); + if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) close(pipe_stdout[1]); // fork failed... close up and clean and release locks if (pd->pid == -1) { @@ -450,24 +450,24 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) // this code is in the child here, and is temporary setup until we // exec() the child to replace everything. - if (pd->flags & EFL_EXE_FLAGS_USE_STDIN) close(pipe_stdin[1]); - if (pd->flags & EFL_EXE_FLAGS_USE_STDOUT) close(pipe_stdout[0]); + if (td->flags & EFL_TASK_FLAGS_USE_STDIN) close(pipe_stdin[1]); + if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) close(pipe_stdout[0]); // set priority of self if ((td->priority >= EFL_TASK_PRIORITY_NORMAL) && (td->priority <= EFL_TASK_PRIORITY_ULTRA)) setpriority(PRIO_PROCESS, 0, primap[td->priority]); // if we want to hide or use any of the stdio, close the fd's - if ((pd->flags & EFL_EXE_FLAGS_USE_STDIN) || + if ((td->flags & EFL_TASK_FLAGS_USE_STDIN) || (pd->flags & EFL_EXE_FLAGS_HIDE_IO)) close(STDIN_FILENO); - if ((pd->flags & EFL_EXE_FLAGS_USE_STDOUT) || + if ((td->flags & EFL_TASK_FLAGS_USE_STDOUT) || (pd->flags & EFL_EXE_FLAGS_HIDE_IO)) close(STDOUT_FILENO); if ((pd->flags & EFL_EXE_FLAGS_HIDE_IO)) close(STDERR_FILENO); - if (!(pd->flags & EFL_EXE_FLAGS_USE_STDIN) && + if (!(td->flags & EFL_TASK_FLAGS_USE_STDIN) && (pd->flags & EFL_EXE_FLAGS_HIDE_IO)) { // hide stdin @@ -475,14 +475,14 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) dup2(devnull, STDIN_FILENO); close(devnull); } - else if ((pd->flags & EFL_EXE_FLAGS_USE_STDIN)) + else if ((td->flags & EFL_TASK_FLAGS_USE_STDIN)) { // hook up stdin to the pipe going to the parent dup2(pipe_stdin[0], STDIN_FILENO); close(pipe_stdin[0]); } - if (!(pd->flags & EFL_EXE_FLAGS_USE_STDOUT) && + if (!(td->flags & EFL_TASK_FLAGS_USE_STDOUT) && (pd->flags & EFL_EXE_FLAGS_HIDE_IO)) { // hide stdout @@ -490,7 +490,7 @@ _efl_exe_efl_task_run(Eo *obj EINA_UNUSED, Efl_Exe_Data *pd) dup2(devnull, STDOUT_FILENO); close(devnull); } - else if ((pd->flags & EFL_EXE_FLAGS_USE_STDOUT)) + else if ((td->flags & EFL_TASK_FLAGS_USE_STDOUT)) { // hook up stdout to the pipe going to the parent dup2(pipe_stdout[1], STDOUT_FILENO); diff --git a/src/lib/ecore/efl_exe.eo b/src/lib/ecore/efl_exe.eo index 5fd91d329b..4fd5854fa4 100644 --- a/src/lib/ecore/efl_exe.eo +++ b/src/lib/ecore/efl_exe.eo @@ -19,9 +19,7 @@ enum Efl.Exe.Flags { none = 0, group_leader = 1, exit_with_parent = 2, - hide_io = 4, - use_stdin = 8, - use_stdout = 16, + hide_io = 4 } class Efl.Exe (Efl.Task) @@ -33,7 +31,7 @@ class Efl.Exe (Efl.Task) sig: Efl.Exe.Signal; [[ Send this signal to the task ]] } } - @property flags { + @property exe_flags { set { } get { } values { diff --git a/src/lib/ecore/efl_task.c b/src/lib/ecore/efl_task.c index d269773117..3a20636cea 100644 --- a/src/lib/ecore/efl_task.c +++ b/src/lib/ecore/efl_task.c @@ -368,6 +368,18 @@ _efl_task_exit_code_get(Eo *obj EINA_UNUSED, Efl_Task_Data *pd) return pd->exit_code; } +EOLIAN static void +_efl_task_flags_set(Eo *obj EINA_UNUSED, Efl_Task_Data *pd, Efl_Task_Flags flags) +{ + pd->flags = flags; +} + +EOLIAN static Efl_Task_Flags +_efl_task_flags_get(Eo *obj EINA_UNUSED, Efl_Task_Data *pd) +{ + return pd->flags; +} + EOLIAN static Eina_Bool _efl_task_run(Eo *obj EINA_UNUSED, Efl_Task_Data *pd EINA_UNUSED) { diff --git a/src/lib/ecore/efl_task.eo b/src/lib/ecore/efl_task.eo index 26ecb4b5a5..ae9afcbc44 100644 --- a/src/lib/ecore/efl_task.eo +++ b/src/lib/ecore/efl_task.eo @@ -10,6 +10,13 @@ enum Efl.Task.Priority { ultra } +enum Efl.Task.Flags { + [[ ]] + none = 0, + use_stdin = 1, + use_stdout = 2 +} + class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) { [[ ]] @@ -126,6 +133,13 @@ class Efl.Task (Efl.Object, Efl.Io.Reader, Efl.Io.Writer, Efl.Io.Closer) code: int; [[ ]] } } + @property flags { + set { } + get { } + values { + flags: Efl.Task.Flags; [[ ]] + } + } run { [[ Actually run the task ]] return: bool; [[ True if ir started to run, false otherwise ]] diff --git a/src/lib/ecore/efl_thread.c b/src/lib/ecore/efl_thread.c index ffd4f4756f..83c7017b79 100644 --- a/src/lib/ecore/efl_thread.c +++ b/src/lib/ecore/efl_thread.c @@ -524,7 +524,9 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) int pipe_from_thread[2]; unsigned int argc, i, num; Efl_Callback_Array_Item_Full *it; + Efl_Task_Data *td = efl_data_scope_get(obj, EFL_TASK_CLASS); + if (!td) return EINA_FALSE; thdat = calloc(1, sizeof(Thread_Data)); if (!thdat) return EINA_FALSE; thdat->fd.in = -1; @@ -532,45 +534,59 @@ _efl_thread_efl_task_run(Eo *obj, Efl_Thread_Data *pd) thdat->ctrl.in = -1; thdat->ctrl.out = -1; - if (pipe(pipe_to_thread) != 0) + // input/output pipes + if (td->flags & EFL_TASK_FLAGS_USE_STDIN) { - ERR("Can't create to_thread pipe"); - free(thdat); - return EINA_FALSE; + if (pipe(pipe_to_thread) != 0) + { + ERR("Can't create to_thread pipe"); + free(thdat); + return EINA_FALSE; + } } - if (pipe(pipe_from_thread) != 0) + if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) { - ERR("Can't create from_thread pipe"); - close(pipe_to_thread[0]); - close(pipe_to_thread[1]); - free(thdat); - return EINA_FALSE; + if (pipe(pipe_from_thread) != 0) + { + ERR("Can't create from_thread pipe"); + close(pipe_to_thread[0]); + close(pipe_to_thread[1]); + free(thdat); + return EINA_FALSE; + } + } + if (td->flags & EFL_TASK_FLAGS_USE_STDIN) + { + thdat->fd.in = pipe_from_thread[1]; // write - input to parent + pd->fd.out = pipe_from_thread[0]; // read - output from child + eina_file_close_on_exec(thdat->fd.in, EINA_TRUE); + eina_file_close_on_exec(pd->fd.out, EINA_TRUE); + fcntl(thdat->fd.in, F_SETFL, O_NONBLOCK); + fcntl(pd->fd.out, F_SETFL, O_NONBLOCK); + pd->fd.out_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->fd.out), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_parent_out, obj)); + if (pd->read_listeners > 0) + efl_loop_handler_active_set(pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ); + } + if (td->flags & EFL_TASK_FLAGS_USE_STDOUT) + { + pd->fd.in = pipe_to_thread [1]; // write - input to child + thdat->fd.out = pipe_to_thread [0]; // read - output from parent + eina_file_close_on_exec(pd->fd.in, EINA_TRUE); + eina_file_close_on_exec(thdat->fd.out, EINA_TRUE); + fcntl(thdat->fd.out, F_SETFL, O_NONBLOCK); + fcntl(pd->fd.in, F_SETFL, O_NONBLOCK); + pd->fd.in_handler = + efl_add(EFL_LOOP_HANDLER_CLASS, obj, + efl_loop_handler_fd_set(efl_added, pd->fd.in), + efl_event_callback_add + (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_thread_parent_in, obj)); } - thdat->fd.in = pipe_from_thread[1]; // write - input to parent - thdat->fd.out = pipe_to_thread [0]; // read - output from parent - pd->fd.in = pipe_to_thread [1]; // write - input to child - pd->fd.out = pipe_from_thread[0]; // read - output from child - eina_file_close_on_exec(pd->fd.in, EINA_TRUE); - eina_file_close_on_exec(pd->fd.out, EINA_TRUE); - eina_file_close_on_exec(thdat->fd.in, EINA_TRUE); - eina_file_close_on_exec(thdat->fd.out, EINA_TRUE); - fcntl(pd->fd.in, F_SETFL, O_NONBLOCK); - fcntl(pd->fd.out, F_SETFL, O_NONBLOCK); - fcntl(thdat->fd.in, F_SETFL, O_NONBLOCK); - fcntl(thdat->fd.out, F_SETFL, O_NONBLOCK); - pd->fd.in_handler = - efl_add(EFL_LOOP_HANDLER_CLASS, obj, - efl_loop_handler_fd_set(efl_added, pd->fd.in), - efl_event_callback_add - (efl_added, EFL_LOOP_HANDLER_EVENT_WRITE, _cb_thread_parent_in, obj)); - pd->fd.out_handler = - efl_add(EFL_LOOP_HANDLER_CLASS, obj, - efl_loop_handler_fd_set(efl_added, pd->fd.out), - efl_event_callback_add - (efl_added, EFL_LOOP_HANDLER_EVENT_READ, _cb_thread_parent_out, obj)); - if (pd->read_listeners > 0) - efl_loop_handler_active_set(pd->fd.out_handler, EFL_LOOP_HANDLER_FLAGS_READ); + // control pipes if (pipe(pipe_to_thread) != 0) { ERR("Can't create to_thread control pipe");