diff --git a/headers/os/app/Looper.h b/headers/os/app/Looper.h index 76016bc4f5..5aa7eadec8 100644 --- a/headers/os/app/Looper.h +++ b/headers/os/app/Looper.h @@ -52,6 +52,8 @@ public: virtual void MessageReceived(BMessage* message); BMessage* CurrentMessage() const; BMessage* DetachCurrentMessage(); + void DispatchExternalMessage(BMessage* message, + BHandler* handler, bool& _detached); BMessageQueue* MessageQueue() const; bool IsMessageWaiting() const; diff --git a/src/kits/app/Looper.cpp b/src/kits/app/Looper.cpp index ecf4637198..4af20167fa 100644 --- a/src/kits/app/Looper.cpp +++ b/src/kits/app/Looper.cpp @@ -300,6 +300,22 @@ BLooper::DetachCurrentMessage() } +void +BLooper::DispatchExternalMessage(BMessage* message, BHandler* handler, + bool& _detached) +{ + AssertLocked(); + + BMessage* previousMessage = fLastMessage; + fLastMessage = message; + + DispatchMessage(message, handler); + + _detached = fLastMessage == NULL; + fLastMessage = previousMessage; +} + + BMessageQueue* BLooper::MessageQueue() const { @@ -1115,11 +1131,14 @@ BLooper::task_looper() bool dispatchNextMessage = true; while (!fTerminating && dispatchNextMessage) { PRINT(("LOOPER: inner loop\n")); - // Get next message from queue (assign to fLastMessage) - fLastMessage = fDirectTarget->Queue()->NextMessage(); + // Get next message from queue (assign to fLastMessage after + // locking) + BMessage* message = fDirectTarget->Queue()->NextMessage(); Lock(); + fLastMessage = message; + if (!fLastMessage) { // No more messages: Unlock the looper and terminate the // dispatch loop. @@ -1173,14 +1192,15 @@ BLooper::task_looper() return; } + message = fLastMessage; + fLastMessage = NULL; + // Unlock the looper Unlock(); // Delete the current message (fLastMessage) - if (fLastMessage) { - delete fLastMessage; - fLastMessage = NULL; - } + if (message != NULL) + delete message; // Are any messages on the port? if (port_count(fMsgPort) > 0) { diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index 5e3de7918d..f23681f23d 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -3037,12 +3037,17 @@ BWindow::task_looper() bool dispatchNextMessage = true; while (!fTerminating && dispatchNextMessage) { - // Get next message from queue (assign to fLastMessage) - fLastMessage = fDirectTarget->Queue()->NextMessage(); + // Get next message from queue (assign to fLastMessage after + // locking) + BMessage* message = fDirectTarget->Queue()->NextMessage(); // Lock the looper - if (!Lock()) + if (!Lock()) { + delete message; break; + } + + fLastMessage = message; if (fLastMessage == NULL) { // No more messages: Unlock the looper and terminate the