From 85d981378a48b19a49cc0dadf80288b68b4e6447 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Fri, 25 Nov 2005 12:50:21 +0000 Subject: [PATCH] Quick fix for our broken locking model: The mouse filter needs to lock RootLayer, but the event dispatcher lock is held during that time, too, so that the focus cannot change in the mean time. On the other side, ServerWindow needs to lock the event dispatcher when adding or removing a listener, or for AS_GET_MOUSE - but since it always helds the root layer lock during message dispatching this easily resulted in a deadlock. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@15146 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- src/servers/app/EventDispatcher.cpp | 23 +++++++++++++++++------ src/servers/app/EventDispatcher.h | 2 ++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index b8584c0d43..f5d9e6b0e2 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -18,6 +18,7 @@ #include #include +#include //#define TRACE_EVENTS @@ -238,6 +239,7 @@ EventDispatcher::EventDispatcher() fKeyboardFilter(NULL), fTargets(10, true), // the list owns its items + fListenerLock("listener lock"), fCursorLock("cursor loop lock"), fHWInterface(NULL) { @@ -337,6 +339,8 @@ void EventDispatcher::SetFocus(const BMessenger* messenger) { BAutolock _(this); + BAutolock _temp(fListenerLock); + ETRACE(("EventDispatcher::SetFocus(messenger = %p)\n", messenger)); if ((messenger == NULL && fFocus == NULL) @@ -425,7 +429,7 @@ bool EventDispatcher::_AddListener(const BMessenger& messenger, int32 token, uint32 eventMask, uint32 options, bool temporary) { - BAutolock _(this); + BAutolock _(fListenerLock); Target* target = _FindTarget(messenger); if (target == NULL) { // we need a new target for this messenger @@ -504,7 +508,7 @@ EventDispatcher::AddTemporaryListener(const BMessenger& messenger, void EventDispatcher::RemoveListener(const BMessenger& messenger, int32 token) { - BAutolock _(this); + BAutolock _(fListenerLock); ETRACE(("events: remove listener token %ld\n", token)); int32 index; @@ -522,7 +526,7 @@ EventDispatcher::RemoveListener(const BMessenger& messenger, int32 token) void EventDispatcher::RemoveTemporaryListener(const BMessenger& messenger, int32 token) { - BAutolock _(this); + BAutolock _(fListenerLock); int32 index; Target* target = _FindTarget(messenger, &index); @@ -565,7 +569,7 @@ EventDispatcher::SetKeyboardFilter(BMessageFilter* filter) void EventDispatcher::GetMouse(BPoint& where, int32& buttons) { - BAutolock _(this); + //BAutolock _(this); where = fLastCursorPosition; buttons = fLastButtons; @@ -613,8 +617,10 @@ EventDispatcher::_SendMessage(BMessenger& messenger, BMessage* message, // TODO: add failed messages to a queue, and start dropping them by importance status_t status = messenger.SendMessage(message, (BHandler*)NULL, 100000); - if (status != B_OK) - printf("failed to send message to target: %lx\n", message->what); + if (status != B_OK) { + printf("EventDispatcher: failed to send message '%.4s' to target: %s\n", + (char*)&message->what, strerror(status)); + } if (status == B_BAD_PORT_ID) { // the target port is gone @@ -630,6 +636,9 @@ EventDispatcher::_AddTokens(BMessage* message, Target* target, uint32 eventMask) { _RemoveTokens(message); + BAutolock _(fListenerLock); + // temporary lock + int32 count = target->CountListeners(); for (int32 i = count; i-- > 0;) { event_listener* listener = target->ListenerAt(i); @@ -808,6 +817,8 @@ EventDispatcher::_EventLoop() event->RemoveName("_view_token"); } + BAutolock _temp(fListenerLock); + for (int32 i = fTargets.CountItems(); i-- > 0;) { Target* target = fTargets.ItemAt(i); diff --git a/src/servers/app/EventDispatcher.h b/src/servers/app/EventDispatcher.h index 59df224c19..f0435b7ed6 100644 --- a/src/servers/app/EventDispatcher.h +++ b/src/servers/app/EventDispatcher.h @@ -92,6 +92,8 @@ class EventDispatcher : public BLocker { BPoint fLastCursorPosition; int32 fLastButtons; + BLocker fListenerLock; + // temporary locker until we have an actual locking model BLocker fCursorLock; HWInterface* fHWInterface; };