Closing ticket #4465:

Net_server starts services by invoking fork() followed by exec(). If the latter
fails (for instance because the service isn't installed), the forked child is
invoking exit(). This in turn unloads libbe, triggering static cleanup code in 
BMessage, which deletes a couple of message ports that were inherited from the
parent during the fork. After that, net_server was desparately missing those
ports and no longer worked reliably.
* in InitTerminateLibBe, we now register an atfork-(child-)handler, which
  takes care to re-initialize the static reply ports used by BMessage code
* added BMessage::Private::StaticReInitForkedChild wrapper and 
  BMessage::_StaticReInitForkedChild() implementation which overwrites the
  inherited port IDs with a set of own ports


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33050 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Oliver Tappe 2009-09-10 23:10:51 +00:00
parent d23fdd96cb
commit e0b7c61c46
4 changed files with 37 additions and 0 deletions

View File

@ -339,6 +339,7 @@ class BMessage {
port_id port, int32 token, bigtime_t timeout); port_id port, int32 token, bigtime_t timeout);
static void _StaticInit(); static void _StaticInit();
static void _StaticReInitForkedChild();
static void _StaticCleanup(); static void _StaticCleanup();
static void _StaticCacheCleanup(); static void _StaticCacheCleanup();
static int32 _StaticGetCachedReplyPort(); static int32 _StaticGetCachedReplyPort();

View File

@ -207,6 +207,12 @@ class BMessage::Private {
BMessage::_StaticInit(); BMessage::_StaticInit();
} }
static void
StaticReInitForkedChild()
{
BMessage::_StaticReInitForkedChild();
}
static void static void
StaticCleanup() StaticCleanup()
{ {

View File

@ -10,6 +10,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdlib.h>
#include <ClipboardPrivate.h> #include <ClipboardPrivate.h>
#include <MessagePrivate.h> #include <MessagePrivate.h>
@ -22,6 +23,17 @@
#define OUT printf #define OUT printf
static void
initialize_forked_child()
{
DBG(OUT("initialize_forked_child()\n"));
BMessage::Private::StaticReInitForkedChild();
DBG(OUT("initialize_forked_child() done\n"));
}
extern "C" void extern "C" void
initialize_before() initialize_before()
{ {
@ -30,6 +42,8 @@ initialize_before()
BMessage::Private::StaticInit(); BMessage::Private::StaticInit();
BRoster::Private::InitBeRoster(); BRoster::Private::InitBeRoster();
atfork(initialize_forked_child);
DBG(OUT("initialize_before() done\n")); DBG(OUT("initialize_before() done\n"));
} }

View File

@ -1971,6 +1971,22 @@ BMessage::_StaticInit()
} }
void
BMessage::_StaticReInitForkedChild()
{
DEBUG_FUNCTION_ENTER2;
// overwrite the inherited ports with a set of our own
sReplyPorts[0] = create_port(1, "tmp_rport0");
sReplyPorts[1] = create_port(1, "tmp_rport1");
sReplyPorts[2] = create_port(1, "tmp_rport2");
sReplyPortInUse[0] = 0;
sReplyPortInUse[1] = 0;
sReplyPortInUse[2] = 0;
}
void void
BMessage::_StaticCleanup() BMessage::_StaticCleanup()
{ {