base-linux: let core catch SIGCHLD signals

This commit is contained in:
Norman Feske 2013-01-03 13:20:24 +01:00
parent 62e0dd579e
commit 38272b9172
5 changed files with 51 additions and 15 deletions

View File

@ -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 */

View File

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

View File

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

View File

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

View File

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