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
This commit is contained in:
parent
2bea891d75
commit
85d981378a
@ -18,6 +18,7 @@
|
||||
|
||||
#include <new>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
//#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);
|
||||
|
||||
|
@ -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;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user