Factored a MessageLooper class out of ServerWindow and ServerApp. Could still
be improved a bit (Quit() and _MessageLooper() are empty right now). Removed ServerApp::PingTarget(). Hopefully cleared some confusion about ServerApp::fClientLooperPort and fClientToken (previously fHandlerToken), even if it's currently unused. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@13807 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
f95c74702f
commit
89ab121e66
@ -236,6 +236,9 @@ int32
|
||||
AppServer::PicassoThread(void *data)
|
||||
{
|
||||
while (!sAppServer->fQuitting) {
|
||||
// TODO: we don't need to do this anymore - dead apps are
|
||||
// detected automatically
|
||||
#if 0
|
||||
sAppServer->fAppListLock.Lock();
|
||||
|
||||
for (int32 i = 0;;) {
|
||||
@ -247,6 +250,7 @@ AppServer::PicassoThread(void *data)
|
||||
}
|
||||
|
||||
sAppServer->fAppListLock.Unlock();
|
||||
#endif
|
||||
// we do this every second so as not to suck *too* many CPU cycles
|
||||
snooze(1000000);
|
||||
}
|
||||
|
@ -76,6 +76,7 @@ Server app_server :
|
||||
PicturePlayer.cpp
|
||||
PNGDump.cpp
|
||||
RAMLinkMsgReader.cpp
|
||||
MessageLooper.cpp
|
||||
|
||||
# Manager Classes
|
||||
CursorManager.cpp
|
||||
|
105
src/servers/app/MessageLooper.cpp
Normal file
105
src/servers/app/MessageLooper.cpp
Normal file
@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
|
||||
|
||||
#include "MessageLooper.h"
|
||||
|
||||
#include <Autolock.h>
|
||||
|
||||
|
||||
MessageLooper::MessageLooper(const char* name)
|
||||
: BLocker(name),
|
||||
fQuitting(false)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
MessageLooper::~MessageLooper()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
MessageLooper::Run()
|
||||
{
|
||||
BAutolock locker(this);
|
||||
|
||||
fQuitting = false;
|
||||
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
_GetLooperName(name, sizeof(name));
|
||||
|
||||
// Spawn our message-monitoring thread
|
||||
fThread = spawn_thread(_message_thread, name, B_NORMAL_PRIORITY, this);
|
||||
if (fThread < B_OK) {
|
||||
fQuitting = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (resume_thread(fThread) != B_OK) {
|
||||
fQuitting = true;
|
||||
kill_thread(fThread);
|
||||
fThread = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MessageLooper::Quit()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Send a message to the looper without any attachments
|
||||
\param code ID code of the message to post
|
||||
*/
|
||||
void
|
||||
MessageLooper::PostMessage(int32 code)
|
||||
{
|
||||
BPrivate::LinkSender link(_MessagePort());
|
||||
link.StartMessage(code);
|
||||
link.Flush();
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MessageLooper::_GetLooperName(char* name, size_t length)
|
||||
{
|
||||
strcpy(name, "unnamed looper");
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MessageLooper::_DispatchMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
MessageLooper::_MessageLooper()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Message-dispatching loop starter
|
||||
*/
|
||||
/*static*/
|
||||
int32
|
||||
MessageLooper::_message_thread(void* _looper)
|
||||
{
|
||||
MessageLooper* looper = (MessageLooper*)_looper;
|
||||
|
||||
looper->_MessageLooper();
|
||||
return 0;
|
||||
}
|
||||
|
42
src/servers/app/MessageLooper.h
Normal file
42
src/servers/app/MessageLooper.h
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, axeld@pinc-software.de
|
||||
*/
|
||||
#ifndef MESSAGE_LOOPER_H
|
||||
#define MESSAGE_LOOPER_H
|
||||
|
||||
|
||||
#include <PortLink.h>
|
||||
#include <Locker.h>
|
||||
#include <OS.h>
|
||||
|
||||
|
||||
class MessageLooper : public BLocker {
|
||||
public:
|
||||
MessageLooper(const char* name);
|
||||
virtual ~MessageLooper();
|
||||
|
||||
virtual bool Run();
|
||||
virtual void Quit();
|
||||
|
||||
void PostMessage(int32 code);
|
||||
thread_id Thread() const { return fThread; }
|
||||
|
||||
private:
|
||||
virtual void _GetLooperName(char* name, size_t length);
|
||||
virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
|
||||
virtual void _MessageLooper();
|
||||
virtual port_id _MessagePort() const = 0;
|
||||
|
||||
static int32 _message_thread(void *_looper);
|
||||
|
||||
protected:
|
||||
thread_id fThread;
|
||||
BPrivate::PortLink fLink;
|
||||
bool fQuitting;
|
||||
};
|
||||
|
||||
#endif /* MESSAGE_LOOPER_H */
|
@ -79,20 +79,18 @@ static const uint32 kMsgAppQuit = 'appQ';
|
||||
*/
|
||||
ServerApp::ServerApp(port_id clientReplyPort, port_id clientLooperPort,
|
||||
team_id clientTeam, int32 handlerID, const char* signature)
|
||||
:
|
||||
fClientReplyPort(clientReplyPort),
|
||||
: MessageLooper("application"),
|
||||
fMessagePort(-1),
|
||||
fClientReplyPort(clientReplyPort),
|
||||
fClientLooperPort(clientLooperPort),
|
||||
fClientToken(handlerID),
|
||||
fSignature(signature),
|
||||
fThread(-1),
|
||||
fClientTeam(clientTeam),
|
||||
fWindowListLock("window list"),
|
||||
fAppCursor(NULL),
|
||||
fCursorHidden(false),
|
||||
fIsActive(false),
|
||||
//fHandlerToken(handlerID),
|
||||
fSharedMem("shared memory"),
|
||||
fQuitting(false)
|
||||
fSharedMem("shared memory")
|
||||
{
|
||||
if (fSignature == "")
|
||||
fSignature = "application/no-signature";
|
||||
@ -230,21 +228,9 @@ ServerApp::InitCheck()
|
||||
bool
|
||||
ServerApp::Run()
|
||||
{
|
||||
fQuitting = false;
|
||||
|
||||
// Unlike a BApplication, a ServerApp is *supposed* to return immediately
|
||||
// when its Run() function is called.
|
||||
fThread = spawn_thread(_message_thread, Signature(), B_NORMAL_PRIORITY, this);
|
||||
if (fThread < B_OK)
|
||||
if (!MessageLooper::Run())
|
||||
return false;
|
||||
|
||||
if (resume_thread(fThread) != B_OK) {
|
||||
fQuitting = true;
|
||||
kill_thread(fThread);
|
||||
fThread = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Let's tell the client how to talk with us
|
||||
fLink.StartMessage(SERVER_TRUE);
|
||||
fLink.Attach<int32>(fMessagePort);
|
||||
@ -278,48 +264,6 @@ ServerApp::Quit(sem_id shutdownSemaphore)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Pings the target app to make sure it's still working
|
||||
\return true if target is still "alive" and false if "He's dead, Jim."
|
||||
"But that's impossible..."
|
||||
|
||||
This function is called by the app_server thread to ensure that
|
||||
the target app still exists. We do this not by sending a message
|
||||
but by calling get_port_info. We don't want to send ping messages
|
||||
just because the app might simply be hung. If this is the case, it
|
||||
should be up to the user to kill it. If the app has been killed, its
|
||||
ports will be invalid. Thus, if get_port_info returns an error, we
|
||||
tell the app_server to delete the respective ServerApp.
|
||||
*/
|
||||
bool
|
||||
ServerApp::PingTarget()
|
||||
{
|
||||
// ToDo: this function doesn't make any sense; if the client dies we are
|
||||
// aware of it anyway at this point. This would only make sense if we
|
||||
// actually send the team a message to see if it's still responsive.
|
||||
team_info info;
|
||||
if (get_team_info(fClientTeam, &info) != B_OK) {
|
||||
BPrivate::LinkSender link(gAppServerPort);
|
||||
link.StartMessage(AS_DELETE_APP);
|
||||
link.Attach(&fThread, sizeof(thread_id));
|
||||
link.Flush();
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Send a message to the ServerApp with no attachments
|
||||
\param code ID code of the message to post
|
||||
*/
|
||||
void
|
||||
ServerApp::PostMessage(int32 code)
|
||||
{
|
||||
BPrivate::LinkSender link(fMessagePort);
|
||||
link.StartMessage(code);
|
||||
link.Flush();
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Send a message to the ServerApp's BApplication
|
||||
\param msg The message to send
|
||||
@ -338,6 +282,7 @@ ServerApp::SendMessageToClient(const BMessage *msg) const
|
||||
delete [] buffer;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Sets the ServerApp's active status
|
||||
\param value The new status of the ServerApp.
|
||||
@ -365,17 +310,15 @@ ServerApp::SetAppCursor(void)
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief The thread function ServerApps use to monitor messages
|
||||
\param data Pointer to the thread's ServerApp object
|
||||
*/
|
||||
int32
|
||||
ServerApp::_message_thread(void *_app)
|
||||
void
|
||||
ServerApp::_GetLooperName(char* name, size_t length)
|
||||
{
|
||||
ServerApp *app = (ServerApp *)_app;
|
||||
|
||||
app->_MessageLooper();
|
||||
return 0;
|
||||
#ifdef __HAIKU__
|
||||
strlcpy(name, Signature(), length);
|
||||
#else
|
||||
strncpy(name, Signature(), length);
|
||||
name[length - 1] = '\0';
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -2307,10 +2250,3 @@ ServerApp::ClientTeam() const
|
||||
return fClientTeam;
|
||||
}
|
||||
|
||||
|
||||
thread_id
|
||||
ServerApp::Thread() const
|
||||
{
|
||||
return fThread;
|
||||
}
|
||||
|
||||
|
@ -13,13 +13,13 @@
|
||||
#define _SERVERAPP_H_
|
||||
|
||||
|
||||
#include <OS.h>
|
||||
#include <String.h>
|
||||
#include <PortLink.h>
|
||||
|
||||
#include "MessageLooper.h"
|
||||
#include "SubWindowList.h"
|
||||
#include "BGet++.h"
|
||||
|
||||
#include <String.h>
|
||||
|
||||
|
||||
class AreaPool;
|
||||
class BMessage;
|
||||
class BList;
|
||||
@ -36,92 +36,76 @@ namespace BPrivate {
|
||||
\class ServerApp ServerApp.h
|
||||
\brief Counterpart to BApplication within the app_server
|
||||
*/
|
||||
class ServerApp {
|
||||
public:
|
||||
ServerApp(port_id clientAppPort, port_id clientLooperPort,
|
||||
team_id clientTeamID, int32 handlerID, const char* signature);
|
||||
~ServerApp();
|
||||
class ServerApp : public MessageLooper {
|
||||
public:
|
||||
ServerApp(port_id clientAppPort, port_id clientLooperPort,
|
||||
team_id clientTeamID, int32 handlerID,
|
||||
const char* signature);
|
||||
virtual ~ServerApp();
|
||||
|
||||
status_t InitCheck();
|
||||
bool Run();
|
||||
void Quit(sem_id shutdownSemaphore = -1);
|
||||
status_t InitCheck();
|
||||
virtual bool Run();
|
||||
void Quit(sem_id shutdownSemaphore = -1);
|
||||
|
||||
/*!
|
||||
\brief Determines whether the application is the active one
|
||||
\return true if active, false if not.
|
||||
*/
|
||||
bool IsActive(void) const { return fIsActive; }
|
||||
void Activate(bool value);
|
||||
/*!
|
||||
\brief Determines whether the application is the active one
|
||||
\return true if active, false if not.
|
||||
*/
|
||||
bool IsActive(void) const { return fIsActive; }
|
||||
void Activate(bool value);
|
||||
|
||||
bool PingTarget(void);
|
||||
void SendMessageToClient(const BMessage* msg) const;
|
||||
|
||||
void PostMessage(int32 code);
|
||||
void SendMessageToClient(const BMessage* msg) const;
|
||||
void SetAppCursor(void);
|
||||
|
||||
void SetAppCursor(void);
|
||||
team_id ClientTeam() const;
|
||||
const char *Signature() const { return fSignature.String(); }
|
||||
|
||||
team_id ClientTeam() const;
|
||||
thread_id Thread() const;
|
||||
void RemoveWindow(ServerWindow* window);
|
||||
|
||||
const char *Signature() const { return fSignature.String(); }
|
||||
int32 CountBitmaps() const;
|
||||
ServerBitmap *FindBitmap(int32 token) const;
|
||||
|
||||
void RemoveWindow(ServerWindow* window);
|
||||
int32 CountPictures() const;
|
||||
ServerPicture *FindPicture(int32 token) const;
|
||||
|
||||
int32 CountBitmaps() const;
|
||||
ServerBitmap *FindBitmap(int32 token) const;
|
||||
AreaPool *AppAreaPool() { return &fSharedMem; }
|
||||
|
||||
int32 CountPictures() const;
|
||||
ServerPicture *FindPicture(int32 token) const;
|
||||
// ToDo: public?
|
||||
SubWindowList fAppSubWindowList;
|
||||
|
||||
AreaPool *AppAreaPool() { return &fSharedMem; }
|
||||
private:
|
||||
virtual void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
|
||||
virtual void _MessageLooper();
|
||||
virtual void _GetLooperName(char* name, size_t size);
|
||||
virtual port_id _MessagePort() const { return fMessagePort; }
|
||||
|
||||
SubWindowList fAppSubWindowList;
|
||||
port_id fMessagePort;
|
||||
port_id fClientReplyPort;
|
||||
// our BApplication's event port
|
||||
|
||||
private:
|
||||
void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
|
||||
void _MessageLooper();
|
||||
port_id fClientLooperPort;
|
||||
int32 fClientToken;
|
||||
// To send a BMessage to the client (port + token)
|
||||
|
||||
static int32 _message_thread(void *data);
|
||||
BString fSignature;
|
||||
team_id fClientTeam;
|
||||
|
||||
// our BApplication's event port
|
||||
port_id fClientReplyPort;
|
||||
// port we receive messages from our BApplication
|
||||
port_id fMessagePort;
|
||||
// TODO: find out why there is both the app port and the looper port. Do
|
||||
// we really need both? Actually, we aren't using any of these ports,
|
||||
// as BAppServerLink/BPortlink's messages always contain the reply port
|
||||
// To send a message to the client, write a BMessage to this port
|
||||
port_id fClientLooperPort;
|
||||
BLocker fWindowListLock;
|
||||
BList fWindowList;
|
||||
|
||||
BString fSignature;
|
||||
// TODO:
|
||||
// - Are really Bitmaps and Pictures stored per application and not globally ?
|
||||
// - As we reference these stuff by token, what about putting them in hash tables ?
|
||||
BList fBitmapList;
|
||||
BList fPictureList;
|
||||
|
||||
thread_id fThread;
|
||||
team_id fClientTeam;
|
||||
ServerCursor *fAppCursor;
|
||||
bool fCursorHidden;
|
||||
|
||||
BPrivate::PortLink fLink;
|
||||
bool fIsActive;
|
||||
|
||||
BLocker fWindowListLock;
|
||||
BList fWindowList;
|
||||
|
||||
// TODO:
|
||||
// - Are really Bitmaps and Pictures stored per application and not globally ?
|
||||
// - As we reference these stuff by token, what about putting them in hash tables ?
|
||||
BList fBitmapList;
|
||||
BList fPictureList;
|
||||
|
||||
ServerCursor *fAppCursor;
|
||||
|
||||
bool fCursorHidden;
|
||||
bool fIsActive;
|
||||
|
||||
// token ID of the BApplication's BHandler object.
|
||||
// Used for BMessage target specification
|
||||
// TODO: Is it still needed ? We aren't using it.
|
||||
//int32 fHandlerToken;
|
||||
|
||||
AreaPool fSharedMem;
|
||||
|
||||
bool fQuitting;
|
||||
AreaPool fSharedMem;
|
||||
};
|
||||
|
||||
#endif // _SERVERAPP_H_
|
||||
|
@ -76,7 +76,7 @@ static const uint32 kMsgWindowQuit = 'winQ';
|
||||
*/
|
||||
ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
||||
port_id clientPort, port_id looperPort, int32 handlerID)
|
||||
: BLocker(title && *title ? title : "Unnamed Window"),
|
||||
: MessageLooper(title && *title ? title : "Unnamed Window"),
|
||||
fTitle(title),
|
||||
fServerApp(app),
|
||||
fWinBorder(NULL),
|
||||
@ -84,7 +84,6 @@ ServerWindow::ServerWindow(const char *title, ServerApp *app,
|
||||
fMessagePort(-1),
|
||||
fClientReplyPort(clientPort),
|
||||
fClientLooperPort(looperPort),
|
||||
fQuitting(false),
|
||||
fClientViewsWithInvalidCoords(B_VIEW_RESIZED),
|
||||
fHandlerToken(handlerID),
|
||||
fCurrentLayer(NULL)
|
||||
@ -145,22 +144,9 @@ ServerWindow::Init(BRect frame, uint32 look, uint32 feel, uint32 flags, uint32 w
|
||||
bool
|
||||
ServerWindow::Run()
|
||||
{
|
||||
BAutolock locker(this);
|
||||
|
||||
char name[B_OS_NAME_LENGTH];
|
||||
snprintf(name, sizeof(name), "w:%ld:%s", ClientTeam(), Title());
|
||||
|
||||
// Spawn our message-monitoring thread
|
||||
fThread = spawn_thread(_message_thread, name, B_NORMAL_PRIORITY, this);
|
||||
if (fThread < B_OK)
|
||||
if (!MessageLooper::Run())
|
||||
return false;
|
||||
|
||||
if (resume_thread(fThread) != B_OK) {
|
||||
kill_thread(fThread);
|
||||
fThread = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
// Send a reply to our window - it is expecting fMessagePort
|
||||
// port and some other info
|
||||
|
||||
@ -206,16 +192,10 @@ ServerWindow::Quit()
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Send a message to the ServerWindow with no attachments
|
||||
\param code ID code of the message to post
|
||||
*/
|
||||
void
|
||||
ServerWindow::PostMessage(int32 code)
|
||||
ServerWindow::_GetLooperName(char* name, size_t length)
|
||||
{
|
||||
BPrivate::LinkSender link(fMessagePort);
|
||||
link.StartMessage(code);
|
||||
link.Flush();
|
||||
snprintf(name, length, "w:%ld:%s", ClientTeam(), Title());
|
||||
}
|
||||
|
||||
|
||||
@ -2130,19 +2110,6 @@ ServerWindow::_DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link)
|
||||
driver->ConstrainClippingRegion(NULL);
|
||||
}
|
||||
|
||||
/*!
|
||||
\brief Message-dispatching loop starter
|
||||
\param data The thread's ServerWindow
|
||||
*/
|
||||
int32
|
||||
ServerWindow::_message_thread(void *_window)
|
||||
{
|
||||
ServerWindow *window = (ServerWindow *)_window;
|
||||
|
||||
window->_MessageLooper();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*!
|
||||
\brief Message-dispatching loop for the ServerWindow
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <String.h>
|
||||
#include <Window.h>
|
||||
|
||||
#include "MessageLooper.h"
|
||||
#include "SubWindowList.h"
|
||||
#include "TokenSpace.h"
|
||||
|
||||
@ -52,7 +53,7 @@ struct window_info;
|
||||
coordinating and linking a window's WinBorder half with its messaging half, dispatching
|
||||
mouse and key events from the server to its window, and other such things.
|
||||
*/
|
||||
class ServerWindow : public BLocker {
|
||||
class ServerWindow : public MessageLooper {
|
||||
public:
|
||||
ServerWindow(const char *title, ServerApp *app,
|
||||
port_id clientPort, port_id looperPort,
|
||||
@ -62,15 +63,13 @@ public:
|
||||
status_t Init(BRect frame, uint32 look,
|
||||
uint32 feel, uint32 flags,
|
||||
uint32 workspace);
|
||||
bool Run();
|
||||
void Quit();
|
||||
virtual bool Run();
|
||||
virtual void Quit();
|
||||
|
||||
void ReplaceDecorator();
|
||||
void Show();
|
||||
void Hide();
|
||||
|
||||
void PostMessage(int32 code);
|
||||
|
||||
// methods for sending various messages to client.
|
||||
void NotifyQuitRequested();
|
||||
void NotifyMinimize(bool minimize);
|
||||
@ -102,7 +101,6 @@ public:
|
||||
|
||||
// related thread/team_id(s).
|
||||
inline team_id ClientTeam() const { return fClientTeam; }
|
||||
inline thread_id Thread() const { return fThread; }
|
||||
|
||||
// server "private" - try not to use.
|
||||
inline int32 ClientToken() const { return fHandlerToken; }
|
||||
@ -123,8 +121,8 @@ private:
|
||||
void _DispatchMessage(int32 code, BPrivate::LinkReceiver &link);
|
||||
void _DispatchGraphicsMessage(int32 code, BPrivate::LinkReceiver &link);
|
||||
void _MessageLooper();
|
||||
|
||||
static int32 _message_thread(void *_window);
|
||||
virtual void _GetLooperName(char* name, size_t size);
|
||||
virtual port_id _MessagePort() const { return fMessagePort; }
|
||||
|
||||
// TODO: Move me elsewhere
|
||||
status_t PictureToRegion(ServerPicture *picture,
|
||||
@ -139,15 +137,11 @@ private:
|
||||
WinBorder* fWinBorder;
|
||||
|
||||
team_id fClientTeam;
|
||||
thread_id fThread;
|
||||
|
||||
port_id fMessagePort;
|
||||
port_id fClientReplyPort;
|
||||
port_id fClientLooperPort;
|
||||
|
||||
BPrivate::PortLink fLink;
|
||||
bool fQuitting;
|
||||
|
||||
BMessage fClientViewsWithInvalidCoords;
|
||||
|
||||
int32 fServerToken;
|
||||
|
Loading…
x
Reference in New Issue
Block a user