From e0b7c61c46c65f6cdc85c3b8240b282f2d045f49 Mon Sep 17 00:00:00 2001 From: Oliver Tappe Date: Thu, 10 Sep 2009 23:10:51 +0000 Subject: [PATCH] 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 --- headers/os/app/Message.h | 1 + headers/private/app/MessagePrivate.h | 6 ++++++ src/kits/app/InitTerminateLibBe.cpp | 14 ++++++++++++++ src/kits/app/Message.cpp | 16 ++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/headers/os/app/Message.h b/headers/os/app/Message.h index d9cd5101eb..a58a21ca26 100644 --- a/headers/os/app/Message.h +++ b/headers/os/app/Message.h @@ -339,6 +339,7 @@ class BMessage { port_id port, int32 token, bigtime_t timeout); static void _StaticInit(); + static void _StaticReInitForkedChild(); static void _StaticCleanup(); static void _StaticCacheCleanup(); static int32 _StaticGetCachedReplyPort(); diff --git a/headers/private/app/MessagePrivate.h b/headers/private/app/MessagePrivate.h index f30c1d8d7e..bbc79217bb 100644 --- a/headers/private/app/MessagePrivate.h +++ b/headers/private/app/MessagePrivate.h @@ -207,6 +207,12 @@ class BMessage::Private { BMessage::_StaticInit(); } + static void + StaticReInitForkedChild() + { + BMessage::_StaticReInitForkedChild(); + } + static void StaticCleanup() { diff --git a/src/kits/app/InitTerminateLibBe.cpp b/src/kits/app/InitTerminateLibBe.cpp index 351c33cc04..8f8314cecd 100644 --- a/src/kits/app/InitTerminateLibBe.cpp +++ b/src/kits/app/InitTerminateLibBe.cpp @@ -10,6 +10,7 @@ #include +#include #include #include @@ -22,6 +23,17 @@ #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 initialize_before() { @@ -30,6 +42,8 @@ initialize_before() BMessage::Private::StaticInit(); BRoster::Private::InitBeRoster(); + atfork(initialize_forked_child); + DBG(OUT("initialize_before() done\n")); } diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index 19c26ffeda..3e1bd40e87 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -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 BMessage::_StaticCleanup() {