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);
void invalidate_server_port();
port_id get_app_server_port();
status_t create_desktop_connection(ServerLink* link, const char* name,
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.
*
* Authors:
* Axel Dörfler, [email protected]
* Ingo Weinhold, bonefish@@users.sf.net
*/
@@ -16,6 +17,7 @@
#include <Entry.h>
#include <image.h>
#include <Messenger.h>
#include <OS.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.
*/
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<port_id>(clientPort);
link->Attach<int32>(getuid());
link->AttachString(getenv("TARGET_SCREEN"));
link->Attach<int32>(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<port_id>(&serverPort);
link->SetSenderPort(serverPort);
port_id desktopPort = reply.GetInt32("port", B_ERROR);
if (desktopPort < 0)
return desktopPort;
link->SetSenderPort(desktopPort);
return B_OK;
}
-1
View File
@@ -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!");
+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.
*
* 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<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 -
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;
}
+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.
*
* Authors:
* DarkWyrm <bpmagic@columbus.rr.com>
* Axel Dörfler, axeld@pinc-software.de
*/
#ifndef APP_SERVER_H
#define APP_SERVER_H
#include <OS.h>
#include <Locker.h>
#include <List.h>
#include <Application.h>
#include <Window.h>
#include <String.h>
#include <List.h>
#include <Locker.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 "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<Desktop> fDesktops;
BLocker fDesktopLock;
private:
BObjectList<Desktop> fDesktops;
BLocker fDesktopLock;
};