diff --git a/headers/private/app/AppMisc.h b/headers/private/app/AppMisc.h index 52295757f7..4ddac85acc 100644 --- a/headers/private/app/AppMisc.h +++ b/headers/private/app/AppMisc.h @@ -30,8 +30,6 @@ thread_id main_thread_for(team_id team); bool is_app_showing_modal_window(team_id team); -void invalidate_server_port(); -port_id get_app_server_port(); status_t create_desktop_connection(ServerLink* link, const char* name, int32 capacity); diff --git a/src/kits/app/AppMisc.cpp b/src/kits/app/AppMisc.cpp index 3306364b6a..1a607f785f 100644 --- a/src/kits/app/AppMisc.cpp +++ b/src/kits/app/AppMisc.cpp @@ -1,8 +1,9 @@ /* - * Copyright 2001-2011, Haiku, Inc. + * Copyright 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT License. * * Authors: + * Axel Dörfler, axeld@pinc-software.de * Ingo Weinhold, bonefish@@users.sf.net */ @@ -16,6 +17,7 @@ #include #include +#include #include #include @@ -174,60 +176,34 @@ is_app_showing_modal_window(team_id team) } -static port_id sServerPort = -1; - - -void -invalidate_server_port() -{ - sServerPort = -1; -} - - -port_id -get_app_server_port() -{ - if (sServerPort < 0) { - // No need for synchronization - in the worst case, we'll call - // find_port() twice. - sServerPort = find_port(SERVER_PORT_NAME); - } - - return sServerPort; -} - - /*! Creates a connection with the desktop. */ status_t create_desktop_connection(ServerLink* link, const char* name, int32 capacity) { - port_id serverPort = get_app_server_port(); - if (serverPort < 0) - return serverPort; - // Create the port so that the app_server knows where to send messages port_id clientPort = create_port(capacity, name); if (clientPort < 0) return clientPort; - link->SetTo(serverPort, clientPort); + link->SetReceiverPort(clientPort); - link->StartMessage(AS_GET_DESKTOP); - link->Attach(clientPort); - link->Attach(getuid()); - link->AttachString(getenv("TARGET_SCREEN")); - link->Attach(AS_PROTOCOL_VERSION); + BMessage request(AS_GET_DESKTOP); + request.AddInt32("user", getuid()); + request.AddInt32("version", AS_PROTOCOL_VERSION); + request.AddString("target", getenv("TARGET_SCREEN")); - int32 code; - if (link->FlushWithReply(code) != B_OK || code != B_OK) { - link->SetSenderPort(-1); - return B_ERROR; - } + BMessenger server("application/x-vnd.Haiku-app_server"); + BMessage reply; + status_t status = server.SendMessage(&request, &reply); + if (status != B_OK) + return status; - link->Read(&serverPort); - link->SetSenderPort(serverPort); + port_id desktopPort = reply.GetInt32("port", B_ERROR); + if (desktopPort < 0) + return desktopPort; + link->SetSenderPort(desktopPort); return B_OK; } diff --git a/src/kits/app/Application.cpp b/src/kits/app/Application.cpp index 75c6dd3e36..04ae7b39c1 100644 --- a/src/kits/app/Application.cpp +++ b/src/kits/app/Application.cpp @@ -1410,7 +1410,6 @@ BApplication::_ReconnectToServer() { delete_port(fServerLink->SenderPort()); delete_port(fServerLink->ReceiverPort()); - invalidate_server_port(); if (_ConnectToServer() != B_OK) debugger("Can't reconnect to app server!"); diff --git a/src/servers/app/AppServer.cpp b/src/servers/app/AppServer.cpp index a17a9d0e64..004b7f489d 100644 --- a/src/servers/app/AppServer.cpp +++ b/src/servers/app/AppServer.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2001-2011, Haiku, Inc. + * Copyright 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: @@ -35,7 +35,6 @@ // Globals port_id gAppServerPort; -static AppServer* sAppServer; BTokenSpace gTokenSpace; uint32 gAppServerSIMDFlags = 0; @@ -46,23 +45,13 @@ uint32 gAppServerSIMDFlags = 0; spawns the main housekeeping threads, loads user preferences for the UI and decorator, and allocates various locks. */ -AppServer::AppServer() +AppServer::AppServer(status_t* status) : - MessageLooper("app_server"), - fMessagePort(-1), - fDesktops(), + BServer("application/x-vnd.Haiku-app_server", "picasso", -1, false, status), fDesktopLock("AppServerDesktopLock") { openlog("app_server", 0, LOG_DAEMON); - fMessagePort = create_port(DEFAULT_MONITOR_PORT_SIZE, SERVER_PORT_NAME); - if (fMessagePort < B_OK) - debugger("app_server could not create message port"); - - fLink.SetReceiverPort(fMessagePort); - - sAppServer = this; - gInputManager = new InputManager(); // Create the font server and scan the proper directories. @@ -98,10 +87,70 @@ AppServer::~AppServer() void -AppServer::RunLooper() +AppServer::MessageReceived(BMessage* message) { - rename_thread(find_thread(NULL), "picasso"); - _message_thread((void*)this); + switch (message->what) { + case AS_GET_DESKTOP: + { + Desktop* desktop = NULL; + + int32 userID = message->GetInt32("user", 0); + int32 version = message->GetInt32("version", 0); + const char* targetScreen = message->GetString("target"); + + if (version != AS_PROTOCOL_VERSION) { + syslog(LOG_ERR, "Application for user %" B_PRId32 " does not " + "support the current server protocol.\n", userID); + } else { + desktop = _FindDesktop(userID, targetScreen); + if (desktop == NULL) { + // we need to create a new desktop object for this user + // TODO: test if the user exists on the system + // TODO: maybe have a separate AS_START_DESKTOP_SESSION for + // authorizing the user + desktop = _CreateDesktop(userID, targetScreen); + } + } + + BMessage reply; + if (desktop != NULL) + reply.AddInt32("port", desktop->MessagePort()); + else + reply.what = (uint32)B_ERROR; + + message->SendReply(&reply); + break; + } + + default: + // We don't allow application scripting + STRACE(("AppServer received unexpected code %" B_PRId32 "\n", + message->what)); + break; + } +} + + +bool +AppServer::QuitRequested() +{ +#if TEST_MODE + while (fDesktops.CountItems() > 0) { + Desktop *desktop = fDesktops.RemoveItemAt(0); + + thread_id thread = desktop->Thread(); + desktop->PostMessage(B_QUIT_REQUESTED); + + // we just wait for the desktop to kill itself + status_t status; + wait_for_thread(thread, &status); + } + + return BServer::QuitRequested(); +#else + return false; +#endif + } @@ -160,112 +209,18 @@ AppServer::_FindDesktop(uid_t userID, const char* targetScreen) } -/*! \brief Message handling function for all messages sent to the app_server - \param code ID of the message sent - \param buffer Attachment buffer for the message. - -*/ -void -AppServer::_DispatchMessage(int32 code, BPrivate::LinkReceiver& msg) -{ - switch (code) { - case AS_GET_DESKTOP: - { - Desktop* desktop = NULL; - - port_id replyPort; - msg.Read(&replyPort); - - int32 userID; - msg.Read(&userID); - - char* targetScreen = NULL; - msg.ReadString(&targetScreen); - if (targetScreen != NULL && strlen(targetScreen) == 0) { - free(targetScreen); - targetScreen = NULL; - } - - int32 version; - if (msg.Read(&version) < B_OK - || version != AS_PROTOCOL_VERSION) { - syslog(LOG_ERR, "Application for user %" B_PRId32 " with port " - "%" B_PRId32 " does not support the current server " - "protocol.\n", userID, replyPort); - } else { - desktop = _FindDesktop(userID, targetScreen); - if (desktop == NULL) { - // we need to create a new desktop object for this user - // TODO: test if the user exists on the system - // TODO: maybe have a separate AS_START_DESKTOP_SESSION for - // authorizing the user - desktop = _CreateDesktop(userID, targetScreen); - } - } - - free(targetScreen); - - BPrivate::LinkSender reply(replyPort); - if (desktop != NULL) { - reply.StartMessage(B_OK); - reply.Attach(desktop->MessagePort()); - } else - reply.StartMessage(B_ERROR); - - reply.Flush(); - break; - } - -#if TEST_MODE - case B_QUIT_REQUESTED: - { - // We've been asked to quit, so (for now) broadcast to all - // desktops to quit. This situation will occur only when the server - // is compiled as a regular Be application. - - fQuitting = true; - - while (fDesktops.CountItems() > 0) { - Desktop *desktop = fDesktops.RemoveItemAt(0); - - thread_id thread = desktop->Thread(); - desktop->PostMessage(B_QUIT_REQUESTED); - - // we just wait for the desktop to kill itself - status_t status; - wait_for_thread(thread, &status); - } - - delete this; - - // we are now clear to exit - exit(0); - break; - } -#endif - - default: - STRACE(("Server::MainLoop received unexpected code %" B_PRId32 " " - "(offset %" B_PRId32 ")\n", code, code - SERVER_TRUE)); - break; - } -} - - // #pragma mark - int main(int argc, char** argv) { - // There can be only one.... - if (find_port(SERVER_PORT_NAME) >= B_OK) - return -1; - srand(real_time_clock_usecs()); - AppServer* server = new AppServer; - server->RunLooper(); + status_t status; + AppServer* server = new AppServer(&status); + if (status == B_OK) + server->Run(); - return 0; + return status == B_OK ? EXIT_SUCCESS : EXIT_FAILURE; } diff --git a/src/servers/app/AppServer.h b/src/servers/app/AppServer.h index 6aaf5b5f56..9320edb9d1 100644 --- a/src/servers/app/AppServer.h +++ b/src/servers/app/AppServer.h @@ -1,58 +1,52 @@ /* - * Copyright 2001-2011, Haiku, Inc. + * Copyright 2001-2015, Haiku, Inc. * Distributed under the terms of the MIT license. * * Authors: * DarkWyrm + * Axel Dörfler, axeld@pinc-software.de */ #ifndef APP_SERVER_H #define APP_SERVER_H -#include -#include -#include #include -#include -#include +#include +#include #include -#include +#include +#include +#include +#include -#include "ServerConfig.h" #include "MessageLooper.h" +#include "ServerConfig.h" + class ServerApp; class BitmapManager; class Desktop; -using BPrivate::BTokenSpace; -namespace BPrivate { - class PortLink; -}; +class AppServer : public BServer { +public: + AppServer(status_t* status); + virtual ~AppServer(); + virtual void MessageReceived(BMessage* message); + virtual bool QuitRequested(); -class AppServer : public MessageLooper { - public: - AppServer(); - virtual ~AppServer(); +private: + Desktop* _CreateDesktop(uid_t userID, + const char* targetScreen); + Desktop* _FindDesktop(uid_t userID, + const char* targetScreen); - void RunLooper(); - virtual port_id MessagePort() const { return fMessagePort; } + void _LaunchInputServer(); - private: - virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver& link); - - Desktop* _CreateDesktop(uid_t userID, const char* targetScreen); - Desktop* _FindDesktop(uid_t userID, const char* targetScreen); - - void _LaunchInputServer(); - - private: - port_id fMessagePort; - - BObjectList fDesktops; - BLocker fDesktopLock; +private: + BObjectList fDesktops; + BLocker fDesktopLock; };