From 49a92384f408916ee1383cc837eaf2bb7873b25a Mon Sep 17 00:00:00 2001 From: Augustin Cavalier Date: Tue, 18 Nov 2025 22:26:31 -0500 Subject: [PATCH] servers & kits: Rehabilitate app_server restart functionality. * It's not really possible to distinguish between a first startup and a restart inside app_server itself. Due to the new BServer setup, the same port will still be used, too. So, change the messages sent to just "AppServerStarted". * Since the message is sent out much later than the port is created, by the time applications see it, the app_server may have already been started a while and applications may have connected to it. So, check if we really need to reconnect in BApplication before actually trying to do that. * BWindow now starts with updates disabled, so they must be enabled after reconnecting. After this commit, basic app_server restart functionality works again; it's restarted automatically by launch_daemon after dying or being killed and applications automatically reconnect. However, some problems still linger (e.g. Terminal doesn't always recreate its windows, colors on the Desktop look wrong, missing desktop background image, etc.) --- headers/private/app/RosterPrivate.h | 3 +-- src/kits/app/Application.cpp | 10 ++++++++-- src/kits/interface/Window.cpp | 3 ++- src/servers/app/AppServer.cpp | 7 ++++++- src/servers/input/InputServer.cpp | 3 ++- src/servers/registrar/Registrar.cpp | 10 ++++++---- src/servers/registrar/TRoster.cpp | 29 ++--------------------------- src/servers/registrar/TRoster.h | 2 +- 8 files changed, 28 insertions(+), 39 deletions(-) diff --git a/headers/private/app/RosterPrivate.h b/headers/private/app/RosterPrivate.h index bba25972bf..5ad11f6d8b 100644 --- a/headers/private/app/RosterPrivate.h +++ b/headers/private/app/RosterPrivate.h @@ -13,8 +13,7 @@ #include -const int32 kMsgAppServerRestarted = 'ASRe'; -const int32 kMsgRestartAppServer = 'ReAS'; +const int32 kMsgAppServerStarted = '_ASt'; class BRoster::Private { diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index c5fbfe1911..8620dbdcc8 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -691,7 +691,7 @@ BApplication::MessageReceived(BMessage* message) be_roster->ActivateApp(Team()); break; - case kMsgAppServerRestarted: + case kMsgAppServerStarted: _ReconnectToServer(); break; @@ -1454,6 +1454,12 @@ BApplication::_ConnectToServer() void BApplication::_ReconnectToServer() { + team_info dummy; + if (get_team_info(fServerLink->TargetTeam(), &dummy) == B_OK) { + // We're already connected to the correct server. + return; + } + // the sender port belongs to the app_server delete_port(fServerLink->ReceiverPort()); @@ -1470,7 +1476,7 @@ BApplication::_ReconnectToServer() if (window == NULL) continue; BMessenger windowMessenger(window); - windowMessenger.SendMessage(kMsgAppServerRestarted); + windowMessenger.SendMessage(kMsgAppServerStarted); } reconnect_bitmaps_to_app_server(); diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index 448ceb8d84..5bb7a8e33b 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -739,7 +739,7 @@ BWindow::MessageReceived(BMessage* message) if (message->what == B_KEY_DOWN) _KeyboardNavigation(); - if (message->what == (int32)kMsgAppServerRestarted) { + if (message->what == kMsgAppServerStarted) { fLink->SetSenderPort( BApplication::Private::ServerLink()->SenderPort()); @@ -786,6 +786,7 @@ BWindow::MessageReceived(BMessage* message) // connect all views to the server again fTopView->_CreateSelf(); + EnableUpdates(); _SendShowOrHideMessage(); } diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index 2a0c4b1f54..91d1a6e03d 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "BitmapManager.h" #include "Desktop.h" @@ -70,15 +71,19 @@ AppServer::AppServer(status_t* status) // Create the bitmap allocator. Object declared in BitmapManager.cpp gBitmapManager = new BitmapManager(); +#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST #if 0 // This is not presently needed, as app_server is launched from the login session. -#ifndef HAIKU_TARGET_PLATFORM_LIBBE_TEST // TODO: check the attached displays, and launch login session for them BMessage data; data.AddString("name", "app_server"); data.AddInt32("session", 0); BLaunchRoster().Target("login", data); #endif + + // Inform the registrar we've (re)started. + BMessage request(kMsgAppServerStarted); + BRoster::Private().SendTo(&request, NULL, false); #endif } diff --git a/src/servers/input/InputServer.cpp b/src/servers/input/InputServer.cpp index 53f0f548bb..c310803097 100644 --- a/src/servers/input/InputServer.cpp +++ b/src/servers/input/InputServer.cpp @@ -582,9 +582,10 @@ InputServer::MessageReceived(BMessage* message) return; } - case kMsgAppServerRestarted: + case kMsgAppServerStarted: { BApplication::MessageReceived(message); + BPrivate::AppServerLink link; link.StartMessage(AS_REGISTER_INPUT_SERVER); link.Flush(); diff --git a/src/servers/registrar/Registrar.cpp b/src/servers/registrar/Registrar.cpp index 29321ab036..5156b66d2b 100644 --- a/src/servers/registrar/Registrar.cpp +++ b/src/servers/registrar/Registrar.cpp @@ -51,7 +51,7 @@ static const char *kEventQueueName = "timer_thread"; /*! \brief Creates the registrar application class. - \param error Passed to the BApplication constructor for returning an + \param error Passed to the BServer constructor for returning an error code. */ Registrar::Registrar(status_t* _error) @@ -375,9 +375,11 @@ Registrar::_MessageReceived(BMessage *message) } break; - case kMsgRestartAppServer: + case kMsgAppServerStarted: { - fRoster->HandleRestartAppServer(message); + fRoster->HandleAppServerStarted(message); + + // Don't pass this message on to our BApplication, as that may deadlock. break; } @@ -477,7 +479,7 @@ main() "registrar main() caught exception: %s", exception.what()); debugger(buffer); } catch (...) { - debugger("registrar main() caught unknown exception"); + debugger("registrar main() caught unknown exception"); } PRINT("delete app...\n"); diff --git a/src/servers/registrar/TRoster.cpp b/src/servers/registrar/TRoster.cpp index 1fdd27ee82..9ed4d15482 100644 --- a/src/servers/registrar/TRoster.cpp +++ b/src/servers/registrar/TRoster.cpp @@ -1141,39 +1141,14 @@ TRoster::HandleSaveRecentLists(BMessage* request) void -TRoster::HandleRestartAppServer(BMessage* request) +TRoster::HandleAppServerStarted(BMessage* request) { BAutolock _(fLock); - // TODO: if an app_server is still running, stop it first - - const char* pathString; - if (request->FindString("path", &pathString) != B_OK) - pathString = "/boot/system/servers"; - BPath path(pathString); - path.Append("app_server"); - // NOTE: its required at some point that the binary name is "app_server" - - const char **argv = new const char * [2]; - argv[0] = strdup(path.Path()); - argv[1] = NULL; - - thread_id threadId = load_image(1, argv, (const char**)environ); - int i; - for (i = 0; i < 1; i++) - delete argv[i]; - delete [] argv; - - resume_thread(threadId); - // give the server some time to create the server port - snooze(100000); - - // notify all apps - // TODO: whats about ourself? AppInfoListMessagingTargetSet targetSet(fRegisteredApps); if (targetSet.HasNext()) { // send the messages - BMessage message(kMsgAppServerRestarted); + BMessage message(kMsgAppServerStarted); MessageDeliverer::Default()->DeliverMessage(&message, targetSet); } } diff --git a/src/servers/registrar/TRoster.h b/src/servers/registrar/TRoster.h index 8a8fa49ef6..f0954bc9a4 100644 --- a/src/servers/registrar/TRoster.h +++ b/src/servers/registrar/TRoster.h @@ -56,7 +56,7 @@ public: void HandleLoadRecentLists(BMessage* request); void HandleSaveRecentLists(BMessage* request); - void HandleRestartAppServer(BMessage* request); + void HandleAppServerStarted(BMessage* request); void ClearRecentDocuments(); void ClearRecentFolders();