The app_server is now a regular BServer.

This commit is contained in:
Axel Dörfler
2015-07-22 20:40:29 +02:00
parent cbfe45bbfa
commit 592ffe6461
5 changed files with 113 additions and 191 deletions
-2
View File
@@ -30,8 +30,6 @@ thread_id main_thread_for(team_id team);
bool is_app_showing_modal_window(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, status_t create_desktop_connection(ServerLink* link, const char* name,
int32 capacity); int32 capacity);
+17 -41
View File
@@ -1,8 +1,9 @@
/* /*
* Copyright 2001-2011, Haiku, Inc. * Copyright 2001-2015, Haiku, Inc.
* Distributed under the terms of the MIT License. * Distributed under the terms of the MIT License.
* *
* Authors: * Authors:
* Axel Dörfler, [email protected]
* Ingo Weinhold, bonefish@@users.sf.net * Ingo Weinhold, bonefish@@users.sf.net
*/ */
@@ -16,6 +17,7 @@
#include <Entry.h> #include <Entry.h>
#include <image.h> #include <image.h>
#include <Messenger.h>
#include <OS.h> #include <OS.h>
#include <ServerLink.h> #include <ServerLink.h>
@@ -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. /*! Creates a connection with the desktop.
*/ */
status_t status_t
create_desktop_connection(ServerLink* link, const char* name, int32 capacity) 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 // Create the port so that the app_server knows where to send messages
port_id clientPort = create_port(capacity, name); port_id clientPort = create_port(capacity, name);
if (clientPort < 0) if (clientPort < 0)
return clientPort; return clientPort;
link->SetTo(serverPort, clientPort); link->SetReceiverPort(clientPort);
link->StartMessage(AS_GET_DESKTOP); BMessage request(AS_GET_DESKTOP);
link->Attach<port_id>(clientPort); request.AddInt32("user", getuid());
link->Attach<int32>(getuid()); request.AddInt32("version", AS_PROTOCOL_VERSION);
link->AttachString(getenv("TARGET_SCREEN")); request.AddString("target", getenv("TARGET_SCREEN"));
link->Attach<int32>(AS_PROTOCOL_VERSION);
int32 code; BMessenger server("application/x-vnd.Haiku-app_server");
if (link->FlushWithReply(code) != B_OK || code != B_OK) { BMessage reply;
link->SetSenderPort(-1); status_t status = server.SendMessage(&request, &reply);
return B_ERROR; if (status != B_OK)
} return status;
link->Read<port_id>(&serverPort); port_id desktopPort = reply.GetInt32("port", B_ERROR);
link->SetSenderPort(serverPort); if (desktopPort < 0)
return desktopPort;
link->SetSenderPort(desktopPort);
return B_OK; return B_OK;
} }
-1
View File
@@ -1410,7 +1410,6 @@ BApplication::_ReconnectToServer()
{ {
delete_port(fServerLink->SenderPort()); delete_port(fServerLink->SenderPort());
delete_port(fServerLink->ReceiverPort()); delete_port(fServerLink->ReceiverPort());
invalidate_server_port();
if (_ConnectToServer() != B_OK) if (_ConnectToServer() != B_OK)
debugger("Can't reconnect to app server!"); debugger("Can't reconnect to app server!");
+71 -116
View File
@@ -1,5 +1,5 @@
/* /*
* Copyright 2001-2011, Haiku, Inc. * Copyright 2001-2015, Haiku, Inc.
* Distributed under the terms of the MIT license. * Distributed under the terms of the MIT license.
* *
* Authors: * Authors:
@@ -35,7 +35,6 @@
// Globals // Globals
port_id gAppServerPort; port_id gAppServerPort;
static AppServer* sAppServer;
BTokenSpace gTokenSpace; BTokenSpace gTokenSpace;
uint32 gAppServerSIMDFlags = 0; uint32 gAppServerSIMDFlags = 0;
@@ -46,23 +45,13 @@ uint32 gAppServerSIMDFlags = 0;
spawns the main housekeeping threads, loads user preferences for the UI spawns the main housekeeping threads, loads user preferences for the UI
and decorator, and allocates various locks. and decorator, and allocates various locks.
*/ */
AppServer::AppServer() AppServer::AppServer(status_t* status)
: :
MessageLooper("app_server"), BServer("application/x-vnd.Haiku-app_server", "picasso", -1, false, status),
fMessagePort(-1),
fDesktops(),
fDesktopLock("AppServerDesktopLock") fDesktopLock("AppServerDesktopLock")
{ {
openlog("app_server", 0, LOG_DAEMON); 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(); gInputManager = new InputManager();
// Create the font server and scan the proper directories. // Create the font server and scan the proper directories.
@@ -98,10 +87,70 @@ AppServer::~AppServer()
void void
AppServer::RunLooper() AppServer::MessageReceived(BMessage* message)
{ {
rename_thread(find_thread(NULL), "picasso"); switch (message->what) {
_message_thread((void*)this); 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<port_id>(&replyPort);
int32 userID;
msg.Read<int32>(&userID);
char* targetScreen = NULL;
msg.ReadString(&targetScreen);
if (targetScreen != NULL && strlen(targetScreen) == 0) {
free(targetScreen);
targetScreen = NULL;
}
int32 version;
if (msg.Read<int32>(&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<port_id>(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 - // #pragma mark -
int int
main(int argc, char** argv) 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()); srand(real_time_clock_usecs());
AppServer* server = new AppServer; status_t status;
server->RunLooper(); AppServer* server = new AppServer(&status);
if (status == B_OK)
server->Run();
return 0; return status == B_OK ? EXIT_SUCCESS : EXIT_FAILURE;
} }
+25 -31
View File
@@ -1,58 +1,52 @@
/* /*
* Copyright 2001-2011, Haiku, Inc. * Copyright 2001-2015, Haiku, Inc.
* Distributed under the terms of the MIT license. * Distributed under the terms of the MIT license.
* *
* Authors: * Authors:
* DarkWyrm <[email protected]> * DarkWyrm <[email protected]>
* Axel Dörfler, [email protected]
*/ */
#ifndef APP_SERVER_H #ifndef APP_SERVER_H
#define APP_SERVER_H #define APP_SERVER_H
#include <OS.h>
#include <Locker.h>
#include <List.h>
#include <Application.h> #include <Application.h>
#include <Window.h> #include <List.h>
#include <String.h> #include <Locker.h>
#include <ObjectList.h> #include <ObjectList.h>
#include <TokenSpace.h> #include <OS.h>
#include <Server.h>
#include <String.h>
#include <Window.h>
#include "ServerConfig.h"
#include "MessageLooper.h" #include "MessageLooper.h"
#include "ServerConfig.h"
class ServerApp; class ServerApp;
class BitmapManager; class BitmapManager;
class Desktop; class Desktop;
using BPrivate::BTokenSpace;
namespace BPrivate { class AppServer : public BServer {
class PortLink; public:
}; AppServer(status_t* status);
virtual ~AppServer();
virtual void MessageReceived(BMessage* message);
virtual bool QuitRequested();
class AppServer : public MessageLooper { private:
public: Desktop* _CreateDesktop(uid_t userID,
AppServer(); const char* targetScreen);
virtual ~AppServer(); Desktop* _FindDesktop(uid_t userID,
const char* targetScreen);
void RunLooper(); void _LaunchInputServer();
virtual port_id MessagePort() const { return fMessagePort; }
private: private:
virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver& link); BObjectList<Desktop> fDesktops;
BLocker fDesktopLock;
Desktop* _CreateDesktop(uid_t userID, const char* targetScreen);
Desktop* _FindDesktop(uid_t userID, const char* targetScreen);
void _LaunchInputServer();
private:
port_id fMessagePort;
BObjectList<Desktop> fDesktops;
BLocker fDesktopLock;
}; };