mirror of
git://source.winehq.org/git/wine.git
synced 2024-11-02 13:27:35 +00:00
Made the timer code thread safe.
This commit is contained in:
parent
f91e6d037e
commit
35ffc5d8c0
3 changed files with 98 additions and 11 deletions
|
@ -18,6 +18,7 @@ extern BOOL MSG_InternalGetMessage( MSG *msg, HWND hwnd,
|
||||||
WORD flags, BOOL sendIdle );
|
WORD flags, BOOL sendIdle );
|
||||||
|
|
||||||
/* timer.c */
|
/* timer.c */
|
||||||
|
extern BOOL TIMER_Init( void );
|
||||||
extern void TIMER_RemoveWindowTimers( HWND hwnd );
|
extern void TIMER_RemoveWindowTimers( HWND hwnd );
|
||||||
extern void TIMER_RemoveQueueTimers( HQUEUE16 hqueue );
|
extern void TIMER_RemoveQueueTimers( HQUEUE16 hqueue );
|
||||||
extern void TIMER_SwitchQueue( HQUEUE16 hOldQueue, HQUEUE16 hNewQueue );
|
extern void TIMER_SwitchQueue( HQUEUE16 hOldQueue, HQUEUE16 hNewQueue );
|
||||||
|
|
|
@ -210,6 +210,9 @@ BOOL WINAPI MAIN_UserInit(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserve
|
||||||
/* Create the DCEs */
|
/* Create the DCEs */
|
||||||
DCE_Init();
|
DCE_Init();
|
||||||
|
|
||||||
|
/* Initialize timers */
|
||||||
|
if (!TIMER_Init()) return FALSE;
|
||||||
|
|
||||||
/* Initialize window procedures */
|
/* Initialize window procedures */
|
||||||
if (!WINPROC_Init()) return FALSE;
|
if (!WINPROC_Init()) return FALSE;
|
||||||
|
|
||||||
|
|
105
windows/timer.c
105
windows/timer.c
|
@ -30,11 +30,27 @@ static TIMER TimersArray[NB_TIMERS];
|
||||||
|
|
||||||
static TIMER * pNextTimer = NULL; /* Next timer to expire */
|
static TIMER * pNextTimer = NULL; /* Next timer to expire */
|
||||||
|
|
||||||
|
static CRITICAL_SECTION csTimer;
|
||||||
|
|
||||||
/* Duration from 'time' until expiration of the timer */
|
/* Duration from 'time' until expiration of the timer */
|
||||||
#define EXPIRE_TIME(pTimer,time) \
|
#define EXPIRE_TIME(pTimer,time) \
|
||||||
(((pTimer)->expires <= (time)) ? 0 : (pTimer)->expires - (time))
|
(((pTimer)->expires <= (time)) ? 0 : (pTimer)->expires - (time))
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* TIMER_Init
|
||||||
|
*
|
||||||
|
* Initialize critical section for the timer.
|
||||||
|
*/
|
||||||
|
BOOL TIMER_Init( void )
|
||||||
|
{
|
||||||
|
InitializeCriticalSection( &csTimer );
|
||||||
|
MakeCriticalSectionGlobal( &csTimer );
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* TIMER_InsertTimer
|
* TIMER_InsertTimer
|
||||||
*
|
*
|
||||||
|
@ -42,6 +58,8 @@ static TIMER * pNextTimer = NULL; /* Next timer to expire */
|
||||||
*/
|
*/
|
||||||
static void TIMER_InsertTimer( TIMER * pTimer )
|
static void TIMER_InsertTimer( TIMER * pTimer )
|
||||||
{
|
{
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
if (!pNextTimer || (pTimer->expires < pNextTimer->expires))
|
if (!pNextTimer || (pTimer->expires < pNextTimer->expires))
|
||||||
{
|
{
|
||||||
pTimer->next = pNextTimer;
|
pTimer->next = pNextTimer;
|
||||||
|
@ -55,6 +73,8 @@ static void TIMER_InsertTimer( TIMER * pTimer )
|
||||||
pTimer->next = ptr->next;
|
pTimer->next = ptr->next;
|
||||||
ptr->next = pTimer;
|
ptr->next = pTimer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -67,9 +87,14 @@ static void TIMER_RemoveTimer( TIMER * pTimer )
|
||||||
{
|
{
|
||||||
TIMER **ppTimer = &pNextTimer;
|
TIMER **ppTimer = &pNextTimer;
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
while (*ppTimer && (*ppTimer != pTimer)) ppTimer = &(*ppTimer)->next;
|
while (*ppTimer && (*ppTimer != pTimer)) ppTimer = &(*ppTimer)->next;
|
||||||
if (*ppTimer) *ppTimer = pTimer->next;
|
if (*ppTimer) *ppTimer = pTimer->next;
|
||||||
pTimer->next = NULL;
|
pTimer->next = NULL;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
|
||||||
if (!pTimer->expires) QUEUE_DecTimerCount( pTimer->hq );
|
if (!pTimer->expires) QUEUE_DecTimerCount( pTimer->hq );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,13 +120,18 @@ static void TIMER_ClearTimer( TIMER * pTimer )
|
||||||
*/
|
*/
|
||||||
void TIMER_SwitchQueue( HQUEUE16 old, HQUEUE16 new )
|
void TIMER_SwitchQueue( HQUEUE16 old, HQUEUE16 new )
|
||||||
{
|
{
|
||||||
TIMER * pT = pNextTimer;
|
TIMER * pT;
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
|
pT = pNextTimer;
|
||||||
while (pT)
|
while (pT)
|
||||||
{
|
{
|
||||||
if (pT->hq == old) pT->hq = new;
|
if (pT->hq == old) pT->hq = new;
|
||||||
pT = pT->next;
|
pT = pT->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -115,9 +145,13 @@ void TIMER_RemoveWindowTimers( HWND hwnd )
|
||||||
int i;
|
int i;
|
||||||
TIMER *pTimer;
|
TIMER *pTimer;
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
|
for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
|
||||||
if ((pTimer->hwnd == hwnd) && pTimer->timeout)
|
if ((pTimer->hwnd == hwnd) && pTimer->timeout)
|
||||||
TIMER_ClearTimer( pTimer );
|
TIMER_ClearTimer( pTimer );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -131,9 +165,13 @@ void TIMER_RemoveQueueTimers( HQUEUE16 hqueue )
|
||||||
int i;
|
int i;
|
||||||
TIMER *pTimer;
|
TIMER *pTimer;
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
|
for (i = NB_TIMERS, pTimer = TimersArray; i > 0; i--, pTimer++)
|
||||||
if ((pTimer->hq == hqueue) && pTimer->timeout)
|
if ((pTimer->hq == hqueue) && pTimer->timeout)
|
||||||
TIMER_ClearTimer( pTimer );
|
TIMER_ClearTimer( pTimer );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -157,7 +195,13 @@ static void TIMER_RestartTimer( TIMER * pTimer, DWORD curTime )
|
||||||
*/
|
*/
|
||||||
LONG TIMER_GetNextExpiration(void)
|
LONG TIMER_GetNextExpiration(void)
|
||||||
{
|
{
|
||||||
return pNextTimer ? EXPIRE_TIME( pNextTimer, GetTickCount() ) : -1;
|
LONG retValue;
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
retValue = pNextTimer ? EXPIRE_TIME( pNextTimer, GetTickCount() ) : -1;
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
|
||||||
|
return retValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -168,9 +212,13 @@ LONG TIMER_GetNextExpiration(void)
|
||||||
*/
|
*/
|
||||||
void TIMER_ExpireTimers(void)
|
void TIMER_ExpireTimers(void)
|
||||||
{
|
{
|
||||||
TIMER *pTimer = pNextTimer;
|
TIMER *pTimer;
|
||||||
DWORD curTime = GetTickCount();
|
DWORD curTime = GetTickCount();
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
|
pTimer = pNextTimer;
|
||||||
|
|
||||||
while (pTimer && !pTimer->expires) /* Skip already expired timers */
|
while (pTimer && !pTimer->expires) /* Skip already expired timers */
|
||||||
pTimer = pTimer->next;
|
pTimer = pTimer->next;
|
||||||
while (pTimer && (pTimer->expires <= curTime))
|
while (pTimer && (pTimer->expires <= curTime))
|
||||||
|
@ -179,6 +227,8 @@ void TIMER_ExpireTimers(void)
|
||||||
QUEUE_IncTimerCount( pTimer->hq );
|
QUEUE_IncTimerCount( pTimer->hq );
|
||||||
pTimer = pTimer->next;
|
pTimer = pTimer->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -190,15 +240,24 @@ void TIMER_ExpireTimers(void)
|
||||||
BOOL TIMER_GetTimerMsg( MSG *msg, HWND hwnd,
|
BOOL TIMER_GetTimerMsg( MSG *msg, HWND hwnd,
|
||||||
HQUEUE16 hQueue, BOOL remove )
|
HQUEUE16 hQueue, BOOL remove )
|
||||||
{
|
{
|
||||||
TIMER *pTimer = pNextTimer;
|
TIMER *pTimer;
|
||||||
DWORD curTime = GetTickCount();
|
DWORD curTime = GetTickCount();
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
|
pTimer = pNextTimer;
|
||||||
|
|
||||||
if (hwnd) /* Find first timer for this window */
|
if (hwnd) /* Find first timer for this window */
|
||||||
while (pTimer && (pTimer->hwnd != hwnd)) pTimer = pTimer->next;
|
while (pTimer && (pTimer->hwnd != hwnd)) pTimer = pTimer->next;
|
||||||
else /* Find first timer for this queue */
|
else /* Find first timer for this queue */
|
||||||
while (pTimer && (pTimer->hq != hQueue)) pTimer = pTimer->next;
|
while (pTimer && (pTimer->hq != hQueue)) pTimer = pTimer->next;
|
||||||
|
|
||||||
if (!pTimer || (pTimer->expires > curTime)) return FALSE; /* No timer */
|
if (!pTimer || (pTimer->expires > curTime))
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
return FALSE; /* No timer */
|
||||||
|
}
|
||||||
|
|
||||||
if (remove) TIMER_RestartTimer( pTimer, curTime ); /* Restart it */
|
if (remove) TIMER_RestartTimer( pTimer, curTime ); /* Restart it */
|
||||||
|
|
||||||
TRACE(timer, "Timer expired: %04x, %04x, %04x, %08lx\n",
|
TRACE(timer, "Timer expired: %04x, %04x, %04x, %08lx\n",
|
||||||
|
@ -210,6 +269,9 @@ BOOL TIMER_GetTimerMsg( MSG *msg, HWND hwnd,
|
||||||
msg->wParam = pTimer->id;
|
msg->wParam = pTimer->id;
|
||||||
msg->lParam = (LONG)pTimer->proc;
|
msg->lParam = (LONG)pTimer->proc;
|
||||||
msg->time = curTime;
|
msg->time = curTime;
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -225,6 +287,8 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
|
||||||
|
|
||||||
if (!timeout) return 0;
|
if (!timeout) return 0;
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
/* Check if there's already a timer with the same hwnd and id */
|
/* Check if there's already a timer with the same hwnd and id */
|
||||||
|
|
||||||
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
|
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
|
||||||
|
@ -240,6 +304,7 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
|
||||||
type, WIN_PROC_TIMER );
|
type, WIN_PROC_TIMER );
|
||||||
pTimer->expires = GetTickCount() + timeout;
|
pTimer->expires = GetTickCount() + timeout;
|
||||||
TIMER_InsertTimer( pTimer );
|
TIMER_InsertTimer( pTimer );
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -248,8 +313,13 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
|
||||||
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
|
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
|
||||||
if (!pTimer->timeout) break;
|
if (!pTimer->timeout) break;
|
||||||
|
|
||||||
if (i >= NB_TIMERS) return 0;
|
if ( (i >= NB_TIMERS) ||
|
||||||
if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return 0;
|
(!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) )
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (!hwnd) id = i + 1;
|
if (!hwnd) id = i + 1;
|
||||||
|
|
||||||
/* Add the timer */
|
/* Add the timer */
|
||||||
|
@ -267,6 +337,9 @@ static UINT TIMER_SetTimer( HWND hwnd, UINT id, UINT timeout,
|
||||||
pTimer, pTimer->hwnd, pTimer->msg, pTimer->id,
|
pTimer, pTimer->hwnd, pTimer->msg, pTimer->id,
|
||||||
(DWORD)pTimer->proc );
|
(DWORD)pTimer->proc );
|
||||||
TIMER_InsertTimer( pTimer );
|
TIMER_InsertTimer( pTimer );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
|
||||||
if (!id) return TRUE;
|
if (!id) return TRUE;
|
||||||
else return id;
|
else return id;
|
||||||
}
|
}
|
||||||
|
@ -280,19 +353,29 @@ static BOOL TIMER_KillTimer( HWND hwnd, UINT id, BOOL sys )
|
||||||
int i;
|
int i;
|
||||||
TIMER * pTimer;
|
TIMER * pTimer;
|
||||||
|
|
||||||
|
EnterCriticalSection( &csTimer );
|
||||||
|
|
||||||
/* Find the timer */
|
/* Find the timer */
|
||||||
|
|
||||||
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
|
for (i = 0, pTimer = TimersArray; i < NB_TIMERS; i++, pTimer++)
|
||||||
if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
|
if ((pTimer->hwnd == hwnd) && (pTimer->id == id) &&
|
||||||
(pTimer->timeout != 0)) break;
|
(pTimer->timeout != 0)) break;
|
||||||
if (i >= NB_TIMERS) return FALSE;
|
|
||||||
if (!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) return FALSE;
|
if ( (i >= NB_TIMERS) ||
|
||||||
if (!sys && (pTimer->msg != WM_TIMER)) return FALSE;
|
(!sys && (i >= NB_TIMERS-NB_RESERVED_TIMERS)) ||
|
||||||
else if (sys && (pTimer->msg != WM_SYSTIMER)) return FALSE;
|
(!sys && (pTimer->msg != WM_TIMER)) ||
|
||||||
|
(sys && (pTimer->msg != WM_SYSTIMER)) )
|
||||||
|
{
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Delete the timer */
|
/* Delete the timer */
|
||||||
|
|
||||||
TIMER_ClearTimer( pTimer );
|
TIMER_ClearTimer( pTimer );
|
||||||
|
|
||||||
|
LeaveCriticalSection( &csTimer );
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue