From 2995011b344808a8fb6fb7aef1706ab2890da0e4 Mon Sep 17 00:00:00 2001 From: Christian Helmuth Date: Thu, 15 Nov 2012 12:53:32 +0100 Subject: [PATCH] base-linux: implement IPC server destruction When an IPC server is finalized two important things should happen: First, the association of the server socket with a capability must be invalidated. And finally, the server socket pair (server side and client side) must be closed. Related to #38. --- base-linux/src/base/env/platform_env.cc | 9 +++++ base-linux/src/base/ipc/ipc.cc | 51 +++++++++++++++++-------- base-linux/src/core/platform.cc | 11 ++++++ 3 files changed, 56 insertions(+), 15 deletions(-) diff --git a/base-linux/src/base/env/platform_env.cc b/base-linux/src/base/env/platform_env.cc index dc050de514..3b4c890d4a 100644 --- a/base-linux/src/base/env/platform_env.cc +++ b/base-linux/src/base/env/platform_env.cc @@ -14,9 +14,11 @@ #include #include #include +#include using namespace Genode; + /******************************** ** Platform_env::Local_parent ** ********************************/ @@ -124,4 +126,11 @@ namespace Genode { } return ncs; } + + void destroy_server_socket_pair(Native_connection_state const &ncs) + { + /* close local file descriptor if it is valid */ + if (ncs.server_sd != -1) lx_close(ncs.server_sd); + if (ncs.client_sd != -1) lx_close(ncs.client_sd); + } } diff --git a/base-linux/src/base/ipc/ipc.cc b/base-linux/src/base/ipc/ipc.cc index 6b7b06d049..a3fff32402 100644 --- a/base-linux/src/base/ipc/ipc.cc +++ b/base-linux/src/base/ipc/ipc.cc @@ -46,6 +46,28 @@ using namespace Genode; +namespace Genode { + + /* + * Helper for obtaining a bound and connected socket pair + * + * For core, the implementation is just a wrapper around + * 'lx_server_socket_pair()'. For all other processes, the implementation + * requests the socket pair from the Env::CPU session interface using a + * Linux-specific interface extension. + */ + Native_connection_state server_socket_pair(); + + /* + * Helper to destroy the server socket pair + * + * For core, this is a no-op. For all other processes, the server and client + * sockets are closed. + */ + void destroy_server_socket_pair(Native_connection_state const &ncs); +} + + /****************************** ** File-descriptor registry ** ******************************/ @@ -390,7 +412,20 @@ Ipc_istream::Ipc_istream(Msgbuf_base *rcv_msg) { } -Ipc_istream::~Ipc_istream() { } +Ipc_istream::~Ipc_istream() +{ + /* + * The association of the capability (client) socket must be invalidated on + * server destruction. We implement it here as the IPC server currently has + * no destructor. We have the plan to remove Ipc_istream and Ipc_ostream + * in the future and, then, move this into the server destructor. + * + * IPC clients have -1 as client_sd and need no disassociation. + */ + if (_rcv_cs.client_sd != -1) + Genode::ep_sd_registry()->disassociate(_rcv_cs.client_sd); + destroy_server_socket_pair(_rcv_cs); +} /**************** @@ -503,20 +538,6 @@ void Ipc_server::_reply_wait() } -namespace Genode { - - /* - * Helper for obtaining a bound and connected socket pair - * - * For core, the implementation is just a wrapper around - * 'lx_server_socket_pair()'. For all other processes, the implementation - * requests the socket pair from the Env::CPU session interface using a - * Linux-specific interface extension. - */ - Native_connection_state server_socket_pair(); -} - - Ipc_server::Ipc_server(Msgbuf_base *snd_msg, Msgbuf_base *rcv_msg) : Ipc_istream(rcv_msg), diff --git a/base-linux/src/core/platform.cc b/base-linux/src/core/platform.cc index 5b003c4ef7..dfb1ff13fc 100644 --- a/base-linux/src/core/platform.cc +++ b/base-linux/src/core/platform.cc @@ -73,5 +73,16 @@ namespace Genode { { return create_server_socket_pair(Thread_base::myself()->tid().tid); } + + void destroy_server_socket_pair(Native_connection_state const &ncs) + { + /* + * As entrypoints in core are never destructed, this function is only + * called on IPC-client destruction. In this case, it's a no-op in core + * as well as in Genode processes. + */ + if (ncs.server_sd != -1 || ncs.client_sd != -1) + PERR("%s called for IPC server which should never happen", __func__); + } }