Author: jimtabor Date: Fri Jul 11 18:07:31 2008 New Revision: 34430
URL: http://svn.reactos.org/svn/reactos?rev=34430&view=rev Log: - 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.
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c
Modified: trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c URL: http://svn.reactos.org/svn/reactos/trunk/reactos/subsystems/win32/win32k/ntu... ============================================================================== --- trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] (original) +++ trunk/reactos/subsystems/win32/win32k/ntuser/msgqueue.c [iso-8859-1] Fri Jul 11 18:07:31 2008 @@ -64,6 +64,17 @@
/* 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 @@ WaitObjects[0] = &HardwareMessageQueueLock; do { + IdlePing(); + UserLeaveCo();
WaitStatus = KeWaitForMultipleObjects(2, WaitObjects, WaitAny, UserRequest, @@ -690,6 +703,9 @@ END_CLEANUP; }
+// +// Note: Only called from input.c. +// VOID FASTCALL co_MsqPostKeyboardMessage(UINT uMsg, WPARAM wParam, LPARAM lParam) { @@ -697,6 +713,9 @@ MSG Msg; 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 @@ }
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 @@ IntGetCursorLocation(FocusMessageQueue->Desktop->WindowStation, &Msg.pt); MsqPostMessage(FocusMessageQueue, &Msg, FALSE, QS_KEY); - } - else - { + } + 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 @@
if(Block) { + IdlePing();
UserLeaveCo();
@@ -1149,6 +1170,7 @@ WaitObjects[1] = ThreadQueue->NewMessages; do { + IdlePing();
UserLeaveCo();
@@ -1303,6 +1325,8 @@ { Timeout = NULL; } + + IdlePing(); // Going to wait so send Idle ping.
UserLeaveCo();