Reverted my changes to timers

svn path=/trunk/; revision=10400
This commit is contained in:
Thomas Bluemel 2004-08-04 22:31:17 +00:00
parent f34c1d586a
commit 0004f90a07
5 changed files with 86 additions and 84 deletions

View file

@ -17,20 +17,17 @@ typedef struct _USER_MESSAGE
struct _USER_MESSAGE_QUEUE; struct _USER_MESSAGE_QUEUE;
#define USMF_WAKE_SENDER 0x1
typedef struct _USER_SENT_MESSAGE typedef struct _USER_SENT_MESSAGE
{ {
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
MSG Msg; MSG Msg;
LRESULT Result; PKEVENT CompletionEvent;
ULONG Flags; /* the sender queue must be locked to access this field!!! */ LRESULT* Result;
struct _USER_MESSAGE_QUEUE* SenderQueue; struct _USER_MESSAGE_QUEUE* SenderQueue;
SENDASYNCPROC CompletionCallback; SENDASYNCPROC CompletionCallback;
ULONG_PTR CompletionCallbackContext; ULONG_PTR CompletionCallbackContext;
/* entry in the dispatching list of the sender's message queue */ /* entry in the dispatching list of the sender's message queue */
LIST_ENTRY DispatchingListEntry; LIST_ENTRY DispatchingListEntry;
KEVENT CompletionEvent;
} USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE; } USER_SENT_MESSAGE, *PUSER_SENT_MESSAGE;
typedef struct _USER_SENT_MESSAGE_NOTIFY typedef struct _USER_SENT_MESSAGE_NOTIFY

View file

@ -4,15 +4,15 @@
typedef struct _MSG_TIMER_ENTRY{ typedef struct _MSG_TIMER_ENTRY{
LIST_ENTRY ListEntry; LIST_ENTRY ListEntry;
LARGE_INTEGER Timeout; LARGE_INTEGER Timeout;
struct _USER_MESSAGE_QUEUE* MessageQueue; HANDLE ThreadID;
UINT Period; UINT Period;
MSG Msg; MSG Msg;
} MSG_TIMER_ENTRY, *PMSG_TIMER_ENTRY; } MSG_TIMER_ENTRY, *PMSG_TIMER_ENTRY;
NTSTATUS FASTCALL InitTimerImpl(VOID); NTSTATUS FASTCALL InitTimerImpl(VOID);
VOID FASTCALL RemoveTimersThread(PUSER_MESSAGE_QUEUE MessageQueue); VOID FASTCALL RemoveTimersThread(HANDLE ThreadID);
VOID FASTCALL RemoveTimersWindow(HWND hWnd); VOID FASTCALL RemoveTimersWindow(HWND hWnd);
PMSG_TIMER_ENTRY FASTCALL IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, BOOL SysTimer); PMSG_TIMER_ENTRY FASTCALL IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, HANDLE ThreadID, BOOL SysTimer);
UINT_PTR FASTCALL IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, BOOL SystemTimer); UINT_PTR FASTCALL IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, BOOL SystemTimer);
#endif /* _WIN32K_TIMER_H */ #endif /* _WIN32K_TIMER_H */

View file

@ -1,4 +1,4 @@
/* $Id: caret.c,v 1.13 2004/07/30 09:16:06 weiden Exp $ /* $Id: caret.c,v 1.14 2004/08/04 22:31:17 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -262,7 +262,7 @@ NtUserCreateCaret(
return FALSE; return FALSE;
} }
IntRemoveTimer(hWnd, IDCARETTIMER, TRUE); IntRemoveTimer(hWnd, IDCARETTIMER, PsGetCurrentThreadId(), TRUE);
ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue; ThreadQueue = (PUSER_MESSAGE_QUEUE)PsGetWin32Thread()->MessageQueue;
@ -347,7 +347,7 @@ NtUserHideCaret(
if(ThreadQueue->CaretInfo->Visible) if(ThreadQueue->CaretInfo->Visible)
{ {
IntRemoveTimer(hWnd, IDCARETTIMER, TRUE); IntRemoveTimer(hWnd, IDCARETTIMER, PsGetCurrentThreadId(), TRUE);
IntHideCaret(ThreadQueue->CaretInfo); IntHideCaret(ThreadQueue->CaretInfo);
ThreadQueue->CaretInfo->Visible = 0; ThreadQueue->CaretInfo->Visible = 0;

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: msgqueue.c,v 1.101 2004/07/30 09:16:06 weiden Exp $ /* $Id: msgqueue.c,v 1.102 2004/08/04 22:31:17 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -729,7 +729,7 @@ MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
PUSER_SENT_MESSAGE Message; PUSER_SENT_MESSAGE Message;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
LRESULT Result; LRESULT Result;
BOOL Freed, Wake; BOOL Freed;
PUSER_SENT_MESSAGE_NOTIFY NotifyMessage; PUSER_SENT_MESSAGE_NOTIFY NotifyMessage;
IntLockMessageQueue(MessageQueue); IntLockMessageQueue(MessageQueue);
@ -775,18 +775,22 @@ MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
MsqSendMessage() function (if timed out) */ MsqSendMessage() function (if timed out) */
/* Let the sender know the result. */ /* Let the sender know the result. */
Message->Result = Result; if (Message->Result != NULL)
Wake = (Message->Flags & USMF_WAKE_SENDER) != 0;
/* Notify the sender. */
if (Wake)
{ {
KeSetEvent(&Message->CompletionEvent, IO_NO_INCREMENT, FALSE); *Message->Result = Result;
} }
/* Notify the sender. */
if (Message->CompletionEvent != NULL)
{
KeSetEvent(Message->CompletionEvent, IO_NO_INCREMENT, FALSE);
}
/* unlock the sender's message queue, the safe operation is done */
IntUnLockMessageQueue(Message->SenderQueue);
/* Notify the sender if they specified a callback. */ /* Notify the sender if they specified a callback. */
if (!Freed && Wake) if (!Freed && Message->CompletionCallback != NULL)
{ {
if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool, if(!(NotifyMessage = ExAllocatePoolWithTag(NonPagedPool,
sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG))) sizeof(USER_SENT_MESSAGE_NOTIFY), TAG_USRMSG)))
@ -794,7 +798,6 @@ MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n"); DPRINT1("MsqDispatchOneSentMessage(): Not enough memory to create a callback notify message\n");
goto Notified; goto Notified;
} }
/* FIXME
NotifyMessage->CompletionCallback = NotifyMessage->CompletionCallback =
Message->CompletionCallback; Message->CompletionCallback;
NotifyMessage->CompletionCallbackContext = NotifyMessage->CompletionCallbackContext =
@ -803,23 +806,16 @@ MsqDispatchOneSentMessage(PUSER_MESSAGE_QUEUE MessageQueue)
NotifyMessage->hWnd = Message->Msg.hwnd; NotifyMessage->hWnd = Message->Msg.hwnd;
NotifyMessage->Msg = Message->Msg.message; NotifyMessage->Msg = Message->Msg.message;
MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage); MsqSendNotifyMessage(Message->SenderQueue, NotifyMessage);
*/
} }
Notified: Notified:
/* unlock the sender's message queue, the safe operation is done */
IntUnLockMessageQueue(Message->SenderQueue);
if(!Wake)
{
IntDereferenceMessageQueue(Message->SenderQueue);
}
if(!Freed) if(!Freed)
{ {
/* only dereference our message queue if the message has not been timed out */ /* only dereference our message queue if the message has not been timed out */
IntDereferenceMessageQueue(MessageQueue); IntDereferenceMessageQueue(MessageQueue);
} }
/* only free the message if not freed already */
ExFreePool(Message); ExFreePool(Message);
return(TRUE); return(TRUE);
} }
@ -841,7 +837,9 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
UINT uTimeout, BOOL Block, ULONG_PTR *uResult) UINT uTimeout, BOOL Block, ULONG_PTR *uResult)
{ {
PUSER_SENT_MESSAGE Message; PUSER_SENT_MESSAGE Message;
KEVENT CompletionEvent;
NTSTATUS WaitStatus; NTSTATUS WaitStatus;
LRESULT Result;
PUSER_MESSAGE_QUEUE ThreadQueue; PUSER_MESSAGE_QUEUE ThreadQueue;
LARGE_INTEGER Timeout; LARGE_INTEGER Timeout;
PLIST_ENTRY Entry; PLIST_ENTRY Entry;
@ -852,24 +850,26 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
return STATUS_INSUFFICIENT_RESOURCES; return STATUS_INSUFFICIENT_RESOURCES;
} }
KeInitializeEvent(&Message->CompletionEvent, NotificationEvent, FALSE); KeInitializeEvent(&CompletionEvent, NotificationEvent, FALSE);
ThreadQueue = PsGetWin32Thread()->MessageQueue; ThreadQueue = PsGetWin32Thread()->MessageQueue;
ASSERT(ThreadQueue != MessageQueue); ASSERT(ThreadQueue != MessageQueue);
Timeout.QuadPart = uTimeout * -10000; Timeout.QuadPart = uTimeout * -10000;
/* FIXME - increase reference counter of sender's message queue here */
Result = 0;
Message->Msg.hwnd = Wnd; Message->Msg.hwnd = Wnd;
Message->Msg.message = Msg; Message->Msg.message = Msg;
Message->Msg.wParam = wParam; Message->Msg.wParam = wParam;
Message->Msg.lParam = lParam; Message->Msg.lParam = lParam;
Message->Result = 0; Message->CompletionEvent = &CompletionEvent;
Message->Flags = USMF_WAKE_SENDER; Message->Result = &Result;
Message->SenderQueue = ThreadQueue; Message->SenderQueue = ThreadQueue;
Message->CompletionCallback = NULL; Message->CompletionCallback = NULL;
IntReferenceMessageQueue(MessageQueue); IntReferenceMessageQueue(MessageQueue);
IntReferenceMessageQueue(ThreadQueue);
/* add it to the list of pending messages */ /* add it to the list of pending messages */
IntLockMessageQueue(ThreadQueue); IntLockMessageQueue(ThreadQueue);
@ -888,11 +888,11 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
if(Block) if(Block)
{ {
/* don't process messages sent to the thread */ /* don't process messages sent to the thread */
WaitStatus = KeWaitForSingleObject(&Message->CompletionEvent, UserRequest, UserMode, WaitStatus = KeWaitForSingleObject(&CompletionEvent, UserRequest, UserMode,
FALSE, (uTimeout ? &Timeout : NULL)); FALSE, (uTimeout ? &Timeout : NULL));
if(WaitStatus == STATUS_TIMEOUT) if(WaitStatus == STATUS_TIMEOUT)
{ {
/* look up if the message has not yet been dispatched, if so /* look up if the message has not yet dispatched, if so
make sure it can't pass a result and it must not set the completion event anymore */ make sure it can't pass a result and it must not set the completion event anymore */
IntLockMessageQueue(MessageQueue); IntLockMessageQueue(MessageQueue);
Entry = MessageQueue->SentMessagesListHead.Flink; Entry = MessageQueue->SentMessagesListHead.Flink;
@ -901,11 +901,10 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry)
== Message) == Message)
{ {
IntLockMessageQueue(ThreadQueue); /* we can access Message here, it's secure because the message queue is locked
/* we can access Message here, it's secure because the sender message queue is locked
and the message is still hasn't been dispatched */ and the message is still hasn't been dispatched */
Message->Flags &= ~USMF_WAKE_SENDER; Message->CompletionEvent = NULL;
IntUnLockMessageQueue(ThreadQueue); Message->Result = NULL;
break; break;
} }
Entry = Entry->Flink; Entry = Entry->Flink;
@ -925,7 +924,8 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
and the message has definitely not yet been destroyed, otherwise it would and the message has definitely not yet been destroyed, otherwise it would
have been removed from this list by the dispatching routine right after have been removed from this list by the dispatching routine right after
dispatching the message */ dispatching the message */
Message->Flags &= ~USMF_WAKE_SENDER; Message->CompletionEvent = NULL;
Message->Result = NULL;
RemoveEntryList(&Message->DispatchingListEntry); RemoveEntryList(&Message->DispatchingListEntry);
IntDereferenceMessageQueue(MessageQueue); IntDereferenceMessageQueue(MessageQueue);
break; break;
@ -942,7 +942,7 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
{ {
PVOID WaitObjects[2]; PVOID WaitObjects[2];
WaitObjects[0] = &Message->CompletionEvent; WaitObjects[0] = &CompletionEvent;
WaitObjects[1] = &ThreadQueue->NewMessages; WaitObjects[1] = &ThreadQueue->NewMessages;
do do
{ {
@ -959,11 +959,10 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry) if ((PUSER_SENT_MESSAGE) CONTAINING_RECORD(Entry, USER_SENT_MESSAGE, ListEntry)
== Message) == Message)
{ {
IntLockMessageQueue(ThreadQueue); /* we can access Message here, it's secure because the message queue is locked
/* we can access Message here, it's secure because the sender message queue is locked
and the message is still hasn't been dispatched */ and the message is still hasn't been dispatched */
Message->Flags &= ~USMF_WAKE_SENDER; Message->CompletionEvent = NULL;
IntUnLockMessageQueue(ThreadQueue); Message->Result = NULL;
break; break;
} }
Entry = Entry->Flink; Entry = Entry->Flink;
@ -983,7 +982,8 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
and the message has definitely not yet been destroyed, otherwise it would and the message has definitely not yet been destroyed, otherwise it would
have been removed from this list by the dispatching routine right after have been removed from this list by the dispatching routine right after
dispatching the message */ dispatching the message */
Message->Flags &= ~USMF_WAKE_SENDER; Message->CompletionEvent = NULL;
Message->Result = NULL;
RemoveEntryList(&Message->DispatchingListEntry); RemoveEntryList(&Message->DispatchingListEntry);
IntDereferenceMessageQueue(MessageQueue); IntDereferenceMessageQueue(MessageQueue);
break; break;
@ -1001,13 +1001,7 @@ MsqSendMessage(PUSER_MESSAGE_QUEUE MessageQueue,
} }
if(WaitStatus != STATUS_TIMEOUT) if(WaitStatus != STATUS_TIMEOUT)
{ *uResult = (STATUS_WAIT_0 == WaitStatus ? Result : -1);
*uResult = (STATUS_WAIT_0 == WaitStatus ? Message->Result : -1);
}
else
{
IntDereferenceMessageQueue(ThreadQueue);
}
return WaitStatus; return WaitStatus;
} }
@ -1165,9 +1159,9 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
} }
/* wake the sender's thread */ /* wake the sender's thread */
if (CurrentSentMessage->Flags & USMF_WAKE_SENDER) if (CurrentSentMessage->CompletionEvent != NULL)
{ {
KeSetEvent(&CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
} }
/* dereference our message queue */ /* dereference our message queue */
@ -1188,9 +1182,9 @@ MsqCleanupMessageQueue(PUSER_MESSAGE_QUEUE MessageQueue)
DPRINT("Notify the sender, the thread has been terminated while dispatching a message!\n"); DPRINT("Notify the sender, the thread has been terminated while dispatching a message!\n");
/* wake the sender's thread */ /* wake the sender's thread */
if (CurrentSentMessage->Flags & USMF_WAKE_SENDER) if (CurrentSentMessage->CompletionEvent != NULL)
{ {
KeSetEvent(&CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE); KeSetEvent(CurrentSentMessage->CompletionEvent, IO_NO_INCREMENT, FALSE);
} }
/* dereference our message queue */ /* dereference our message queue */

View file

@ -16,7 +16,7 @@
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/ */
/* $Id: timer.c,v 1.34 2004/07/30 09:16:06 weiden Exp $ /* $Id: timer.c,v 1.35 2004/08/04 22:31:17 weiden Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -85,11 +85,10 @@ IntInsertTimerAscendingOrder(PMSG_TIMER_ENTRY NewTimer)
//must hold mutex while calling this //must hold mutex while calling this
PMSG_TIMER_ENTRY FASTCALL PMSG_TIMER_ENTRY FASTCALL
IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, BOOL SysTimer) IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, HANDLE ThreadID, BOOL SysTimer)
{ {
PMSG_TIMER_ENTRY MsgTimer; PMSG_TIMER_ENTRY MsgTimer;
PLIST_ENTRY EnumEntry; PLIST_ENTRY EnumEntry;
PUSER_MESSAGE_QUEUE MessageQueue = PsGetWin32Thread()->MessageQueue;
//remove timer if already in the queue //remove timer if already in the queue
EnumEntry = TimerListHead.Flink; EnumEntry = TimerListHead.Flink;
@ -100,7 +99,7 @@ IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, BOOL SysTimer)
if (MsgTimer->Msg.hwnd == hWnd && if (MsgTimer->Msg.hwnd == hWnd &&
MsgTimer->Msg.wParam == (WPARAM)IDEvent && MsgTimer->Msg.wParam == (WPARAM)IDEvent &&
MsgTimer->MessageQueue == MessageQueue && MsgTimer->ThreadID == ThreadID &&
(MsgTimer->Msg.message == WM_SYSTIMER) == SysTimer) (MsgTimer->Msg.message == WM_SYSTIMER) == SysTimer)
{ {
RemoveEntryList(&MsgTimer->ListEntry); RemoveEntryList(&MsgTimer->ListEntry);
@ -116,16 +115,11 @@ IntRemoveTimer(HWND hWnd, UINT_PTR IDEvent, BOOL SysTimer)
* NOTE: It doesn't kill the timer. It just removes them from the list. * NOTE: It doesn't kill the timer. It just removes them from the list.
*/ */
VOID FASTCALL VOID FASTCALL
RemoveTimersThread(PUSER_MESSAGE_QUEUE MessageQueue) RemoveTimersThread(HANDLE ThreadID)
{ {
PMSG_TIMER_ENTRY MsgTimer; PMSG_TIMER_ENTRY MsgTimer;
PLIST_ENTRY EnumEntry; PLIST_ENTRY EnumEntry;
if(MessageQueue == NULL)
{
return;
}
IntLockTimerList(); IntLockTimerList();
EnumEntry = TimerListHead.Flink; EnumEntry = TimerListHead.Flink;
@ -134,7 +128,7 @@ RemoveTimersThread(PUSER_MESSAGE_QUEUE MessageQueue)
MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry); MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
EnumEntry = EnumEntry->Flink; EnumEntry = EnumEntry->Flink;
if (MsgTimer->MessageQueue == MessageQueue) if (MsgTimer->ThreadID == ThreadID)
{ {
if (MsgTimer->Msg.hwnd == NULL) if (MsgTimer->Msg.hwnd == NULL)
{ {
@ -142,9 +136,6 @@ RemoveTimersThread(PUSER_MESSAGE_QUEUE MessageQueue)
} }
RemoveEntryList(&MsgTimer->ListEntry); RemoveEntryList(&MsgTimer->ListEntry);
IntDereferenceMessageQueue(MsgTimer->MessageQueue);
ExFreePool(MsgTimer); ExFreePool(MsgTimer);
} }
} }
@ -173,9 +164,6 @@ RemoveTimersWindow(HWND Wnd)
if (MsgTimer->Msg.hwnd == Wnd) if (MsgTimer->Msg.hwnd == Wnd)
{ {
RemoveEntryList(&MsgTimer->ListEntry); RemoveEntryList(&MsgTimer->ListEntry);
IntDereferenceMessageQueue(MsgTimer->MessageQueue);
ExFreePool(MsgTimer); ExFreePool(MsgTimer);
} }
} }
@ -191,8 +179,10 @@ IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, B
PMSG_TIMER_ENTRY NewTimer; PMSG_TIMER_ENTRY NewTimer;
LARGE_INTEGER CurrentTime; LARGE_INTEGER CurrentTime;
PWINDOW_OBJECT WindowObject; PWINDOW_OBJECT WindowObject;
HANDLE ThreadID;
UINT_PTR Ret = 0; UINT_PTR Ret = 0;
ThreadID = PsGetCurrentThreadId();
KeQuerySystemTime(&CurrentTime); KeQuerySystemTime(&CurrentTime);
IntLockTimerList(); IntLockTimerList();
@ -229,7 +219,7 @@ IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, B
IntReleaseWindowObject(WindowObject); IntReleaseWindowObject(WindowObject);
/* remove timer if already in the queue */ /* remove timer if already in the queue */
MsgTimer = IntRemoveTimer(hWnd, nIDEvent, SystemTimer); MsgTimer = IntRemoveTimer(hWnd, nIDEvent, ThreadID, SystemTimer);
} }
#if 1 #if 1
@ -276,9 +266,7 @@ IntSetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc, B
NewTimer->Msg.lParam = (LPARAM)lpTimerFunc; NewTimer->Msg.lParam = (LPARAM)lpTimerFunc;
NewTimer->Period = uElapse; NewTimer->Period = uElapse;
NewTimer->Timeout.QuadPart = CurrentTime.QuadPart + (uElapse * 10000); NewTimer->Timeout.QuadPart = CurrentTime.QuadPart + (uElapse * 10000);
NewTimer->MessageQueue = PsGetWin32Thread()->MessageQueue; NewTimer->ThreadID = ThreadID;
IntReferenceMessageQueue(NewTimer->MessageQueue);
} }
Ret = nIDEvent; // FIXME - return lpTimerProc if it's not a system timer Ret = nIDEvent; // FIXME - return lpTimerProc if it's not a system timer
@ -334,7 +322,7 @@ IntKillTimer(HWND hWnd, UINT_PTR uIDEvent, BOOL SystemTimer)
IntReleaseWindowObject(WindowObject); IntReleaseWindowObject(WindowObject);
} }
MsgTimer = IntRemoveTimer(hWnd, uIDEvent, SystemTimer); MsgTimer = IntRemoveTimer(hWnd, uIDEvent, PsGetCurrentThreadId(), SystemTimer);
IntUnLockTimerList(); IntUnLockTimerList();
@ -345,8 +333,6 @@ IntKillTimer(HWND hWnd, UINT_PTR uIDEvent, BOOL SystemTimer)
return FALSE; return FALSE;
} }
IntReferenceMessageQueue(MsgTimer->MessageQueue);
/* FIXME: use lookaside? */ /* FIXME: use lookaside? */
ExFreePool(MsgTimer); ExFreePool(MsgTimer);
@ -360,6 +346,9 @@ TimerThreadMain(PVOID StartContext)
LARGE_INTEGER CurrentTime; LARGE_INTEGER CurrentTime;
PLIST_ENTRY EnumEntry; PLIST_ENTRY EnumEntry;
PMSG_TIMER_ENTRY MsgTimer; PMSG_TIMER_ENTRY MsgTimer;
PETHREAD Thread;
PETHREAD *ThreadsToDereference;
ULONG ThreadsToDereferenceCount, ThreadsToDereferencePos, i;
for(;;) for(;;)
{ {
@ -374,6 +363,8 @@ TimerThreadMain(PVOID StartContext)
KEBUGCHECK(0); KEBUGCHECK(0);
} }
ThreadsToDereferenceCount = ThreadsToDereferencePos = 0;
IntLockTimerList(); IntLockTimerList();
KeQuerySystemTime(&CurrentTime); KeQuerySystemTime(&CurrentTime);
@ -383,10 +374,16 @@ TimerThreadMain(PVOID StartContext)
EnumEntry = EnumEntry->Flink) EnumEntry = EnumEntry->Flink)
{ {
MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry); MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
if (CurrentTime.QuadPart < MsgTimer->Timeout.QuadPart) if (CurrentTime.QuadPart >= MsgTimer->Timeout.QuadPart)
++ThreadsToDereferenceCount;
else
break; break;
} }
ThreadsToDereference = (PETHREAD *)ExAllocatePoolWithTag(
NonPagedPool, ThreadsToDereferenceCount * sizeof(PETHREAD), TAG_TIMERTD);
EnumEntry = TimerListHead.Flink; EnumEntry = TimerListHead.Flink;
while (EnumEntry != &TimerListHead) while (EnumEntry != &TimerListHead)
{ {
@ -402,7 +399,16 @@ TimerThreadMain(PVOID StartContext)
* FIXME: 1) Find a faster way of getting the thread message queue? (lookup by id is slow) * FIXME: 1) Find a faster way of getting the thread message queue? (lookup by id is slow)
*/ */
MsqPostMessage(MsgTimer->MessageQueue, &MsgTimer->Msg, FALSE); if (!NT_SUCCESS(PsLookupThreadByThreadId(MsgTimer->ThreadID, &Thread)))
{
ExFreePool(MsgTimer);
continue;
}
MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, &MsgTimer->Msg, FALSE);
ThreadsToDereference[ThreadsToDereferencePos] = Thread;
++ThreadsToDereferencePos;
//set up next periodic timeout //set up next periodic timeout
//FIXME: is this calculation really necesary (and correct)? -Gunnar //FIXME: is this calculation really necesary (and correct)? -Gunnar
@ -429,6 +435,11 @@ TimerThreadMain(PVOID StartContext)
} }
IntUnLockTimerList(); IntUnLockTimerList();
for (i = 0; i < ThreadsToDereferencePos; i++)
ObDereferenceObject(ThreadsToDereference[i]);
ExFreePool(ThreadsToDereference);
} }
} }