26 #if !LELY_NO_STDIO && _POSIX_C_SOURCE >= 199309L
46 static size_t io_timer_impl_dev_cancel(
io_dev_t *dev,
struct ev_task *task);
47 static size_t io_timer_impl_dev_abort(
io_dev_t *dev,
struct ev_task *task);
50 static const struct io_dev_vtbl io_timer_impl_dev_vtbl = {
51 &io_timer_impl_dev_get_ctx,
52 &io_timer_impl_dev_get_exec,
53 &io_timer_impl_dev_cancel,
54 &io_timer_impl_dev_abort
60 static int io_timer_impl_getoverrun(
const io_timer_t *timer);
61 static int io_timer_impl_gettime(
62 const io_timer_t *timer,
struct itimerspec *value);
63 static int io_timer_impl_settime(
io_timer_t *timer,
int flags,
64 const struct itimerspec *value,
struct itimerspec *ovalue);
65 static void io_timer_impl_submit_wait(
70 &io_timer_impl_get_dev,
71 &io_timer_impl_get_clock,
72 &io_timer_impl_getoverrun,
73 &io_timer_impl_gettime,
74 &io_timer_impl_settime,
75 &io_timer_impl_submit_wait
79 static void io_timer_impl_svc_shutdown(
struct io_svc *svc);
82 static const struct io_svc_vtbl io_timer_impl_svc_vtbl = {
84 &io_timer_impl_svc_shutdown
103 static void io_timer_impl_notify_function(
union sigval val);
106 static inline struct io_timer_impl *io_timer_impl_from_timer(
109 const struct io_svc *svc);
121 impl->timer_vptr = NULL;
123 return &impl->timer_vptr;
127 io_timer_free(
void *ptr)
130 free(io_timer_impl_from_timer(ptr));
137 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
145 impl->dev_vptr = &io_timer_impl_dev_vtbl;
146 impl->timer_vptr = &io_timer_impl_vtbl;
153 impl->clockid = clockid;
156 ev.sigev_notify = SIGEV_THREAD;
158 ev.sigev_value.sival_ptr = impl;
159 ev.sigev_notify_function = &io_timer_impl_notify_function;
160 ev.sigev_notify_attributes = NULL;
161 if (timer_create(clockid, &ev, &impl->timerid) == -1) {
163 goto error_create_timer;
167 if ((errsv = pthread_mutex_init(&impl->mtx, NULL)))
183 timer_delete(impl->timerid);
192 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
196 io_timer_impl_svc_shutdown(&impl->svc);
199 struct itimerspec value = { { 0, 0 }, { 0, 0 } };
200 timer_settime(impl->timerid, 0, &value, NULL);
206 pthread_mutex_destroy(&impl->mtx);
209 timer_delete(impl->timerid);
223 io_timer_t *tmp = io_timer_init(timer, poll, exec, clockid);
233 io_timer_free((
void *)timer);
243 io_timer_fini(timer);
244 io_timer_free((
void *)timer);
249 io_timer_impl_dev_get_ctx(
const io_dev_t *dev)
251 const struct io_timer_impl *impl = io_timer_impl_from_dev(dev);
257 io_timer_impl_dev_get_exec(
const io_dev_t *dev)
259 const struct io_timer_impl *impl = io_timer_impl_from_dev(dev);
272 io_timer_impl_pop(impl, &queue, task);
274 return io_timer_wait_queue_post(&queue, -1, ECANCELED);
285 io_timer_impl_pop(impl, &queue, task);
291 io_timer_impl_get_dev(
const io_timer_t *timer)
293 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
295 return &impl->dev_vptr;
299 io_timer_impl_get_clock(
const io_timer_t *timer)
301 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
302 assert(impl->clockid == CLOCK_REALTIME
303 || impl->clockid == CLOCK_MONOTONIC);
305 switch (impl->clockid) {
308 default:
return NULL;
313 io_timer_impl_getoverrun(
const io_timer_t *timer)
315 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
317 return timer_getoverrun(impl->timerid);
321 io_timer_impl_gettime(
const io_timer_t *timer,
struct itimerspec *value)
323 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
325 return timer_gettime(impl->timerid, value);
329 io_timer_impl_settime(
io_timer_t *timer,
int flags,
330 const struct itimerspec *value,
struct itimerspec *ovalue)
332 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
334 return timer_settime(impl->timerid, flags, value, ovalue);
340 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
345 task->
exec = impl->exec;
349 pthread_mutex_lock(&impl->mtx);
351 if (impl->shutdown) {
353 pthread_mutex_unlock(&impl->mtx);
355 io_timer_wait_post(wait, -1, ECANCELED);
359 pthread_mutex_unlock(&impl->mtx);
365 io_timer_impl_svc_shutdown(
struct io_svc *svc)
371 pthread_mutex_lock(&impl->mtx);
373 int shutdown = !impl->shutdown;
376 pthread_mutex_unlock(&impl->mtx);
381 io_timer_impl_dev_cancel(dev, NULL);
385 io_timer_impl_notify_function(
union sigval val)
392 int overrun = timer_getoverrun(impl->timerid);
398 pthread_mutex_lock(&impl->mtx);
402 pthread_mutex_unlock(&impl->mtx);
405 io_timer_wait_queue_post(&queue, overrun, errno);
410 io_timer_impl_from_dev(
const io_dev_t *dev)
418 io_timer_impl_from_timer(
const io_timer_t *timer)
426 io_timer_impl_from_svc(
const struct io_svc *svc)
441 pthread_mutex_lock(&impl->mtx);
448 pthread_mutex_unlock(&impl->mtx);
452 #endif // !LELY_NO_STDIO && _POSIX_C_SOURCE >= 199309L