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.
This commit is contained in:
Carsten Haitzler 2018-03-06 18:31:48 +09:00
parent f5b0cd2b3b
commit 1ac60fe022
6 changed files with 94 additions and 53 deletions

View File

@ -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;
};

View File

@ -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);

View File

@ -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 {

View File

@ -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)
{

View File

@ -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 ]]

View File

@ -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");