mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-11 21:13:09 +00:00
base-linux: let core catch SIGCHLD signals
This commit is contained in:
parent
62e0dd579e
commit
38272b9172
@ -48,11 +48,6 @@ void Thread_base::_thread_start()
|
|||||||
*/
|
*/
|
||||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||||
|
|
||||||
/*
|
|
||||||
* Prevent children from becoming zombies. (SIG_IGN = 1)
|
|
||||||
*/
|
|
||||||
lx_sigaction(LX_SIGCHLD, (void (*)(int))1);
|
|
||||||
|
|
||||||
Thread_base * const thread = Thread_base::myself();
|
Thread_base * const thread = Thread_base::myself();
|
||||||
|
|
||||||
/* inform core about the new thread and process ID of the new thread */
|
/* inform core about the new thread and process ID of the new thread */
|
||||||
|
@ -80,7 +80,12 @@ inline int lx_kill(int pid, int signal)
|
|||||||
|
|
||||||
inline int lx_create_process(int (*entry)(void *), void *stack, void *arg)
|
inline int lx_create_process(int (*entry)(void *), void *stack, void *arg)
|
||||||
{
|
{
|
||||||
int flags = CLONE_VFORK | SIGCHLD;
|
/*
|
||||||
|
* The low byte of the flags denotes the signal to be sent to the parent
|
||||||
|
* when the process terminates. We want core to receive SIGCHLD signals on
|
||||||
|
* this condition.
|
||||||
|
*/
|
||||||
|
int const flags = CLONE_VFORK | LX_SIGCHLD;
|
||||||
return lx_clone((int (*)(void *))entry, stack, flags, arg);
|
return lx_clone((int (*)(void *))entry, stack, flags, arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,11 +32,20 @@ using namespace Genode;
|
|||||||
*/
|
*/
|
||||||
static char _core_mem[80*1024*1024];
|
static char _core_mem[80*1024*1024];
|
||||||
static Lock _wait_for_exit_lock(Lock::LOCKED); /* exit() sync */
|
static Lock _wait_for_exit_lock(Lock::LOCKED); /* exit() sync */
|
||||||
|
static bool _do_exit = false;
|
||||||
|
|
||||||
|
|
||||||
static void signal_handler(int signum)
|
static void sigint_handler(int signum)
|
||||||
{
|
{
|
||||||
_wait_for_exit_lock.unlock();
|
_wait_for_exit_lock.unlock();
|
||||||
|
_do_exit = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void sigchld_handler(int signnum)
|
||||||
|
{
|
||||||
|
_wait_for_exit_lock.unlock();
|
||||||
|
raw_write_str("sigchld_handler called\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +53,10 @@ Platform::Platform()
|
|||||||
: _core_mem_alloc(0)
|
: _core_mem_alloc(0)
|
||||||
{
|
{
|
||||||
/* catch control-c */
|
/* catch control-c */
|
||||||
lx_sigaction(2, signal_handler);
|
lx_sigaction(LX_SIGINT, sigint_handler);
|
||||||
|
|
||||||
|
/* catch SIGCHLD */
|
||||||
|
lx_sigaction(LX_SIGCHLD, sigchld_handler);
|
||||||
|
|
||||||
/* create resource directory under /tmp */
|
/* create resource directory under /tmp */
|
||||||
lx_mkdir(resource_path(), S_IRWXU);
|
lx_mkdir(resource_path(), S_IRWXU);
|
||||||
@ -64,9 +76,29 @@ Platform::Platform()
|
|||||||
|
|
||||||
void Platform::wait_for_exit()
|
void Platform::wait_for_exit()
|
||||||
{
|
{
|
||||||
/* block until exit condition is satisfied */
|
for (;;) {
|
||||||
try { _wait_for_exit_lock.lock(); }
|
|
||||||
catch (Blocking_canceled) { };
|
/*
|
||||||
|
* Block until a signal occurs.
|
||||||
|
*/
|
||||||
|
try { _wait_for_exit_lock.lock(); }
|
||||||
|
catch (Blocking_canceled) { };
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Each time, the '_wait_for_exit_lock' gets unlocked, we could have
|
||||||
|
* received either a SIGINT or SIGCHLD. If a SIGINT was received, the
|
||||||
|
* '_exit' condition will be set.
|
||||||
|
*/
|
||||||
|
if (_do_exit)
|
||||||
|
return;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we received a SIGCHLD, we go through the list of our children to
|
||||||
|
* catch any pending terminated children.
|
||||||
|
*/
|
||||||
|
|
||||||
|
PINF("we should check for pending terminated children");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,15 +27,18 @@ static void empty_signal_handler(int) { }
|
|||||||
void Thread_base::_thread_start()
|
void Thread_base::_thread_start()
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Set signal handler such that canceled system calls get not
|
* Set signal handler such that canceled system calls get not transparently
|
||||||
* transparently retried after a signal gets received.
|
* retried after a signal gets received.
|
||||||
*/
|
*/
|
||||||
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prevent children from becoming zombies. (SIG_IGN = 1)
|
* Deliver SIGCHLD signals to no thread other than the main thread. Core's
|
||||||
|
* main thread will handle the signals while executing the 'wait_for_exit'
|
||||||
|
* function, which is known to not hold any locks that would interfere with
|
||||||
|
* the handling of the signal.
|
||||||
*/
|
*/
|
||||||
lx_sigaction(LX_SIGCHLD, (void (*)(int))1);
|
lx_sigsetmask(LX_SIGCHLD, false);
|
||||||
|
|
||||||
Thread_base::myself()->entry();
|
Thread_base::myself()->entry();
|
||||||
Thread_base::myself()->_join_lock.unlock();
|
Thread_base::myself()->_join_lock.unlock();
|
||||||
|
@ -237,6 +237,7 @@ inline Genode::addr_t lx_vm_reserve(Genode::addr_t base, Genode::size_t size)
|
|||||||
***********************************************************************/
|
***********************************************************************/
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
LX_SIGINT = 2, /* used by core to catch Control-C */
|
||||||
LX_SIGUSR1 = 10, /* used for cancel-blocking mechanism */
|
LX_SIGUSR1 = 10, /* used for cancel-blocking mechanism */
|
||||||
LX_SIGCHLD = 17, /* child process changed state, i.e., terminated */
|
LX_SIGCHLD = 17, /* child process changed state, i.e., terminated */
|
||||||
LX_SIGCANCEL = 32, /* accoring to glibc, this equals SIGRTMIN,
|
LX_SIGCANCEL = 32, /* accoring to glibc, this equals SIGRTMIN,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user