Implemented waitable timers.
This commit is contained in:
parent
1a61a03be4
commit
ad47a30f5e
|
@ -18,9 +18,6 @@
|
|||
|
||||
DEFAULT_DEBUG_CHANNEL(ntdll)
|
||||
|
||||
/* move to winbase.h */
|
||||
typedef VOID (CALLBACK *PTIMERAPCROUTINE)(LPVOID lpArgToCompletionRoutine,DWORD dwTimerLowValue,DWORD dwTimerHighValue);
|
||||
|
||||
/*
|
||||
* Timer object
|
||||
*/
|
||||
|
|
|
@ -967,6 +967,43 @@ struct set_registry_levels_request
|
|||
};
|
||||
|
||||
|
||||
/* Create a waitable timer */
|
||||
struct create_timer_request
|
||||
{
|
||||
IN int inherit; /* inherit flag */
|
||||
IN int manual; /* manual reset */
|
||||
OUT int handle; /* handle to the timer */
|
||||
IN WCHAR name[1]; /* timer name */
|
||||
};
|
||||
|
||||
|
||||
/* Open a waitable timer */
|
||||
struct open_timer_request
|
||||
{
|
||||
IN unsigned int access; /* wanted access rights */
|
||||
IN int inherit; /* inherit flag */
|
||||
OUT int handle; /* handle to the timer */
|
||||
IN WCHAR name[1]; /* timer name */
|
||||
};
|
||||
|
||||
/* Set a waitable timer */
|
||||
struct set_timer_request
|
||||
{
|
||||
IN int handle; /* handle to the timer */
|
||||
IN int sec; /* next expiration absolute time */
|
||||
IN int usec; /* next expiration absolute time */
|
||||
IN int period; /* timer period in ms */
|
||||
IN void* callback; /* callback function */
|
||||
IN void* arg; /* callback argument */
|
||||
};
|
||||
|
||||
/* Cancel a waitable timer */
|
||||
struct cancel_timer_request
|
||||
{
|
||||
IN int handle; /* handle to the timer */
|
||||
};
|
||||
|
||||
|
||||
/* Everything below this line is generated automatically by tools/make_requests */
|
||||
/* ### make_requests begin ### */
|
||||
|
||||
|
@ -1058,6 +1095,10 @@ enum request
|
|||
REQ_LOAD_REGISTRY,
|
||||
REQ_SAVE_REGISTRY,
|
||||
REQ_SET_REGISTRY_LEVELS,
|
||||
REQ_CREATE_TIMER,
|
||||
REQ_OPEN_TIMER,
|
||||
REQ_SET_TIMER,
|
||||
REQ_CANCEL_TIMER,
|
||||
REQ_NB_REQUESTS
|
||||
};
|
||||
|
||||
|
|
|
@ -1086,7 +1086,8 @@ typedef struct tagCOMMTIMEOUTS {
|
|||
|
||||
#include "poppack.h"
|
||||
|
||||
typedef VOID (CALLBACK *PAPCFUNC)(ULONG_PTR);
|
||||
typedef void (CALLBACK *PAPCFUNC)(ULONG_PTR);
|
||||
typedef void (CALLBACK *PTIMERAPCROUTINE)(LPVOID,DWORD,DWORD);
|
||||
|
||||
BOOL WINAPI ClearCommError(INT,LPDWORD,LPCOMSTAT);
|
||||
BOOL WINAPI BuildCommDCBA(LPCSTR,LPDCB);
|
||||
|
@ -1154,7 +1155,8 @@ BOOL WINAPI AreFileApisANSI(void);
|
|||
BOOL WINAPI BackupEventLogA(HANDLE,LPCSTR);
|
||||
BOOL WINAPI BackupEventLogW(HANDLE,LPCWSTR);
|
||||
#define BackupEventLog WINELIB_NAME_AW(BackupEventLog)
|
||||
BOOL WINAPI Beep(DWORD,DWORD);
|
||||
BOOL WINAPI Beep(DWORD,DWORD);
|
||||
BOOL WINAPI CancelWaitableTimer(HANDLE);
|
||||
BOOL WINAPI ClearEventLogA(HANDLE,LPCSTR);
|
||||
BOOL WINAPI ClearEventLogW(HANDLE,LPCWSTR);
|
||||
#define ClearEventLog WINELIB_NAME_AW(ClearEventLog)
|
||||
|
@ -1198,6 +1200,9 @@ HANDLE WINAPI CreateSemaphoreA(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCSTR);
|
|||
HANDLE WINAPI CreateSemaphoreW(LPSECURITY_ATTRIBUTES,LONG,LONG,LPCWSTR);
|
||||
#define CreateSemaphore WINELIB_NAME_AW(CreateSemaphore)
|
||||
HANDLE WINAPI CreateThread(LPSECURITY_ATTRIBUTES,DWORD,LPTHREAD_START_ROUTINE,LPVOID,DWORD,LPDWORD);
|
||||
HANDLE WINAPI CreateWaitableTimerA(LPSECURITY_ATTRIBUTES,BOOL,LPCSTR);
|
||||
HANDLE WINAPI CreateWaitableTimerW(LPSECURITY_ATTRIBUTES,BOOL,LPCWSTR);
|
||||
#define CreateWaitableTimer WINELIB_NAME_AW(CreateWaitableTimer)
|
||||
BOOL WINAPI DebugActiveProcess(DWORD);
|
||||
void WINAPI DebugBreak(void);
|
||||
BOOL WINAPI DeregisterEventSource(HANDLE);
|
||||
|
@ -1335,10 +1340,11 @@ BOOL WINAPI GetStringTypeExA(LCID,DWORD,LPCSTR,INT,LPWORD);
|
|||
BOOL WINAPI GetStringTypeExW(LCID,DWORD,LPCWSTR,INT,LPWORD);
|
||||
#define GetStringTypeEx WINELIB_NAME_AW(GetStringTypeEx)
|
||||
VOID WINAPI GetSystemInfo(LPSYSTEM_INFO);
|
||||
BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS);
|
||||
BOOL WINAPI GetSystemPowerStatus(LPSYSTEM_POWER_STATUS);
|
||||
VOID WINAPI GetSystemTime(LPSYSTEMTIME);
|
||||
INT WINAPI GetTimeFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT);
|
||||
INT WINAPI GetTimeFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT);
|
||||
VOID WINAPI GetSystemTimeAsFileTime(LPFILETIME);
|
||||
INT WINAPI GetTimeFormatA(LCID,DWORD,LPSYSTEMTIME,LPCSTR,LPSTR,INT);
|
||||
INT WINAPI GetTimeFormatW(LCID,DWORD,LPSYSTEMTIME,LPCWSTR,LPWSTR,INT);
|
||||
#define GetTimeFormat WINELIB_NAME_AW(GetTimeFormat)
|
||||
BOOL WINAPI GetThreadContext(HANDLE,CONTEXT *);
|
||||
LCID WINAPI GetThreadLocale(void);
|
||||
|
@ -1413,8 +1419,11 @@ HANDLE WINAPI OpenSemaphoreA(DWORD,BOOL,LPCSTR);
|
|||
HANDLE WINAPI OpenSemaphoreW(DWORD,BOOL,LPCWSTR);
|
||||
#define OpenSemaphore WINELIB_NAME_AW(OpenSemaphore)
|
||||
BOOL WINAPI OpenThreadToken(HANDLE,DWORD,BOOL,PHANDLE);
|
||||
BOOL WINAPI PulseEvent(HANDLE);
|
||||
BOOL WINAPI PurgeComm(HANDLE,DWORD);
|
||||
HANDLE WINAPI OpenWaitableTimerA(DWORD,BOOL,LPCSTR);
|
||||
HANDLE WINAPI OpenWaitableTimerW(DWORD,BOOL,LPCWSTR);
|
||||
#define OpenWaitableTimer WINELIB_NAME_AW(OpenWaitableTimer)
|
||||
BOOL WINAPI PulseEvent(HANDLE);
|
||||
BOOL WINAPI PurgeComm(HANDLE,DWORD);
|
||||
DWORD WINAPI QueryDosDeviceA(LPCSTR,LPSTR,DWORD);
|
||||
DWORD WINAPI QueryDosDeviceW(LPCWSTR,LPWSTR,DWORD);
|
||||
#define QueryDosDevice WINELIB_NAME_AW(QueryDosDevice)
|
||||
|
@ -1484,9 +1493,10 @@ BOOL WINAPI SetSystemPowerState(BOOL,BOOL);
|
|||
BOOL WINAPI SetSystemTime(const SYSTEMTIME*);
|
||||
DWORD WINAPI SetThreadAffinityMask(HANDLE,DWORD);
|
||||
BOOL WINAPI SetThreadContext(HANDLE,const CONTEXT *);
|
||||
BOOL WINAPI SetThreadLocale(LCID);
|
||||
BOOL WINAPI SetThreadPriority(HANDLE,INT);
|
||||
BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
|
||||
BOOL WINAPI SetThreadLocale(LCID);
|
||||
BOOL WINAPI SetThreadPriority(HANDLE,INT);
|
||||
BOOL WINAPI SetTimeZoneInformation(const LPTIME_ZONE_INFORMATION);
|
||||
BOOL WINAPI SetWaitableTimer(HANDLE,const LARGE_INTEGER*,LONG,PTIMERAPCROUTINE,LPVOID,BOOL);
|
||||
VOID WINAPI Sleep(DWORD);
|
||||
DWORD WINAPI SleepEx(DWORD,BOOL);
|
||||
DWORD WINAPI SuspendThread(HANDLE);
|
||||
|
|
|
@ -873,12 +873,12 @@ import ntdll.dll
|
|||
|
||||
# NT 4.0 additions
|
||||
856 stub CancelIo
|
||||
857 stub CancelWaitableTimer
|
||||
857 stdcall CancelWaitableTimer(long) CancelWaitableTimer
|
||||
858 stdcall CopyFileExA (str str ptr ptr ptr long) CopyFileExA
|
||||
859 stdcall CopyFileExW (wstr wstr ptr ptr ptr long) CopyFileExW
|
||||
860 stub CreateFiber
|
||||
861 stub CreateWaitableTimerA
|
||||
862 stub CreateWaitableTimerW
|
||||
861 stdcall CreateWaitableTimerA(ptr long str) CreateWaitableTimerA
|
||||
862 stdcall CreateWaitableTimerW(ptr long wstr) CreateWaitableTimerW
|
||||
863 stub DeleteFiber
|
||||
864 stub DuplicateConsoleHandle
|
||||
865 stub FindFirstFileExA
|
||||
|
@ -896,8 +896,8 @@ import ntdll.dll
|
|||
878 stdcall InterlockedCompareExchange (ptr long long) InterlockedCompareExchange
|
||||
879 stdcall InterlockedExchangeAdd (ptr long ) InterlockedExchangeAdd
|
||||
880 stdcall IsProcessorFeaturePresent(long) IsProcessorFeaturePresent
|
||||
881 stub OpenWaitableTimerA
|
||||
882 stub OpenWaitableTimerW
|
||||
881 stdcall OpenWaitableTimerA(long long str) OpenWaitableTimerA
|
||||
882 stdcall OpenWaitableTimerW(long long wstr) OpenWaitableTimerW
|
||||
883 stub ReadConsoleInputExA
|
||||
884 stub ReadConsoleInputExW
|
||||
885 stub ReadDirectoryChangesW
|
||||
|
@ -909,7 +909,7 @@ import ntdll.dll
|
|||
891 stdcall SetProcessPriorityBoost(long long) SetProcessPriorityBoost
|
||||
892 stub SetThreadIdealProcessor
|
||||
893 stub SetThreadPriorityBoost
|
||||
894 stub SetWaitableTimer
|
||||
894 stdcall SetWaitableTimer(long ptr long ptr ptr long) SetWaitableTimer
|
||||
895 stub SignalObjectAndWait
|
||||
896 stub SwitchToFiber
|
||||
897 stub SwitchToThread
|
||||
|
|
|
@ -19,7 +19,8 @@ C_SRCS = \
|
|||
synchro.c \
|
||||
sysdeps.c \
|
||||
syslevel.c \
|
||||
thread.c
|
||||
thread.c \
|
||||
timer.c
|
||||
|
||||
all: $(MODULE).o
|
||||
|
||||
|
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Win32 waitable timers
|
||||
*
|
||||
* Copyright 1999 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
#include "winerror.h"
|
||||
#include "file.h" /* for FILETIME routines */
|
||||
#include "server.h"
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateWaitableTimerA (KERNEL32.861)
|
||||
*/
|
||||
HANDLE WINAPI CreateWaitableTimerA( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCSTR name )
|
||||
{
|
||||
struct create_timer_request *req = get_req_buffer();
|
||||
|
||||
req->manual = manual;
|
||||
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
|
||||
server_strcpyAtoW( req->name, name );
|
||||
SetLastError(0);
|
||||
server_call( REQ_CREATE_TIMER );
|
||||
if (req->handle == -1) return 0;
|
||||
return req->handle;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CreateWaitableTimerW (KERNEL32.862)
|
||||
*/
|
||||
HANDLE WINAPI CreateWaitableTimerW( SECURITY_ATTRIBUTES *sa, BOOL manual, LPCWSTR name )
|
||||
{
|
||||
struct create_timer_request *req = get_req_buffer();
|
||||
|
||||
req->manual = manual;
|
||||
req->inherit = (sa && (sa->nLength>=sizeof(*sa)) && sa->bInheritHandle);
|
||||
server_strcpyW( req->name, name );
|
||||
SetLastError(0);
|
||||
server_call( REQ_CREATE_TIMER );
|
||||
if (req->handle == -1) return 0;
|
||||
return req->handle;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* OpenWaitableTimerA (KERNEL32.881)
|
||||
*/
|
||||
HANDLE WINAPI OpenWaitableTimerA( DWORD access, BOOL inherit, LPCSTR name )
|
||||
{
|
||||
struct open_timer_request *req = get_req_buffer();
|
||||
|
||||
req->access = access;
|
||||
req->inherit = inherit;
|
||||
server_strcpyAtoW( req->name, name );
|
||||
server_call( REQ_OPEN_TIMER );
|
||||
if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
|
||||
return req->handle;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* OpenWaitableTimerW (KERNEL32.882)
|
||||
*/
|
||||
HANDLE WINAPI OpenWaitableTimerW( DWORD access, BOOL inherit, LPCWSTR name )
|
||||
{
|
||||
struct open_timer_request *req = get_req_buffer();
|
||||
|
||||
req->access = access;
|
||||
req->inherit = inherit;
|
||||
server_strcpyW( req->name, name );
|
||||
server_call( REQ_OPEN_TIMER );
|
||||
if (req->handle == -1) return 0; /* must return 0 on failure, not -1 */
|
||||
return req->handle;
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* SetWaitableTimer (KERNEL32.894)
|
||||
*/
|
||||
BOOL WINAPI SetWaitableTimer( HANDLE handle, const LARGE_INTEGER *when, LONG period,
|
||||
PTIMERAPCROUTINE callback, LPVOID arg, BOOL resume )
|
||||
{
|
||||
FILETIME ft;
|
||||
DWORD remainder;
|
||||
struct set_timer_request *req = get_req_buffer();
|
||||
|
||||
if (when->s.HighPart < 0) /* relative time */
|
||||
{
|
||||
DWORD low = ft.dwLowDateTime;
|
||||
GetSystemTimeAsFileTime( &ft );
|
||||
ft.dwLowDateTime -= when->s.LowPart;
|
||||
ft.dwHighDateTime -= when->s.HighPart;
|
||||
if (low < ft.dwLowDateTime) ft.dwHighDateTime--; /* overflow */
|
||||
}
|
||||
else /* absolute time */
|
||||
{
|
||||
ft.dwLowDateTime = when->s.LowPart;
|
||||
ft.dwHighDateTime = when->s.HighPart;
|
||||
}
|
||||
req->handle = handle;
|
||||
req->sec = DOSFS_FileTimeToUnixTime( &ft, &remainder );
|
||||
req->usec = remainder / 10; /* convert from 100-ns to us units */
|
||||
req->period = period;
|
||||
req->callback = callback;
|
||||
req->arg = arg;
|
||||
if (resume) SetLastError( ERROR_NOT_SUPPORTED ); /* set error but can still succeed */
|
||||
return !server_call( REQ_SET_TIMER );
|
||||
}
|
||||
|
||||
|
||||
/***********************************************************************
|
||||
* CancelWaitableTimer (KERNEL32.857)
|
||||
*/
|
||||
BOOL WINAPI CancelWaitableTimer( HANDLE handle )
|
||||
{
|
||||
struct cancel_timer_request *req = get_req_buffer();
|
||||
req->handle = handle;
|
||||
return !server_call( REQ_CANCEL_TIMER );
|
||||
}
|
|
@ -27,6 +27,7 @@ C_SRCS = \
|
|||
sock.c \
|
||||
socket.c \
|
||||
thread.c \
|
||||
timer.c \
|
||||
trace.c \
|
||||
unicode.c
|
||||
|
||||
|
|
|
@ -155,6 +155,10 @@ DECL_HANDLER(delete_key_value);
|
|||
DECL_HANDLER(load_registry);
|
||||
DECL_HANDLER(save_registry);
|
||||
DECL_HANDLER(set_registry_levels);
|
||||
DECL_HANDLER(create_timer);
|
||||
DECL_HANDLER(open_timer);
|
||||
DECL_HANDLER(set_timer);
|
||||
DECL_HANDLER(cancel_timer);
|
||||
|
||||
#ifdef WANT_REQUEST_HANDLERS
|
||||
|
||||
|
@ -248,6 +252,10 @@ static const struct handler {
|
|||
{ (void(*)())req_load_registry, sizeof(struct load_registry_request) },
|
||||
{ (void(*)())req_save_registry, sizeof(struct save_registry_request) },
|
||||
{ (void(*)())req_set_registry_levels, sizeof(struct set_registry_levels_request) },
|
||||
{ (void(*)())req_create_timer, sizeof(struct create_timer_request) },
|
||||
{ (void(*)())req_open_timer, sizeof(struct open_timer_request) },
|
||||
{ (void(*)())req_set_timer, sizeof(struct set_timer_request) },
|
||||
{ (void(*)())req_cancel_timer, sizeof(struct cancel_timer_request) },
|
||||
};
|
||||
#endif /* WANT_REQUEST_HANDLERS */
|
||||
|
||||
|
|
|
@ -0,0 +1,200 @@
|
|||
/*
|
||||
* Waitable timers management
|
||||
*
|
||||
* Copyright (C) 1999 Alexandre Julliard
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include "winerror.h"
|
||||
|
||||
#include "handle.h"
|
||||
#include "request.h"
|
||||
|
||||
/* FIXME: check values and move to standard header */
|
||||
#define TIMER_MODIFY_STATE 0x0001
|
||||
#define TIMER_QUERY_STATE 0x0002
|
||||
#define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
|
||||
|
||||
struct timer
|
||||
{
|
||||
struct object obj; /* object header */
|
||||
int manual; /* manual reset */
|
||||
int signaled; /* current signaled state */
|
||||
int period; /* timer period in ms */
|
||||
struct timeval when; /* next expiration */
|
||||
struct timeout_user *timeout; /* timeout user */
|
||||
void *callback; /* callback APC function */
|
||||
void *arg; /* callback argument */
|
||||
};
|
||||
|
||||
static void timer_dump( struct object *obj, int verbose );
|
||||
static int timer_signaled( struct object *obj, struct thread *thread );
|
||||
static int timer_satisfied( struct object *obj, struct thread *thread );
|
||||
static void timer_destroy( struct object *obj );
|
||||
|
||||
static const struct object_ops timer_ops =
|
||||
{
|
||||
sizeof(struct timer),
|
||||
timer_dump,
|
||||
add_queue,
|
||||
remove_queue,
|
||||
timer_signaled,
|
||||
timer_satisfied,
|
||||
no_read_fd,
|
||||
no_write_fd,
|
||||
no_flush,
|
||||
no_get_file_info,
|
||||
timer_destroy
|
||||
};
|
||||
|
||||
|
||||
/* create a timer object */
|
||||
static struct timer *create_timer( const WCHAR *name, size_t len, int manual )
|
||||
{
|
||||
struct timer *timer;
|
||||
|
||||
if ((timer = create_named_object( &timer_ops, name, len )))
|
||||
{
|
||||
if (get_error() != ERROR_ALREADY_EXISTS)
|
||||
{
|
||||
/* initialize it if it didn't already exist */
|
||||
timer->manual = manual;
|
||||
timer->signaled = 0;
|
||||
timer->when.tv_sec = 0;
|
||||
timer->when.tv_usec = 0;
|
||||
timer->period = 0;
|
||||
timer->timeout = NULL;
|
||||
}
|
||||
}
|
||||
return timer;
|
||||
}
|
||||
|
||||
/* callback on timer expiration */
|
||||
static void timer_callback( void *private )
|
||||
{
|
||||
struct timer *timer = (struct timer *)private;
|
||||
|
||||
if (timer->period) /* schedule the next expiration */
|
||||
{
|
||||
make_timeout( &timer->when, timer->period );
|
||||
timer->timeout = add_timeout_user( &timer->when, timer_callback, timer );
|
||||
}
|
||||
else timer->timeout = NULL;
|
||||
|
||||
/* wake up waiters */
|
||||
timer->signaled = 1;
|
||||
wake_up( &timer->obj, 0 );
|
||||
}
|
||||
|
||||
/* set the timer expiration and period */
|
||||
static void set_timer( struct timer *timer, int sec, int usec, int period,
|
||||
void *callback, void *arg )
|
||||
{
|
||||
if (timer->manual)
|
||||
{
|
||||
period = 0; /* period doesn't make any sense for a manual timer */
|
||||
timer->signaled = 0;
|
||||
}
|
||||
if (timer->timeout) remove_timeout_user( timer->timeout );
|
||||
timer->when.tv_sec = sec;
|
||||
timer->when.tv_usec = usec;
|
||||
timer->period = period;
|
||||
timer->callback = callback;
|
||||
timer->arg = arg;
|
||||
timer->timeout = add_timeout_user( &timer->when, timer_callback, timer );
|
||||
}
|
||||
|
||||
/* cancel a running timer */
|
||||
static void cancel_timer( struct timer *timer )
|
||||
{
|
||||
if (timer->timeout)
|
||||
{
|
||||
remove_timeout_user( timer->timeout );
|
||||
timer->timeout = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void timer_dump( struct object *obj, int verbose )
|
||||
{
|
||||
struct timer *timer = (struct timer *)obj;
|
||||
assert( obj->ops == &timer_ops );
|
||||
fprintf( stderr, "Timer manual=%d when=%ld.%06ld period=%d ",
|
||||
timer->manual, timer->when.tv_sec, timer->when.tv_usec, timer->period );
|
||||
dump_object_name( &timer->obj );
|
||||
fputc( '\n', stderr );
|
||||
}
|
||||
|
||||
static int timer_signaled( struct object *obj, struct thread *thread )
|
||||
{
|
||||
struct timer *timer = (struct timer *)obj;
|
||||
assert( obj->ops == &timer_ops );
|
||||
return timer->signaled;
|
||||
}
|
||||
|
||||
static int timer_satisfied( struct object *obj, struct thread *thread )
|
||||
{
|
||||
struct timer *timer = (struct timer *)obj;
|
||||
assert( obj->ops == &timer_ops );
|
||||
if (!timer->manual) timer->signaled = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void timer_destroy( struct object *obj )
|
||||
{
|
||||
struct timer *timer = (struct timer *)obj;
|
||||
assert( obj->ops == &timer_ops );
|
||||
|
||||
if (timer->timeout) remove_timeout_user( timer->timeout );
|
||||
}
|
||||
|
||||
/* create a timer */
|
||||
DECL_HANDLER(create_timer)
|
||||
{
|
||||
size_t len = get_req_strlenW( req->name );
|
||||
struct timer *timer;
|
||||
|
||||
req->handle = -1;
|
||||
if ((timer = create_timer( req->name, len, req->manual )))
|
||||
{
|
||||
req->handle = alloc_handle( current->process, timer, TIMER_ALL_ACCESS, req->inherit );
|
||||
release_object( timer );
|
||||
}
|
||||
}
|
||||
|
||||
/* open a handle to a timer */
|
||||
DECL_HANDLER(open_timer)
|
||||
{
|
||||
size_t len = get_req_strlenW( req->name );
|
||||
req->handle = open_object( req->name, len, &timer_ops, req->access, req->inherit );
|
||||
}
|
||||
|
||||
/* set a waitable timer */
|
||||
DECL_HANDLER(set_timer)
|
||||
{
|
||||
struct timer *timer;
|
||||
|
||||
if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
|
||||
TIMER_MODIFY_STATE, &timer_ops )))
|
||||
{
|
||||
set_timer( timer, req->sec, req->usec, req->period, req->callback, req->arg );
|
||||
release_object( timer );
|
||||
}
|
||||
}
|
||||
|
||||
/* cancel a waitable timer */
|
||||
DECL_HANDLER(cancel_timer)
|
||||
{
|
||||
struct timer *timer;
|
||||
|
||||
if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
|
||||
TIMER_MODIFY_STATE, &timer_ops )))
|
||||
{
|
||||
cancel_timer( timer );
|
||||
release_object( timer );
|
||||
}
|
||||
}
|
|
@ -999,6 +999,47 @@ static void dump_set_registry_levels_request( struct set_registry_levels_request
|
|||
fprintf( stderr, " version=%d", req->version );
|
||||
}
|
||||
|
||||
static void dump_create_timer_request( struct create_timer_request *req )
|
||||
{
|
||||
fprintf( stderr, " inherit=%d,", req->inherit );
|
||||
fprintf( stderr, " manual=%d,", req->manual );
|
||||
fprintf( stderr, " name=" );
|
||||
dump_unicode_string( req->name );
|
||||
}
|
||||
|
||||
static void dump_create_timer_reply( struct create_timer_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%d", req->handle );
|
||||
}
|
||||
|
||||
static void dump_open_timer_request( struct open_timer_request *req )
|
||||
{
|
||||
fprintf( stderr, " access=%08x,", req->access );
|
||||
fprintf( stderr, " inherit=%d,", req->inherit );
|
||||
fprintf( stderr, " name=" );
|
||||
dump_unicode_string( req->name );
|
||||
}
|
||||
|
||||
static void dump_open_timer_reply( struct open_timer_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%d", req->handle );
|
||||
}
|
||||
|
||||
static void dump_set_timer_request( struct set_timer_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%d,", req->handle );
|
||||
fprintf( stderr, " sec=%d,", req->sec );
|
||||
fprintf( stderr, " usec=%d,", req->usec );
|
||||
fprintf( stderr, " period=%d,", req->period );
|
||||
fprintf( stderr, " callback=%p,", req->callback );
|
||||
fprintf( stderr, " arg=%p", req->arg );
|
||||
}
|
||||
|
||||
static void dump_cancel_timer_request( struct cancel_timer_request *req )
|
||||
{
|
||||
fprintf( stderr, " handle=%d", req->handle );
|
||||
}
|
||||
|
||||
static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
||||
(dump_func)dump_new_process_request,
|
||||
(dump_func)dump_new_thread_request,
|
||||
|
@ -1086,6 +1127,10 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)dump_load_registry_request,
|
||||
(dump_func)dump_save_registry_request,
|
||||
(dump_func)dump_set_registry_levels_request,
|
||||
(dump_func)dump_create_timer_request,
|
||||
(dump_func)dump_open_timer_request,
|
||||
(dump_func)dump_set_timer_request,
|
||||
(dump_func)dump_cancel_timer_request,
|
||||
};
|
||||
|
||||
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
||||
|
@ -1175,6 +1220,10 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
|
|||
(dump_func)0,
|
||||
(dump_func)0,
|
||||
(dump_func)0,
|
||||
(dump_func)dump_create_timer_reply,
|
||||
(dump_func)dump_open_timer_reply,
|
||||
(dump_func)0,
|
||||
(dump_func)0,
|
||||
};
|
||||
|
||||
static const char * const req_names[REQ_NB_REQUESTS] = {
|
||||
|
@ -1264,6 +1313,10 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
|
|||
"load_registry",
|
||||
"save_registry",
|
||||
"set_registry_levels",
|
||||
"create_timer",
|
||||
"open_timer",
|
||||
"set_timer",
|
||||
"cancel_timer",
|
||||
};
|
||||
|
||||
/* ### make_requests end ### */
|
||||
|
|
Loading…
Reference in New Issue