[interfacekit] Re: BMessage::~BMessage()

On 2004-02-21 at 22:15:13 [+0100], Ingo Weinhold wrote:
> 
> I discovered, that our BMessage destructor implementation doesn't send a
> reply when none has been sent till that time.

In fact there are even more subtleties we haven't covered yet. The 
B_NO_REPLY message the BMessage destructor sends is filtered out by 
BLooper. It never hits MessageReceived(), DispatchMessage(), or any 
BMessageFilter::Filter(). The BMessage destructor must not send a 
B_NO_REPLY in this case, obviously.

One of the things I always wondered -- and cared to examine today -- is 
what happens, if one synchronously sends a message and a timeout occurs 
while waiting for the reply. Since the message already reached its target, 
a reply will eventually be sent and arrive at the temporary reply port. If 
this reply port would be reused later, the sender would get an erroneous 
reply. And, as it is, R5 actually deletes the reply port, if an error 
occurred while sending, and creates a new one (only if it was one of the 
three cached ports, of course).

Furthermore I discovered another intriguing feature: message forwarding. 
Those who, as I, believed, that the following code snippets are 
behaviorally equivalent, might be interested to learn that they are not:

        void MyHandler::MessageReceived(BMessage* message)
        {
                someLooper->PostMessage(message, someHandler);
        }

vs.

        void MyHandler::MessageReceived(BMessage* message)
        {
                BMessage copy(*message);
                someLooper->PostMessage(&copy, someHandler);
        }

The difference is, that the first version indeed forwards the original 
message, while the second one merely sends a copy. That is in the first 
case...

1) the message is considered replied, i.e. its destructor won't send a 
B_NO_REPLY.

2) the ReturnAddress() of the forwarded message will remain the same, even 
if one explicitly supplies a reply handler or messenger. Thus a reply to 
the forwarded message will be sent to the original sender (more correctly 
the reply target the original sender specified).

An implication of 2) is, that one cannot forward a message with a 
synchronous send method. R5 catches this case, entering the debugger with 
the message `can't do a synchronous send on a fowarded message.'

CU, Ingo

Other related posts: