* Forwarding message that had someone waiting for a reply did not work correctly;
both messages wanted to reply then, which could get the wrong reply (B_NO_REPLY) into the reply port. This fixes bug #513, took me some hours to figure that out... * _SendMessage() no longer allows to forward a message and asking for a synchronous reply that already has a source waiting for a reply. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17584 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1910,6 +1910,12 @@ BMessage::_SendMessage(port_id port, int32 token, bigtime_t timeout,
|
|||||||
B_RELATIVE_TIMEOUT, timeout);
|
B_RELATIVE_TIMEOUT, timeout);
|
||||||
} while (result == B_INTERRUPTED);
|
} while (result == B_INTERRUPTED);
|
||||||
|
|
||||||
|
if (result == B_OK && IsSourceWaiting()) {
|
||||||
|
// the forwarded message will handle the reply - we must not do
|
||||||
|
// this anymore
|
||||||
|
fHeader->flags |= MESSAGE_FLAG_REPLY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -1919,6 +1925,12 @@ status_t
|
|||||||
BMessage::_SendMessage(port_id port, team_id portOwner, int32 token,
|
BMessage::_SendMessage(port_id port, team_id portOwner, int32 token,
|
||||||
BMessage *reply, bigtime_t sendTimeout, bigtime_t replyTimeout) const
|
BMessage *reply, bigtime_t sendTimeout, bigtime_t replyTimeout) const
|
||||||
{
|
{
|
||||||
|
if (IsSourceWaiting()) {
|
||||||
|
// we can't forward this message synchronously when it's already
|
||||||
|
// waiting for a reply
|
||||||
|
return B_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
DEBUG_FUNCTION_ENTER;
|
DEBUG_FUNCTION_ENTER;
|
||||||
const int32 cachedReplyPort = _StaticGetCachedReplyPort();
|
const int32 cachedReplyPort = _StaticGetCachedReplyPort();
|
||||||
port_id replyPort = B_BAD_PORT_ID;
|
port_id replyPort = B_BAD_PORT_ID;
|
||||||
@@ -1950,12 +1962,19 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token,
|
|||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
|
// tests if the queue of the reply port is really empty
|
||||||
|
#if 0
|
||||||
|
port_info portInfo;
|
||||||
|
if (get_port_info(replyPort, &portInfo) == B_OK
|
||||||
|
&& portInfo.queue_count > 0)
|
||||||
|
debugger("reply port not empty!");
|
||||||
|
#endif
|
||||||
|
|
||||||
{
|
{
|
||||||
BMessenger messenger;
|
BMessenger replyTarget;
|
||||||
BMessenger::Private(messenger).SetTo(team, replyPort,
|
BMessenger::Private(replyTarget).SetTo(team, replyPort,
|
||||||
B_PREFERRED_TOKEN);
|
B_PREFERRED_TOKEN);
|
||||||
result = _SendMessage(port, token, sendTimeout, true,
|
result = _SendMessage(port, token, sendTimeout, true, replyTarget);
|
||||||
messenger);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result < B_OK)
|
if (result < B_OK)
|
||||||
@@ -2022,7 +2041,7 @@ BMessage::_SendFlattenedMessage(void *data, int32 size, port_id port,
|
|||||||
|
|
||||||
|
|
||||||
static status_t
|
static status_t
|
||||||
handle_reply(port_id replyPort, int32 *pCode, bigtime_t timeout,
|
handle_reply(port_id replyPort, int32 *_code, bigtime_t timeout,
|
||||||
BMessage *reply)
|
BMessage *reply)
|
||||||
{
|
{
|
||||||
DEBUG_FUNCTION_ENTER2;
|
DEBUG_FUNCTION_ENTER2;
|
||||||
@@ -2037,12 +2056,12 @@ handle_reply(port_id replyPort, int32 *pCode, bigtime_t timeout,
|
|||||||
status_t result;
|
status_t result;
|
||||||
char *buffer = (char *)malloc(size);
|
char *buffer = (char *)malloc(size);
|
||||||
do {
|
do {
|
||||||
result = read_port(replyPort, pCode, buffer, size);
|
result = read_port(replyPort, _code, buffer, size);
|
||||||
} while (result == B_INTERRUPTED);
|
} while (result == B_INTERRUPTED);
|
||||||
|
|
||||||
if (result < B_OK || *pCode != kPortMessageCode) {
|
if (result < B_OK || *_code != kPortMessageCode) {
|
||||||
free(buffer);
|
free(buffer);
|
||||||
return (result < B_OK ? result : B_ERROR);
|
return result < B_OK ? result : B_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = reply->Unflatten(buffer);
|
result = reply->Unflatten(buffer);
|
||||||
|
|||||||
@@ -385,15 +385,16 @@ status_t
|
|||||||
BMessenger::SendMessage(BMessage *message, BMessage *reply,
|
BMessenger::SendMessage(BMessage *message, BMessage *reply,
|
||||||
bigtime_t deliveryTimeout, bigtime_t replyTimeout) const
|
bigtime_t deliveryTimeout, bigtime_t replyTimeout) const
|
||||||
{
|
{
|
||||||
status_t error = (message && reply ? B_OK : B_BAD_VALUE);
|
if (message == NULL || reply == NULL)
|
||||||
if (error == B_OK) {
|
return B_BAD_VALUE;
|
||||||
error = BMessage::Private(message).SendMessage(fPort, fTeam,
|
|
||||||
fHandlerToken, reply, deliveryTimeout, replyTimeout);
|
status_t error = BMessage::Private(message).SendMessage(fPort, fTeam,
|
||||||
|
fHandlerToken, reply, deliveryTimeout, replyTimeout);
|
||||||
|
|
||||||
|
// Map this error for now:
|
||||||
|
if (error == B_BAD_TEAM_ID)
|
||||||
|
error = B_BAD_PORT_ID;
|
||||||
|
|
||||||
// Map this error for now:
|
|
||||||
if (error == B_BAD_TEAM_ID)
|
|
||||||
error = B_BAD_PORT_ID;
|
|
||||||
}
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user