26 #if _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);
119 return impl ? &impl->timer_vptr : NULL;
123 io_timer_free(
void *ptr)
126 free(io_timer_impl_from_timer(ptr));
133 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
141 impl->dev_vptr = &io_timer_impl_dev_vtbl;
142 impl->timer_vptr = &io_timer_impl_vtbl;
149 impl->clockid = clockid;
152 ev.sigev_notify = SIGEV_THREAD;
154 ev.sigev_value.sival_ptr = impl;
155 ev.sigev_notify_function = &io_timer_impl_notify_function;
156 ev.sigev_notify_attributes = NULL;
157 if (timer_create(clockid, &ev, &impl->timerid) == -1) {
159 goto error_create_timer;
163 if ((errsv = pthread_mutex_init(&impl->mtx, NULL)))
179 timer_delete(impl->timerid);
188 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
192 io_timer_impl_svc_shutdown(&impl->svc);
195 struct itimerspec value = { { 0, 0 }, { 0, 0 } };
196 timer_settime(impl->timerid, 0, &value, NULL);
202 pthread_mutex_destroy(&impl->mtx);
205 timer_delete(impl->timerid);
219 io_timer_t *tmp = io_timer_init(timer, poll, exec, clockid);
229 io_timer_free((
void *)timer);
239 io_timer_fini(timer);
240 io_timer_free((
void *)timer);
245 io_timer_impl_dev_get_ctx(
const io_dev_t *dev)
247 const struct io_timer_impl *impl = io_timer_impl_from_dev(dev);
253 io_timer_impl_dev_get_exec(
const io_dev_t *dev)
255 const struct io_timer_impl *impl = io_timer_impl_from_dev(dev);
268 io_timer_impl_pop(impl, &queue, task);
270 return io_timer_wait_queue_post(&queue, -1, ECANCELED);
281 io_timer_impl_pop(impl, &queue, task);
287 io_timer_impl_get_dev(
const io_timer_t *timer)
289 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
291 return &impl->dev_vptr;
295 io_timer_impl_get_clock(
const io_timer_t *timer)
297 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
298 assert(impl->clockid == CLOCK_REALTIME
299 || impl->clockid == CLOCK_MONOTONIC);
301 switch (impl->clockid) {
304 default:
return NULL;
309 io_timer_impl_getoverrun(
const io_timer_t *timer)
311 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
313 return timer_getoverrun(impl->timerid);
317 io_timer_impl_gettime(
const io_timer_t *timer,
struct itimerspec *value)
319 const struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
321 return timer_gettime(impl->timerid, value);
325 io_timer_impl_settime(
io_timer_t *timer,
int flags,
326 const struct itimerspec *value,
struct itimerspec *ovalue)
328 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
330 return timer_settime(impl->timerid, flags, value, ovalue);
336 struct io_timer_impl *impl = io_timer_impl_from_timer(timer);
341 task->
exec = impl->exec;
345 pthread_mutex_lock(&impl->mtx);
347 if (impl->shutdown) {
349 pthread_mutex_unlock(&impl->mtx);
351 io_timer_wait_post(wait, -1, ECANCELED);
355 pthread_mutex_unlock(&impl->mtx);
361 io_timer_impl_svc_shutdown(
struct io_svc *svc)
367 pthread_mutex_lock(&impl->mtx);
369 int shutdown = !impl->shutdown;
372 pthread_mutex_unlock(&impl->mtx);
377 io_timer_impl_dev_cancel(dev, NULL);
381 io_timer_impl_notify_function(
union sigval val)
388 int overrun = timer_getoverrun(impl->timerid);
394 pthread_mutex_lock(&impl->mtx);
398 pthread_mutex_unlock(&impl->mtx);
401 io_timer_wait_queue_post(&queue, overrun, errno);
406 io_timer_impl_from_dev(
const io_dev_t *dev)
414 io_timer_impl_from_timer(
const io_timer_t *timer)
422 io_timer_impl_from_svc(
const struct io_svc *svc)
437 pthread_mutex_lock(&impl->mtx);
444 pthread_mutex_unlock(&impl->mtx);
const struct io_clock_vtbl *const io_clock_t
An abstract clock.
This header file is part of the I/O library; it contains the I/O context and service declarations.
void io_ctx_insert(io_ctx_t *ctx, struct io_svc *svc)
Registers an I/O service with an I/O context.
#define IO_SVC_INIT(vptr)
The static initializer for io_svc.
void io_ctx_remove(io_ctx_t *ctx, struct io_svc *svc)
Unregisters an I/O service with an I/O context.
void ev_exec_on_task_init(ev_exec_t *exec)
Indicates to the specified executor that a task will be submitted for execution in the future.
const struct ev_exec_vtbl *const ev_exec_t
An abstract task executor.
This header file is part of the I/O library; it contains the I/O system timer declarations.
const struct io_timer_vtbl *const io_timer_t
An abstract timer.
This is the public header file of the utilities library.
#define structof(ptr, type, member)
Obtains the address of a structure from the address of one of its members.
const struct io_dev_vtbl *const io_dev_t
An abstract I/O device.
This header file is part of the I/O library; it contains the I/O polling declarations for POSIX platf...
io_ctx_t * io_poll_get_ctx(const io_poll_t *poll)
Returns a pointer to the I/O context with which the I/O polling instance is registered.
io_timer_t * io_timer_create(io_poll_t *poll, ev_exec_t *exec, clockid_t clockid)
Creates a new I/O system timer.
void io_timer_destroy(io_timer_t *timer)
Destroys an I/O system timer.
void sllist_init(struct sllist *list)
Initializes a singly-linked list.
struct sllist * sllist_append(struct sllist *dst, struct sllist *src)
Appends the singly-linked list at src to the one at dst.
struct slnode * sllist_remove(struct sllist *list, struct slnode *node)
Removes a node from a singly-linked list.
void sllist_push_back(struct sllist *list, struct slnode *node)
Pushes a node to the back of a singly-linked list.
This is the internal header file of the Windows-specific I/O declarations.
This header file is part of the C11 and POSIX compatibility library; it includes <stdlib....
An I/O polling interface.
ev_exec_t * exec
A pointer to the executor to which the task is (to be) submitted.
The virtual table of an I/O service.
A wait operation suitable for use with an I/O timer.
struct ev_task task
The task (to be) submitted upon completion (or cancellation) of the wait operation.
This header file is part of the I/O library; it contains the standard system clock definitions.
#define IO_CLOCK_REALTIME
The io_clock_t pointer representing the POSIX realtime clock.
#define IO_CLOCK_MONOTONIC
The io_clock_t pointer representing the POSIX monotonic clock.
size_t ev_task_queue_abort(struct sllist *queue)
Aborts the tasks in queue by invoking ev_exec_on_task_fini() for each of them.