Implemented direct message passing for local targets; this fixes a deadlock
with PostMessage() in case the message queue is full. Some notes: * for synchronous replies, we don't use this mechanism yet, but it could be extended to do that as well. * the code looks so complicated because we need a way to access the looper's queue without locking it (to prevent deadlocks); like Dano's solution, I've abused BTokenSpace to store a BDirectMessageTarget with a BHandler. * we also need to decouple the lifetime of a looper's queue from its target, as we cannot lock the looper, and therefore, can't guarantee it stays valid as long as we're accessing it outside of BLooper. * init_clipboard() now needs to be done after the global constructors have been called - since sending messages now needs gDefaultTokens to be initialized. Since this is done per image, it shouldn't cause any troubles, though. * some minor cleanup, removed unused _msg_cache_cleanup_() and friends. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@19968 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
class BMessage;
|
||||
class BMessageQueue;
|
||||
namespace BPrivate {
|
||||
class BDirectMessageTarget;
|
||||
class BLooperList;
|
||||
}
|
||||
|
||||
@@ -150,7 +151,7 @@ private:
|
||||
BHandler* resolve_specifier(BHandler* target, BMessage* msg);
|
||||
void UnlockFully();
|
||||
|
||||
BMessageQueue* fQueue;
|
||||
BPrivate::BDirectMessageTarget* fDirectTarget;
|
||||
BMessage* fLastMessage;
|
||||
port_id fMsgPort;
|
||||
int32 fAtomicCount;
|
||||
|
||||
+15
-19
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All Rights Reserved.
|
||||
* Copyright 2005-2007, Haiku Inc. All Rights Reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -22,13 +22,8 @@ class BMessenger;
|
||||
class BHandler;
|
||||
class BString;
|
||||
|
||||
// Private or reserved ---------------------------------------------------------
|
||||
extern "C" void _msg_cache_cleanup_();
|
||||
extern "C" int _init_message_();
|
||||
extern "C" int _delete_message_();
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
// Name lengths and Scripting specifiers ---------------------------------------
|
||||
// Name lengths and Scripting specifiers
|
||||
#define B_FIELD_NAME_LENGTH 255
|
||||
#define B_PROPERTY_NAME_LENGTH 255
|
||||
|
||||
@@ -57,7 +52,7 @@ class BMessage {
|
||||
|
||||
BMessage &operator=(const BMessage &other);
|
||||
|
||||
// Statistics and misc info
|
||||
// Statistics and misc info
|
||||
status_t GetInfo(type_code typeRequested, int32 index,
|
||||
char **nameFound, type_code *typeFound,
|
||||
int32 *countFound = NULL) const;
|
||||
@@ -74,7 +69,7 @@ class BMessage {
|
||||
|
||||
status_t Rename(const char *oldEntry, const char *newEntry);
|
||||
|
||||
// Delivery info
|
||||
// Delivery info
|
||||
bool WasDelivered() const;
|
||||
bool IsSourceWaiting() const;
|
||||
bool IsSourceRemote() const;
|
||||
@@ -83,7 +78,7 @@ class BMessage {
|
||||
bool WasDropped() const;
|
||||
BPoint DropPoint(BPoint *offset = NULL) const;
|
||||
|
||||
// Replying
|
||||
// Replying
|
||||
status_t SendReply(uint32 command, BHandler *replyTo = NULL);
|
||||
status_t SendReply(BMessage *reply, BHandler *replyTo = NULL,
|
||||
bigtime_t timeout = B_INFINITE_TIMEOUT);
|
||||
@@ -95,14 +90,14 @@ class BMessage {
|
||||
bigtime_t sendTimeout = B_INFINITE_TIMEOUT,
|
||||
bigtime_t replyTimeout = B_INFINITE_TIMEOUT);
|
||||
|
||||
// Flattening data
|
||||
// Flattening data
|
||||
ssize_t FlattenedSize() const;
|
||||
status_t Flatten(char *buffer, ssize_t size) const;
|
||||
status_t Flatten(BDataIO *stream, ssize_t *size = NULL) const;
|
||||
status_t Unflatten(const char *flatBuffer);
|
||||
status_t Unflatten(BDataIO *stream);
|
||||
|
||||
// Specifiers (scripting)
|
||||
// Specifiers (scripting)
|
||||
status_t AddSpecifier(const char *property);
|
||||
status_t AddSpecifier(const char *property, int32 index);
|
||||
status_t AddSpecifier(const char *property, int32 index, int32 range);
|
||||
@@ -116,7 +111,7 @@ class BMessage {
|
||||
bool HasSpecifiers() const;
|
||||
status_t PopSpecifier();
|
||||
|
||||
// Adding data
|
||||
// Adding data
|
||||
status_t AddRect(const char *name, BRect aRect);
|
||||
status_t AddPoint(const char *name, BPoint aPoint);
|
||||
status_t AddString(const char *name, const char *aString);
|
||||
@@ -138,12 +133,12 @@ class BMessage {
|
||||
const void *data, ssize_t numBytes,
|
||||
bool isFixedSize = true, int32 count = 1);
|
||||
|
||||
// Removing data
|
||||
// Removing data
|
||||
status_t RemoveData(const char *name, int32 index = 0);
|
||||
status_t RemoveName(const char *name);
|
||||
status_t MakeEmpty();
|
||||
|
||||
// Finding data
|
||||
// Finding data
|
||||
status_t FindRect(const char *name, BRect *rect) const;
|
||||
status_t FindRect(const char *name, int32 index, BRect *rect) const;
|
||||
status_t FindPoint(const char *name, BPoint *point) const;
|
||||
@@ -181,7 +176,7 @@ class BMessage {
|
||||
status_t FindData(const char *name, type_code type, int32 index,
|
||||
const void **data, ssize_t *numBytes) const;
|
||||
|
||||
// Replacing data
|
||||
// Replacing data
|
||||
status_t ReplaceRect(const char *name, BRect aRect);
|
||||
status_t ReplaceRect(const char *name, int32 index, BRect aRect);
|
||||
status_t ReplacePoint(const char *name, BPoint aPoint);
|
||||
@@ -223,7 +218,7 @@ class BMessage {
|
||||
void *operator new(size_t, void *pointer);
|
||||
void operator delete(void *pointer, size_t size);
|
||||
|
||||
// Private, reserved, or obsolete ----------------------------------------------
|
||||
// Private, reserved, or obsolete
|
||||
bool HasRect(const char *, int32 n = 0) const;
|
||||
bool HasPoint(const char *, int32 n = 0) const;
|
||||
bool HasString(const char *, int32 n = 0) const;
|
||||
@@ -303,8 +298,9 @@ class BMessage {
|
||||
virtual void _ReservedMessage2();
|
||||
virtual void _ReservedMessage3();
|
||||
|
||||
status_t _SendMessage(port_id port, int32 token, bigtime_t timeout,
|
||||
bool replyRequired, BMessenger &replyTo) const;
|
||||
status_t _SendMessage(port_id port, team_id portOwner, int32 token,
|
||||
bigtime_t timeout, bool replyRequired,
|
||||
BMessenger &replyTo) const;
|
||||
status_t _SendMessage(port_id port, team_id portOwner,
|
||||
int32 token, BMessage *reply, bigtime_t sendTimeout,
|
||||
bigtime_t replyTimeout) const;
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright 2007, Haiku, Inc.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
* Axel Dörfler, [email protected]
|
||||
*/
|
||||
#ifndef _DIRECT_MESSAGE_TARGET_H
|
||||
#define _DIRECT_MESSAGE_TARGET_H
|
||||
|
||||
|
||||
#include <MessageQueue.h>
|
||||
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class BDirectMessageTarget {
|
||||
public:
|
||||
BDirectMessageTarget();
|
||||
~BDirectMessageTarget();
|
||||
|
||||
bool AddMessage(BMessage* message);
|
||||
|
||||
void Close();
|
||||
void Acquire();
|
||||
void Release();
|
||||
|
||||
BMessageQueue* Queue() { return &fQueue; }
|
||||
|
||||
private:
|
||||
int32 fReferenceCount;
|
||||
BMessageQueue fQueue;
|
||||
bool fClosed;
|
||||
};
|
||||
|
||||
} // namespace BPrivate
|
||||
|
||||
#endif // _DIRECT_MESSAGE_TARGET_H
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2005, Haiku Inc. All rights reserved.
|
||||
* Copyright 2005-2007, Haiku Inc. All rights reserved.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -200,10 +200,10 @@ class BMessage::Private {
|
||||
}
|
||||
|
||||
status_t
|
||||
SendMessage(port_id port, int32 token, bigtime_t timeout,
|
||||
bool replyRequired, BMessenger &replyTo) const
|
||||
SendMessage(port_id port, team_id portOwner, int32 token,
|
||||
bigtime_t timeout, bool replyRequired, BMessenger &replyTo) const
|
||||
{
|
||||
return fMessage->_SendMessage(port, token,
|
||||
return fMessage->_SendMessage(port, portOwner, token,
|
||||
timeout, replyRequired, replyTo);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2001-2006, Haiku.
|
||||
* Copyright 2001-2007, Haiku.
|
||||
* Distributed under the terms of the MIT License.
|
||||
*
|
||||
* Authors:
|
||||
@@ -10,13 +10,13 @@
|
||||
#define _TOKEN_SPACE_H
|
||||
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
#include <BeBuild.h>
|
||||
#include <Locker.h>
|
||||
#include <SupportDefs.h>
|
||||
|
||||
#include <map>
|
||||
#include <stack>
|
||||
|
||||
|
||||
// token types as specified in targets
|
||||
#define B_PREFERRED_TOKEN -2 /* A little bird told me about this one */
|
||||
@@ -30,6 +30,9 @@
|
||||
|
||||
namespace BPrivate {
|
||||
|
||||
class BDirectMessageTarget;
|
||||
|
||||
|
||||
class BTokenSpace : public BLocker {
|
||||
public:
|
||||
BTokenSpace();
|
||||
@@ -40,12 +43,16 @@ class BTokenSpace : public BLocker {
|
||||
|
||||
bool RemoveToken(int32 token);
|
||||
bool CheckToken(int32 token, int16 type) const;
|
||||
status_t GetToken(int32 token, int16 type, void** object) const;
|
||||
status_t GetToken(int32 token, int16 type, void** _object) const;
|
||||
|
||||
status_t SetHandlerTarget(int32 token, BDirectMessageTarget* target);
|
||||
status_t AcquireHandlerTarget(int32 token, BDirectMessageTarget** _target);
|
||||
|
||||
private:
|
||||
struct token_info {
|
||||
int16 type;
|
||||
void* object;
|
||||
BDirectMessageTarget* target;
|
||||
};
|
||||
typedef std::map<int32, token_info> TokenMap;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user