Implemented all missing functionality save the actual sending of a
flattened message. Support for this needs to be added to BMessage first. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@11034 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
5ac1156848
commit
2c17b743c7
|
@ -20,6 +20,8 @@
|
||||||
// sDeliverer -- the singleton instance
|
// sDeliverer -- the singleton instance
|
||||||
MessageDeliverer *MessageDeliverer::sDeliverer = NULL;
|
MessageDeliverer *MessageDeliverer::sDeliverer = NULL;
|
||||||
|
|
||||||
|
static const bigtime_t kRetryDelay = 20000; // 20 ms
|
||||||
|
|
||||||
// Message
|
// Message
|
||||||
class MessageDeliverer::Message : public Referencable {
|
class MessageDeliverer::Message : public Referencable {
|
||||||
public:
|
public:
|
||||||
|
@ -123,6 +125,12 @@ public:
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~TargetPort()
|
||||||
|
{
|
||||||
|
while (fFirstMessage)
|
||||||
|
PopMessage();
|
||||||
|
}
|
||||||
|
|
||||||
port_id PortID() const
|
port_id PortID() const
|
||||||
{
|
{
|
||||||
return fPortID;
|
return fPortID;
|
||||||
|
@ -145,7 +153,7 @@ public:
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
Message *PeekMessage(int32 &token)
|
Message *PeekMessage(int32 &token) const
|
||||||
{
|
{
|
||||||
if (!fFirstMessage)
|
if (!fFirstMessage)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -165,6 +173,11 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IsEmpty() const
|
||||||
|
{
|
||||||
|
return !fFirstMessage;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
port_id fPortID;
|
port_id fPortID;
|
||||||
TargetMessage *fFirstMessage;
|
TargetMessage *fFirstMessage;
|
||||||
|
@ -189,8 +202,6 @@ MessageDeliverer::~MessageDeliverer()
|
||||||
{
|
{
|
||||||
fTerminating = true;
|
fTerminating = true;
|
||||||
|
|
||||||
// TODO: How to stop the thread?
|
|
||||||
|
|
||||||
if (fDelivererThread >= 0) {
|
if (fDelivererThread >= 0) {
|
||||||
int32 result;
|
int32 result;
|
||||||
wait_for_thread(fDelivererThread, &result);
|
wait_for_thread(fDelivererThread, &result);
|
||||||
|
@ -339,6 +350,25 @@ MessageDeliverer::DeliverMessage(const void *messageData, int32 messageSize,
|
||||||
if (!port)
|
if (!port)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
// try sending the message, if there are no queued messages yet
|
||||||
|
if (port->IsEmpty()) {
|
||||||
|
status_t error = _SendMessage(message, targets[i].port,
|
||||||
|
targets[i].token);
|
||||||
|
// if the message was delivered OK, we're done with the target
|
||||||
|
if (error == B_OK) {
|
||||||
|
_PutTargetPort(port);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if the port is not full, but an error occurred, we skip this target
|
||||||
|
if (error != B_WOULD_BLOCK) {
|
||||||
|
_PutTargetPort(port);
|
||||||
|
if (targetCount == 1)
|
||||||
|
return error;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// add the message
|
// add the message
|
||||||
status_t error = port->PushMessage(message, targets[i].token);
|
status_t error = port->PushMessage(message, targets[i].token);
|
||||||
_PutTargetPort(port);
|
_PutTargetPort(port);
|
||||||
|
@ -377,13 +407,20 @@ MessageDeliverer::_PutTargetPort(TargetPort *port)
|
||||||
if (!port)
|
if (!port)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int32 token;
|
if (port->IsEmpty()) {
|
||||||
if (!port->PeekMessage(token)) {
|
|
||||||
fTargetPorts->erase(port->PortID());
|
fTargetPorts->erase(port->PortID());
|
||||||
delete port;
|
delete port;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// _SendMessage
|
||||||
|
status_t
|
||||||
|
MessageDeliverer::_SendMessage(Message *message, port_id portID, int32 token)
|
||||||
|
{
|
||||||
|
// TODO: Implement!
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
// _DelivererThreadEntry
|
// _DelivererThreadEntry
|
||||||
int32
|
int32
|
||||||
MessageDeliverer::_DelivererThreadEntry(void *data)
|
MessageDeliverer::_DelivererThreadEntry(void *data)
|
||||||
|
@ -395,8 +432,43 @@ MessageDeliverer::_DelivererThreadEntry(void *data)
|
||||||
int32
|
int32
|
||||||
MessageDeliverer::_DelivererThread()
|
MessageDeliverer::_DelivererThread()
|
||||||
{
|
{
|
||||||
// while (fTerminating) {
|
while (!fTerminating) {
|
||||||
// }
|
snooze(kRetryDelay);
|
||||||
|
if (fTerminating)
|
||||||
|
break;
|
||||||
|
|
||||||
|
// iterate through all target ports and try sending the messages
|
||||||
|
BAutolock _(fLock);
|
||||||
|
for (TargetPortMap::iterator it = fTargetPorts->begin();
|
||||||
|
it != fTargetPorts->end();) {
|
||||||
|
TargetPort *port = it->second;
|
||||||
|
bool portError = false;
|
||||||
|
|
||||||
|
// try sending all messages
|
||||||
|
int32 token;
|
||||||
|
while (Message *message = port->PeekMessage(token)) {
|
||||||
|
status_t error = _SendMessage(message, port->PortID(), token);
|
||||||
|
if (error == B_OK) {
|
||||||
|
port->PopMessage();
|
||||||
|
} else if (error == B_WOULD_BLOCK) {
|
||||||
|
// no luck yet -- port is still full
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// unexpected error -- probably the port is gone
|
||||||
|
portError = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// next port
|
||||||
|
if (portError) {
|
||||||
|
TargetPortMap::iterator oldIt = it;
|
||||||
|
++it;
|
||||||
|
delete port;
|
||||||
|
fTargetPorts->erase(oldIt);
|
||||||
|
} else
|
||||||
|
++it;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -41,6 +41,8 @@ private:
|
||||||
TargetPort *_GetTargetPort(port_id portID, bool create = false);
|
TargetPort *_GetTargetPort(port_id portID, bool create = false);
|
||||||
void _PutTargetPort(TargetPort *port);
|
void _PutTargetPort(TargetPort *port);
|
||||||
|
|
||||||
|
status_t _SendMessage(Message *message, port_id portID, int32 token);
|
||||||
|
|
||||||
static int32 _DelivererThreadEntry(void *data);
|
static int32 _DelivererThreadEntry(void *data);
|
||||||
int32 _DelivererThread();
|
int32 _DelivererThread();
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue