From c1c0c220912dc1a11786ca0a3c119942fdb31e08 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Mon, 5 Feb 2007 16:04:46 +0000 Subject: [PATCH] * In the BMessage assignment operator we do now clear some of the message header flags after copying the header of the original message. Before cloning a message that still needed a reply would result in the clone also needing a reply, which, in the end, led to two replies being sent, thus screwing up the cached reply ports used for synchronous messaging. Fixes bug #1008. BTW, also clearing the reply info breaks Tracker and Deskbar, so I suppose R5 keeps it and Tracker and Deskbar rely on that behavior. * Added a bit of debug code removing and printing spurious messages from a cached reply port. * Added TODO in BMessage::~BMessage(). ATM, we only send a B_NO_REPLY in the destructor, but not in case the message is overwritten using the assignment operator or Flatten(). git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20074 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/kits/app/Message.cpp | 38 +++++++++++++++++++++++++++++++++++++- 1 file changed, 37 insertions(+), 1 deletion(-) diff --git a/src/kits/app/Message.cpp b/src/kits/app/Message.cpp index 7706fa9eeb..757f375b45 100644 --- a/src/kits/app/Message.cpp +++ b/src/kits/app/Message.cpp @@ -102,6 +102,7 @@ BMessage::BMessage(const BMessage &other) BMessage::~BMessage() { DEBUG_FUNCTION_ENTER; + // TODO: Check why we don't do that in _Clear() and fix or comment it. if (IsSourceWaiting()) SendReply(B_NO_REPLY); @@ -119,6 +120,13 @@ BMessage::operator=(const BMessage &other) fHeader = (message_header *)malloc(sizeof(message_header)); memcpy(fHeader, other.fHeader, sizeof(message_header)); + // Clear some header flags inherited from the original message that don't + // apply to the clone. + fHeader->flags &= ~(MESSAGE_FLAG_REPLY_REQUIRED | MESSAGE_FLAG_REPLY_DONE + | MESSAGE_FLAG_IS_REPLY | MESSAGE_FLAG_WAS_DELIVERED + | MESSAGE_FLAG_WAS_DROPPED | MESSAGE_FLAG_PASS_BY_AREA); + // Note, that BeOS R5 seems to keep the reply info. + if (fHeader->fields_size > 0) { fFields = (field_header *)malloc(fHeader->fields_size); memcpy(fFields, other.fFields, fHeader->fields_size); @@ -1988,8 +1996,36 @@ BMessage::_SendMessage(port_id port, team_id portOwner, int32 token, #if 0 port_info portInfo; if (get_port_info(replyPort, &portInfo) == B_OK - && portInfo.queue_count > 0) + && portInfo.queue_count > 0) { debugger("reply port not empty!"); + printf(" reply port not empty! %ld message(s) in queue\n", + portInfo.queue_count); + + // fetch and print the messages + for (int32 i = 0; i < portInfo.queue_count; i++) { + char buffer[1024]; + int32 code; + ssize_t size = read_port(replyPort, &code, buffer, sizeof(buffer)); + if (size < 0) { + printf("failed to read message from reply port\n"); + continue; + } + if (size >= (ssize_t)sizeof(buffer)) { + printf("message from reply port too big\n"); + continue; + } + + BMemoryIO stream(buffer, size); + BMessage reply; + if (reply.Unflatten(&stream) != B_OK) { + printf("failed to unflatten message from reply port\n"); + continue; + } + + printf("message %ld from reply port:\n", i); + reply.PrintToStream(); + } + } #endif {