From f7a34846ba680445e1084e17facd408ee39bf7be Mon Sep 17 00:00:00 2001 From: James Tabor Date: Fri, 11 Jul 2008 23:07:31 +0000 Subject: [PATCH] - Christoph von Wittich spotted a condition when co_MsqPostKeyboardMessage was called from KeyboardThreadMain, the thread was unlocked when waiting in co_MsqSendMessage. The problem; UserLeave was called before waiting on an event. I added checks to verify locking and if not, lock the thread. I'm not sure ATM if co_MsqPostKeyboardMessage should have full locking since it is only used by input.c. - Added IdlePing to wakeup process threads before waiting on events, it look like the right place to put them. svn path=/trunk/; revision=34430 --- .../subsystems/win32/win32k/ntuser/msgqueue.c | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c index ee2f7fa2779..fae5d732608 100644 --- a/reactos/subsystems/win32/win32k/ntuser/msgqueue.c +++ b/reactos/subsystems/win32/win32k/ntuser/msgqueue.c @@ -64,6 +64,17 @@ static PAGED_LOOKASIDE_LIST TimerLookasideList; /* FUNCTIONS *****************************************************************/ +// +// Wakeup any thread/process waiting on idle input. +// +static VOID FASTCALL +IdlePing(VOID) +{ + PW32PROCESS W32d = PsGetCurrentProcessWin32Process(); + if (W32d && W32d->InputIdleEvent) + KePulseEvent( W32d->InputIdleEvent, EVENT_INCREMENT, TRUE); +} + HANDLE FASTCALL IntMsqSetWakeMask(DWORD WakeMask) { @@ -490,6 +501,8 @@ co_MsqPeekHardwareMessage(PUSER_MESSAGE_QUEUE MessageQueue, HWND hWnd, WaitObjects[0] = &HardwareMessageQueueLock; do { + IdlePing(); + UserLeaveCo(); WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest, @@ -690,6 +703,9 @@ CLEANUP: END_CLEANUP; } +// +// Note: Only called from input.c. +// VOID FASTCALL co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -698,6 +714,9 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) LARGE_INTEGER LargeTickCount; KBDLLHOOKSTRUCT KbdHookData; + // Condition may arise when calling MsqPostMessage and waiting for an event. + if (!UserIsEntered()) UserEnterExclusive(); // Fixme: Not sure ATM if this thread is locked. + DPRINT("MsqPostKeyboardMessage(uMsg 0x%x, wParam 0x%x, lParam 0x%x)\n", uMsg, wParam, lParam); @@ -726,14 +745,14 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) } FocusMessageQueue = IntGetFocusMessageQueue(); - if (FocusMessageQueue == NULL) - { + if (FocusMessageQueue == NULL) + { DPRINT("No focus message queue\n"); return; - } + } - if (FocusMessageQueue->FocusWindow != (HWND)0) - { + if (FocusMessageQueue->FocusWindow != (HWND)0) + { Msg.hwnd = FocusMessageQueue->FocusWindow; DPRINT("Msg.hwnd = %x\n", Msg.hwnd); @@ -742,12 +761,13 @@ co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) IntGetCursorLocation(FocusMessageQueue->Desktop->WindowStation, &Msg.pt); MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY); - } - else - { - DPRINT("Invalid focus window handle\n"); - } } + else + { + DPRINT("Invalid focus window handle\n"); + } + if (UserIsEntered()) UserLeave(); +} VOID FASTCALL MsqPostHotKeyMessage(PVOID Thread, HWND hWnd, WPARAM wParam, LPARAM lParam) @@ -1087,6 +1107,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, if(Block) { + IdlePing(); UserLeaveCo(); @@ -1149,6 +1170,7 @@ co_MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue, WaitObjects[1] = ThreadQueue->NewMessages; do { + IdlePing(); UserLeaveCo(); @@ -1304,6 +1326,8 @@ co_MsqWaitForNewMessages(PUSER_MESSAGE_QUEUE MessageQueue, HWND WndFilter, Timeout = NULL; } + IdlePing(); // Going to wait so send Idle ping. + UserLeaveCo(); ret = KeWaitForMultipleObjects(2,