⛏️ index : haiku.git

author Augustin Cavalier <waddlesplash@gmail.com> 2025-11-18 22:26:31.0 -05:00:00
committer Augustin Cavalier <waddlesplash@gmail.com> 2025-11-18 22:26:31.0 -05:00:00
commit
49a92384f408916ee1383cc837eaf2bb7873b25a [patch]
tree
91150de15e0fd087c22dbe0519fa07386ce0c89e
parent
fe8f88cff41e731db2bd6958331c6585a5feaa5a
download
49a92384f408916ee1383cc837eaf2bb7873b25a.tar.gz

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.)

Diff

 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 bba2597..5ad11f6 100644
--- a/headers/private/app/RosterPrivate.h
+++ b/headers/private/app/RosterPrivate.h
@@ -13,8 +13,7 @@
#include <Roster.h>


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 c5fbfe1..8620dbd 100644
--- a/src/kits/app/Application.cpp
+++ b/src/kits/app/Application.cpp
@@ -691,7 +691,7 @@
			be_roster->ActivateApp(Team());
			break;

		case kMsgAppServerRestarted:
		case kMsgAppServerStarted:
			_ReconnectToServer();
			break;

@@ -1454,6 +1454,12 @@
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 @@
		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 448ceb8..5bb7a8e 100644
--- a/src/kits/interface/Window.cpp
+++ b/src/kits/interface/Window.cpp
@@ -739,7 +739,7 @@
		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 @@
			// 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 2a0c4b1..91d1a6e 100644
--- a/src/servers/app/AppServer.cpp
+++ b/src/servers/app/AppServer.cpp
@@ -17,6 +17,7 @@
#include <AutoDeleter.h>
#include <LaunchRoster.h>
#include <PortLink.h>
#include <RosterPrivate.h>

#include "BitmapManager.h"
#include "Desktop.h"
@@ -70,15 +71,19 @@
	// 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 53f0f54..c310803 100644
--- a/src/servers/input/InputServer.cpp
+++ b/src/servers/input/InputServer.cpp
@@ -582,9 +582,10 @@
			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 29321ab..5156b66 100644
--- a/src/servers/registrar/Registrar.cpp
+++ b/src/servers/registrar/Registrar.cpp
@@ -51,7 +51,7 @@


/*!	\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 @@
			}
			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 @@
			"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 1fdd27e..9ed4d15 100644
--- a/src/servers/registrar/TRoster.cpp
+++ b/src/servers/registrar/TRoster.cpp
@@ -1141,39 +1141,14 @@


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 8a8fa49..f0954bc 100644
--- a/src/servers/registrar/TRoster.h
+++ b/src/servers/registrar/TRoster.h
@@ -56,7 +56,7 @@
			void			HandleLoadRecentLists(BMessage* request);
			void			HandleSaveRecentLists(BMessage* request);

			void			HandleRestartAppServer(BMessage* request);
			void			HandleAppServerStarted(BMessage* request);

			void			ClearRecentDocuments();
			void			ClearRecentFolders();