Encapsulated Wine internal data into an ifdef __WINE__.
[wine.git] / server / timer.c
blob9ded7bd5c89fbc757c941b50c886562082a32939
1 /*
2 * Waitable timers management
4 * Copyright (C) 1999 Alexandre Julliard
5 */
7 #include <assert.h>
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <sys/time.h>
11 #include <sys/types.h>
13 #include "winerror.h"
15 #include "handle.h"
16 #include "request.h"
18 /* FIXME: check values and move to standard header */
19 #define TIMER_MODIFY_STATE 0x0001
20 #define TIMER_QUERY_STATE 0x0002
21 #define TIMER_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|SYNCHRONIZE|0x3)
23 struct timer
25 struct object obj; /* object header */
26 int manual; /* manual reset */
27 int signaled; /* current signaled state */
28 int period; /* timer period in ms */
29 struct timeval when; /* next expiration */
30 struct timeout_user *timeout; /* timeout user */
31 void *callback; /* callback APC function */
32 void *arg; /* callback argument */
35 static void timer_dump( struct object *obj, int verbose );
36 static int timer_signaled( struct object *obj, struct thread *thread );
37 static int timer_satisfied( struct object *obj, struct thread *thread );
38 static void timer_destroy( struct object *obj );
40 static const struct object_ops timer_ops =
42 sizeof(struct timer), /* size */
43 timer_dump, /* dump */
44 add_queue, /* add_queue */
45 remove_queue, /* remove_queue */
46 timer_signaled, /* signaled */
47 timer_satisfied, /* satisfied */
48 NULL, /* get_poll_events */
49 NULL, /* poll_event */
50 no_read_fd, /* get_read_fd */
51 no_write_fd, /* get_write_fd */
52 no_flush, /* flush */
53 no_get_file_info, /* get_file_info */
54 timer_destroy /* destroy */
58 /* create a timer object */
59 static struct timer *create_timer( const WCHAR *name, size_t len, int manual )
61 struct timer *timer;
63 if ((timer = create_named_object( &timer_ops, name, len )))
65 if (get_error() != ERROR_ALREADY_EXISTS)
67 /* initialize it if it didn't already exist */
68 timer->manual = manual;
69 timer->signaled = 0;
70 timer->when.tv_sec = 0;
71 timer->when.tv_usec = 0;
72 timer->period = 0;
73 timer->timeout = NULL;
76 return timer;
79 /* callback on timer expiration */
80 static void timer_callback( void *private )
82 struct timer *timer = (struct timer *)private;
84 if (timer->period) /* schedule the next expiration */
86 add_timeout( &timer->when, timer->period );
87 timer->timeout = add_timeout_user( &timer->when, timer_callback, timer );
89 else timer->timeout = NULL;
91 /* wake up waiters */
92 timer->signaled = 1;
93 wake_up( &timer->obj, 0 );
96 /* set the timer expiration and period */
97 static void set_timer( struct timer *timer, int sec, int usec, int period,
98 void *callback, void *arg )
100 if (timer->manual)
102 period = 0; /* period doesn't make any sense for a manual timer */
103 timer->signaled = 0;
105 if (timer->timeout) remove_timeout_user( timer->timeout );
106 if (!sec && !usec)
108 /* special case: use now + period as first expiration */
109 gettimeofday( &timer->when, 0 );
110 add_timeout( &timer->when, period );
112 else
114 timer->when.tv_sec = sec;
115 timer->when.tv_usec = usec;
117 timer->period = period;
118 timer->callback = callback;
119 timer->arg = arg;
120 timer->timeout = add_timeout_user( &timer->when, timer_callback, timer );
123 /* cancel a running timer */
124 static void cancel_timer( struct timer *timer )
126 if (timer->timeout)
128 remove_timeout_user( timer->timeout );
129 timer->timeout = NULL;
133 static void timer_dump( struct object *obj, int verbose )
135 struct timer *timer = (struct timer *)obj;
136 assert( obj->ops == &timer_ops );
137 fprintf( stderr, "Timer manual=%d when=%ld.%06ld period=%d ",
138 timer->manual, timer->when.tv_sec, timer->when.tv_usec, timer->period );
139 dump_object_name( &timer->obj );
140 fputc( '\n', stderr );
143 static int timer_signaled( struct object *obj, struct thread *thread )
145 struct timer *timer = (struct timer *)obj;
146 assert( obj->ops == &timer_ops );
147 return timer->signaled;
150 static int timer_satisfied( struct object *obj, struct thread *thread )
152 struct timer *timer = (struct timer *)obj;
153 assert( obj->ops == &timer_ops );
154 if (!timer->manual) timer->signaled = 0;
155 return 0;
158 static void timer_destroy( struct object *obj )
160 struct timer *timer = (struct timer *)obj;
161 assert( obj->ops == &timer_ops );
163 if (timer->timeout) remove_timeout_user( timer->timeout );
166 /* create a timer */
167 DECL_HANDLER(create_timer)
169 size_t len = get_req_strlenW( req->name );
170 struct timer *timer;
172 req->handle = -1;
173 if ((timer = create_timer( req->name, len, req->manual )))
175 req->handle = alloc_handle( current->process, timer, TIMER_ALL_ACCESS, req->inherit );
176 release_object( timer );
180 /* open a handle to a timer */
181 DECL_HANDLER(open_timer)
183 size_t len = get_req_strlenW( req->name );
184 req->handle = open_object( req->name, len, &timer_ops, req->access, req->inherit );
187 /* set a waitable timer */
188 DECL_HANDLER(set_timer)
190 struct timer *timer;
192 if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
193 TIMER_MODIFY_STATE, &timer_ops )))
195 set_timer( timer, req->sec, req->usec, req->period, req->callback, req->arg );
196 release_object( timer );
200 /* cancel a waitable timer */
201 DECL_HANDLER(cancel_timer)
203 struct timer *timer;
205 if ((timer = (struct timer *)get_handle_obj( current->process, req->handle,
206 TIMER_MODIFY_STATE, &timer_ops )))
208 cancel_timer( timer );
209 release_object( timer );