Create threads to manage timers instead of using the service thread.

This commit is contained in:
Alexandre Julliard 2002-03-23 18:48:53 +00:00
parent 8d1550d1c6
commit ac0e137998
3 changed files with 63 additions and 22 deletions

View File

@ -27,7 +27,6 @@
#include "dosexe.h"
#include "vga.h"
#include "ddraw.h"
#include "services.h"
#include "wine/debug.h"
WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
@ -46,6 +45,8 @@ static int vga_depth;
typedef HRESULT (WINAPI *DirectDrawCreateProc)(LPGUID,LPDIRECTDRAW *,LPUNKNOWN);
static DirectDrawCreateProc pDirectDrawCreate;
static void CALLBACK VGA_Poll( LPVOID arg, DWORD low, DWORD high );
/*
* For simplicity, I'm creating a second palette.
* 16 color accesses will use these pointers and insert
@ -168,19 +169,43 @@ static PALETTEENTRY vga_def64_palette[256]={
{0,0,0} /* The next 192 entries are all zeros */
};
static HANDLE VGA_timer;
static HANDLE VGA_timer_thread;
/* set the timer rate; called in the polling thread context */
static void CALLBACK set_timer_rate( ULONG_PTR arg )
{
LARGE_INTEGER when;
when.s.LowPart = when.s.HighPart = 0;
SetWaitableTimer( VGA_timer, &when, arg, VGA_Poll, 0, FALSE );
}
static DWORD CALLBACK VGA_TimerThread( void *dummy )
{
for (;;) WaitForMultipleObjectsEx( 0, NULL, FALSE, INFINITE, TRUE );
}
static void VGA_DeinstallTimer(void)
{
if (poll_timer) {
SERVICE_Delete( poll_timer );
poll_timer = 0;
if (VGA_timer_thread)
{
CancelWaitableTimer( VGA_timer );
CloseHandle( VGA_timer );
TerminateThread( VGA_timer_thread, 0 );
CloseHandle( VGA_timer_thread );
VGA_timer_thread = 0;
}
}
static void VGA_InstallTimer(unsigned Rate)
{
VGA_DeinstallTimer();
if (!poll_timer)
poll_timer = SERVICE_AddTimer( Rate, VGA_Poll, 0 );
if (!VGA_timer_thread)
{
VGA_timer = CreateWaitableTimerA( NULL, FALSE, NULL );
VGA_timer_thread = CreateThread( NULL, 0, VGA_TimerThread, NULL, 0, NULL );
}
QueueUserAPC( set_timer_rate, VGA_timer_thread, (ULONG_PTR)Rate );
}
HANDLE VGA_AlphaConsole(void)
@ -484,7 +509,7 @@ static void VGA_Poll_Graphics(void)
}
void CALLBACK VGA_Poll( ULONG_PTR arg )
static void CALLBACK VGA_Poll( LPVOID arg, DWORD low, DWORD high )
{
char *dat;
unsigned int Height,Width,Y,X;

View File

@ -42,7 +42,6 @@ void VGA_GetCursorPos(unsigned*X,unsigned*Y);
void VGA_WriteChars(unsigned X,unsigned Y,unsigned ch,int attr,int count);
/* control */
void CALLBACK VGA_Poll(ULONG_PTR arg);
void VGA_ioport_out(WORD port, BYTE val);
BYTE VGA_ioport_in(WORD port);
void VGA_Clean(void);

View File

@ -22,7 +22,6 @@
#include "wingdi.h"
#include "wine/winbase16.h"
#include "wine/winuser16.h"
#include "services.h"
#include "stackframe.h"
#include "wine/debug.h"
@ -41,16 +40,18 @@ typedef struct
static SYSTEM_TIMER SYS_Timers[NB_SYS_TIMERS];
static int SYS_NbTimers = 0;
static HANDLE SYS_Service = INVALID_HANDLE_VALUE;
static HANDLE SYS_timer;
static HANDLE SYS_thread;
static int SYS_timers_disabled;
/***********************************************************************
* SYSTEM_TimerTick
*/
static void CALLBACK SYSTEM_TimerTick( ULONG_PTR arg )
static void CALLBACK SYSTEM_TimerTick( LPVOID arg, DWORD low, DWORD high )
{
int i;
if (SYS_timers_disabled) return;
for (i = 0; i < NB_SYS_TIMERS; i++)
{
if (!SYS_Timers[i].callback) continue;
@ -62,6 +63,22 @@ static void CALLBACK SYSTEM_TimerTick( ULONG_PTR arg )
}
}
/***********************************************************************
* SYSTEM_TimerThread
*/
static DWORD CALLBACK SYSTEM_TimerThread( void *dummy )
{
LARGE_INTEGER when;
if (!(SYS_timer = CreateWaitableTimerA( NULL, FALSE, NULL ))) return 0;
when.s.LowPart = when.s.HighPart = 0;
SetWaitableTimer( SYS_timer, &when, (SYS_TIMER_RATE+500)/1000, SYSTEM_TimerTick, 0, FALSE );
for (;;) WaitForMultipleObjectsEx( 0, NULL, FALSE, INFINITE, TRUE );
}
/**********************************************************************
* SYSTEM_StartTicks
*
@ -69,8 +86,7 @@ static void CALLBACK SYSTEM_TimerTick( ULONG_PTR arg )
*/
static void SYSTEM_StartTicks(void)
{
if ( SYS_Service == INVALID_HANDLE_VALUE )
SYS_Service = SERVICE_AddTimer( (SYS_TIMER_RATE+500)/1000, SYSTEM_TimerTick, 0L );
if (!SYS_thread) SYS_thread = CreateThread( NULL, 0, SYSTEM_TimerThread, NULL, 0, NULL );
}
@ -81,10 +97,13 @@ static void SYSTEM_StartTicks(void)
*/
static void SYSTEM_StopTicks(void)
{
if ( SYS_Service != INVALID_HANDLE_VALUE )
if (SYS_thread)
{
SERVICE_Delete( SYS_Service );
SYS_Service = INVALID_HANDLE_VALUE;
CancelWaitableTimer( SYS_timer );
TerminateThread( SYS_thread, 0 );
CloseHandle( SYS_thread );
CloseHandle( SYS_timer );
SYS_thread = 0;
}
}
@ -186,8 +205,7 @@ WORD WINAPI SYSTEM_KillSystemTimer( WORD timer )
*/
void WINAPI EnableSystemTimers16(void)
{
if ( SYS_Service != INVALID_HANDLE_VALUE )
SERVICE_Enable( SYS_Service );
SYS_timers_disabled = 0;
}
@ -196,8 +214,7 @@ void WINAPI EnableSystemTimers16(void)
*/
void WINAPI DisableSystemTimers16(void)
{
if ( SYS_Service != INVALID_HANDLE_VALUE )
SERVICE_Disable( SYS_Service );
SYS_timers_disabled = 1;
}