- Attempt to fix race condition in timer handler. Reported by Jason Filby.

- Temporary disabled NtGdiExtTextOut experimental clipping implementation because it caused problems with buttons.

svn path=/trunk/; revision=7166
This commit is contained in:
Filip Navara 2003-12-21 20:37:42 +00:00
parent 99af0f4db6
commit dea090e06c
2 changed files with 50 additions and 7 deletions

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.17 2003/11/12 22:53:31 weiden Exp $ /* $Id: timer.c,v 1.18 2003/12/21 20:37:42 navaraf Exp $
* *
* COPYRIGHT: See COPYING in the top level directory * COPYRIGHT: See COPYING in the top level directory
* PROJECT: ReactOS kernel * PROJECT: ReactOS kernel
@ -391,6 +391,8 @@ TimerThreadMain(PVOID StartContext)
PLIST_ENTRY EnumEntry; PLIST_ENTRY EnumEntry;
PMSG_TIMER_ENTRY MsgTimer, MsgTimer2; PMSG_TIMER_ENTRY MsgTimer, MsgTimer2;
PETHREAD Thread; PETHREAD Thread;
PETHREAD *ThreadsToDereference;
ULONG ThreadsToDereferenceCount, ThreadsToDereferencePos;
for(;;) for(;;)
{ {
@ -409,11 +411,37 @@ TimerThreadMain(PVOID StartContext)
KeQuerySystemTime(&CurrentTime); KeQuerySystemTime(&CurrentTime);
ThreadsToDereferenceCount = ThreadsToDereferencePos = 0;
for (EnumEntry = TimerListHead.Flink;
EnumEntry != &TimerListHead;
EnumEntry = EnumEntry->Flink)
{
MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
if (CurrentTime.QuadPart >= MsgTimer->Timeout.QuadPart)
++ThreadsToDereferenceCount;
else
break;
}
for (EnumEntry = SysTimerListHead.Flink;
EnumEntry != &SysTimerListHead;
EnumEntry = EnumEntry->Flink)
{
MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
if (CurrentTime.QuadPart >= MsgTimer->Timeout.QuadPart)
++ThreadsToDereferenceCount;
else
break;
}
ThreadsToDereference = (PETHREAD *)ExAllocatePool(
NonPagedPool, ThreadsToDereferenceCount * sizeof(PETHREAD));
EnumEntry = TimerListHead.Flink; EnumEntry = TimerListHead.Flink;
while (EnumEntry != &TimerListHead) while (EnumEntry != &TimerListHead)
{ {
MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry); MsgTimer = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
EnumEntry = EnumEntry->Flink;
if (CurrentTime.QuadPart >= MsgTimer->Timeout.QuadPart) if (CurrentTime.QuadPart >= MsgTimer->Timeout.QuadPart)
{ {
@ -431,7 +459,8 @@ TimerThreadMain(PVOID StartContext)
MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, MsqCreateMessage(&MsgTimer->Msg)); MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, MsqCreateMessage(&MsgTimer->Msg));
ObDereferenceObject(Thread); ThreadsToDereference[ThreadsToDereferencePos] = Thread;
++ThreadsToDereferencePos;
//set up next periodic timeout //set up next periodic timeout
MsgTimer->Timeout.QuadPart += (MsgTimer->Period * 10000); MsgTimer->Timeout.QuadPart += (MsgTimer->Period * 10000);
@ -441,13 +470,14 @@ TimerThreadMain(PVOID StartContext)
{ {
break; break;
} }
EnumEntry = EnumEntry->Flink;
} }
EnumEntry = SysTimerListHead.Flink; EnumEntry = SysTimerListHead.Flink;
while (EnumEntry != &SysTimerListHead) while (EnumEntry != &SysTimerListHead)
{ {
MsgTimer2 = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry); MsgTimer2 = CONTAINING_RECORD(EnumEntry, MSG_TIMER_ENTRY, ListEntry);
EnumEntry = EnumEntry->Flink;
if (CurrentTime.QuadPart >= MsgTimer2->Timeout.QuadPart) if (CurrentTime.QuadPart >= MsgTimer2->Timeout.QuadPart)
{ {
@ -465,7 +495,8 @@ TimerThreadMain(PVOID StartContext)
MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, MsqCreateMessage(&MsgTimer2->Msg)); MsqPostMessage(((PW32THREAD)Thread->Win32Thread)->MessageQueue, MsqCreateMessage(&MsgTimer2->Msg));
ObDereferenceObject(Thread); ThreadsToDereference[ThreadsToDereferencePos] = Thread;
++ThreadsToDereferencePos;
//set up next periodic timeout //set up next periodic timeout
MsgTimer2->Timeout.QuadPart += (MsgTimer2->Period * 10000); MsgTimer2->Timeout.QuadPart += (MsgTimer2->Period * 10000);
@ -475,6 +506,8 @@ TimerThreadMain(PVOID StartContext)
{ {
break; break;
} }
EnumEntry = EnumEntry->Flink;
} }
//set up next timeout from first entry (if any) //set up next timeout from first entry (if any)
@ -509,6 +542,13 @@ TimerThreadMain(PVOID StartContext)
} }
ExReleaseFastMutex(&Mutex); ExReleaseFastMutex(&Mutex);
for (ThreadsToDereferencePos = 0;
ThreadsToDereferencePos < ThreadsToDereferenceCount;
ThreadsToDereferencePos++)
ObDereferenceObject(ThreadsToDereference[ThreadsToDereferencePos]);
ExFreePool(ThreadsToDereference);
} }
} }

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: text.c,v 1.62 2003/12/21 18:38:37 navaraf Exp $ */ /* $Id: text.c,v 1.63 2003/12/21 20:37:42 navaraf Exp $ */
#undef WIN32_LEAN_AND_MEAN #undef WIN32_LEAN_AND_MEAN
@ -471,8 +471,10 @@ BOOL STDCALL
NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions, NtGdiExtTextOut(HDC hDC, int XStart, int YStart, UINT fuOptions,
CONST RECT *lprc, LPCWSTR String, UINT Count, CONST INT *lpDx) CONST RECT *lprc, LPCWSTR String, UINT Count, CONST INT *lpDx)
{ {
#if 1
/* FIXME: Implement */ /* FIXME: Implement */
// return NtGdiTextOut(hdc, X, Y, lpString, cbCount); return NtGdiTextOut(hDC, XStart, YStart, String, Count);
#else
// Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate) // Fixme: Call EngTextOut, which does the real work (calling DrvTextOut where appropriate)
DC *dc; DC *dc;
@ -737,6 +739,7 @@ fail:
} }
DC_UnlockDc( hDC ); DC_UnlockDc( hDC );
return FALSE; return FALSE;
#endif
} }
BOOL BOOL