From ad47a30f5e9f1db9d280515650d424389f8ae1b5 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 29 Nov 1999 01:58:35 +0000 Subject: [PATCH] Implemented waitable timers. --- dlls/ntdll/nt.c | 3 - include/server.h | 41 +++++++++ include/winbase.h | 30 ++++--- relay32/kernel32.spec | 12 +-- scheduler/Makefile.in | 3 +- scheduler/timer.c | 122 ++++++++++++++++++++++++++ server/Makefile.in | 1 + server/request.h | 8 ++ server/timer.c | 200 ++++++++++++++++++++++++++++++++++++++++++ server/trace.c | 53 +++++++++++ 10 files changed, 453 insertions(+), 20 deletions(-) create mode 100644 scheduler/timer.c create mode 100644 server/timer.c diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 4fa4d1034a5..4206462d838 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -18,9 +18,6 @@ DEFAULT_DEBUG_CHANNEL(ntdll) -/* move to winbase.h */ -typedef VOID (CALLBACK *PTIMERAPCROUTINE)(LPVOID lpArgToCompletionRoutine,DWORD dwTimerLowValue,DWORD dwTimerHighValue); - /* * Timer object */ diff --git a/include/server.h b/include/server.h index 62fe2e1ad38..1518f0ded7f 100644 --- a/include/server.h +++ b/include/server.h @@ -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 }; diff --git a/include/winbase.h b/include/winbase.h index 69a656faa8f..045544d9824 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -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); diff --git a/relay32/kernel32.spec b/relay32/kernel32.spec index dc64eadcb25..0218608ff64 100644 --- a/relay32/kernel32.spec +++ b/relay32/kernel32.spec @@ -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 diff --git a/scheduler/Makefile.in b/scheduler/Makefile.in index e969ff0f468..c2127c52e3f 100644 --- a/scheduler/Makefile.in +++ b/scheduler/Makefile.in @@ -19,7 +19,8 @@ C_SRCS = \ synchro.c \ sysdeps.c \ syslevel.c \ - thread.c + thread.c \ + timer.c all: $(MODULE).o diff --git a/scheduler/timer.c b/scheduler/timer.c new file mode 100644 index 00000000000..0054187b974 --- /dev/null +++ b/scheduler/timer.c @@ -0,0 +1,122 @@ +/* + * Win32 waitable timers + * + * Copyright 1999 Alexandre Julliard + */ + +#include +#include +#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 ); +} diff --git a/server/Makefile.in b/server/Makefile.in index d917cfed5a3..60aa6e0f647 100644 --- a/server/Makefile.in +++ b/server/Makefile.in @@ -27,6 +27,7 @@ C_SRCS = \ sock.c \ socket.c \ thread.c \ + timer.c \ trace.c \ unicode.c diff --git a/server/request.h b/server/request.h index 0d509ac643e..d34c7986395 100644 --- a/server/request.h +++ b/server/request.h @@ -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 */ diff --git a/server/timer.c b/server/timer.c new file mode 100644 index 00000000000..0a20ca160c4 --- /dev/null +++ b/server/timer.c @@ -0,0 +1,200 @@ +/* + * Waitable timers management + * + * Copyright (C) 1999 Alexandre Julliard + */ + +#include +#include +#include +#include +#include + +#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 ); + } +} diff --git a/server/trace.c b/server/trace.c index b05af06f7ae..0e436f2f8ba 100644 --- a/server/trace.c +++ b/server/trace.c @@ -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 ### */