mirror of
https://github.com/reactos/reactos.git
synced 2025-08-06 06:02:56 +00:00
Reverted my changes to timers
svn path=/trunk/; revision=10400
This commit is contained in:
parent
f34c1d586a
commit
0004f90a07
5 changed files with 86 additions and 84 deletions
|
@ -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
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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 */
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue