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/nt…
==============================================================================
--- 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();