forked from enlightenment/efl
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:
parent
f5b0cd2b3b
commit
1ac60fe022
|
@ -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;
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 ]]
|
||||
|
|
|
@ -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");
|
||||
|
|
Loading…
Reference in New Issue