linux: Remove socket member from 'Native_thread'

The only information needed per thread is whether the thread plays the
role of an 'Ipc_server' or not. We encode this information using a bool
value.
This commit is contained in:
Norman Feske 2012-07-26 19:22:55 +02:00
parent b01a1a92cc
commit 8b343d7e1a
3 changed files with 44 additions and 27 deletions

View File

@ -74,7 +74,7 @@ namespace Genode {
*/
struct Native_thread : Native_thread_id
{
int socket; /* server-entrypoint socket */
bool is_ipc_server;
/**
* Opaque pointer to additional thread-specific meta data
@ -85,7 +85,7 @@ namespace Genode {
*/
Thread_meta_data *meta_data;
Native_thread() : socket(-1), meta_data(0) { }
Native_thread() : is_ipc_server(false), meta_data(0) { }
};
inline bool operator == (Native_thread_id t1, Native_thread_id t2) {

View File

@ -203,10 +203,33 @@ void Ipc_server::_reply_wait()
Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg)
: Ipc_istream(rcv_msg),
Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false)
:
Ipc_istream(rcv_msg),
Ipc_ostream(Native_capability(), snd_msg), _reply_needed(false)
{
Thread_base *thread = Thread_base::myself();
/*
* If 'thread' is 0, the constructor was called by the main thread. By
* definition, main is never an RPC entrypoint. However, the main thread
* may call 'sleep_forever()', which instantiates 'Ipc_server'.
*/
if (thread && thread->tid().is_ipc_server) {
PRAW("unexpected multiple instantiation of Ipc_server by one thread");
struct Ipc_server_multiple_instance { };
throw Ipc_server_multiple_instance();
}
_rcv_cs = lx_server_socket(Thread_base::myself());
if (_rcv_cs < 0) {
PRAW("lx_server_socket failed (error %d)", _rcv_cs);
struct Ipc_socket_creation_failed { };
throw Ipc_socket_creation_failed();
}
if (thread)
thread->tid().is_ipc_server = true;
_prepare_next_reply_wait();
}

View File

@ -3,13 +3,8 @@
* \author Christian Helmuth
* \date 2012-01-17
*
* We create two sockets under lx_rpath() for each thread: client and server
* role. The naming is 'ep-<thread id>-<role>'. The socket descriptors are
* cached in Thread_base::_tid.
*
* Currently two socket files are needed, as the client does not send the reply
* socket access-rights in a combined message with the payload. In the future,
* only server sockets must be bound in lx_rpath().
* We create one socket under lx_rpath() for each 'Ipc_server'. The naming is
* 'ep-<thread id>-<role>'.
*/
/*
@ -146,29 +141,28 @@ namespace {
*/
static int lx_server_socket(Genode::Thread_base *thread)
{
int sd = lx_socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sd < 0)
return sd;
/*
* Main thread uses Ipc_server for sleep_forever() only.
* Main thread uses 'Ipc_server' for 'sleep_forever()' only. No need
* for binding.
*/
if (!thread)
return lx_socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
return sd;
if (thread->tid().socket == -1) {
int sd = lx_socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0);
if (sd < 0) return -1;
sockaddr_un addr;
lx_create_server_addr(&addr, thread->tid().tid);
sockaddr_un addr;
lx_create_server_addr(&addr, thread->tid().tid);
/* make sure bind succeeds */
lx_unlink(addr.sun_path);
/* make sure bind succeeds */
lx_unlink(addr.sun_path);
int const bind_ret = lx_bind(sd, (sockaddr *)&addr, sizeof(addr));
if (bind_ret < 0)
return bind_ret;
if (lx_bind(sd, (sockaddr *)&addr, sizeof(addr)) < 0)
return -2;
thread->tid().socket = sd;
}
return thread->tid().socket;
return sd;
}