mirror of
https://github.com/genodelabs/genode.git
synced 2025-05-25 19:54:26 +00:00
This patch improves the life-time management of socket descriptors and addresses several corner cases exposed by the 'bomb' test. The lookup and association of file descriptors with global IDs have been turned into an atomic operation. Otherwise, multiple threads interacting with the singleton 'ep_sd_registry' may override each other's associations. Closing the socket pair used for the reply channel has been implemented via the RAII pattern to capture all corner cases, in particular exceptions. If blocking operations are interrupted by signals, we throw a 'Blocking_canceled' exception. We preserve core's socket descriptor at 'PARENT_SOCKET_HANDLE' to avoid a corner case where the parent capability is going to dup2'ed to the same handle. Support for 'Thread_base::join' within core to enable leaving Genode via Control-C.
62 lines
1.3 KiB
C++
62 lines
1.3 KiB
C++
/*
|
|
* \brief Implementation of the core-internal Thread API via Linux threads
|
|
* \author Norman Feske
|
|
* \date 2006-06-13
|
|
*/
|
|
|
|
/*
|
|
* Copyright (C) 2006-2012 Genode Labs GmbH
|
|
*
|
|
* This file is part of the Genode OS framework, which is distributed
|
|
* under the terms of the GNU General Public License version 2.
|
|
*/
|
|
|
|
/* Genode includes */
|
|
#include <base/thread.h>
|
|
#include <base/sleep.h>
|
|
|
|
/* Linux syscall bindings */
|
|
#include <linux_syscalls.h>
|
|
|
|
using namespace Genode;
|
|
|
|
|
|
static void empty_signal_handler(int) { }
|
|
|
|
|
|
void Thread_base::_thread_start()
|
|
{
|
|
/*
|
|
* Set signal handler such that canceled system calls get not
|
|
* transparently retried after a signal gets received.
|
|
*/
|
|
lx_sigaction(LX_SIGUSR1, empty_signal_handler);
|
|
|
|
/*
|
|
* Prevent children from becoming zombies. (SIG_IGN = 1)
|
|
*/
|
|
lx_sigaction(LX_SIGCHLD, (void (*)(int))1);
|
|
|
|
Thread_base::myself()->entry();
|
|
Thread_base::myself()->_join_lock.unlock();
|
|
sleep_forever();
|
|
}
|
|
|
|
|
|
void Thread_base::_init_platform_thread() { }
|
|
|
|
|
|
void Thread_base::_deinit_platform_thread() { }
|
|
|
|
|
|
void Thread_base::start()
|
|
{
|
|
/* align initial stack to 16 byte boundary */
|
|
void *thread_sp = (void *)((addr_t)(_context->stack) & ~0xf);
|
|
_tid.tid = lx_create_thread(Thread_base::_thread_start, thread_sp, this);
|
|
_tid.pid = lx_getpid();
|
|
}
|
|
|
|
|
|
void Thread_base::cancel_blocking() { }
|