35#include <sys/select.h>
36#include <sys/signalfd.h>
42static int _init(
uev_ctx_t *ctx,
int close_old)
46 fd = epoll_create1(EPOLL_CLOEXEC);
59static int has_data(
int fd)
61 struct timeval timeout = { 0, 0 };
68 if (select(1, &fds, NULL, NULL, &timeout) > 0)
69 return ioctl(0, FIONREAD, &n) == 0 && n > 0;
75int _uev_watcher_init(
uev_ctx_t *ctx,
uev_t *w, uev_type_t type,
uev_cb_t *cb,
void *arg,
int fd,
int events)
94int _uev_watcher_start(
uev_t *w)
96 struct epoll_event ev;
98 if (!w || w->
fd < 0 || !w->
ctx) {
103 if (_uev_watcher_active(w))
106 ev.events = w->events | EPOLLRDHUP;
108 if (epoll_ctl(w->
ctx->fd, EPOLL_CTL_ADD, w->
fd, &ev) < 0) {
113 if (w->type != UEV_IO_TYPE || w->events !=
UEV_READ)
117 if (w->
fd != STDIN_FILENO)
120 w->
ctx->workaround = 1;
127 _UEV_INSERT(w, w->
ctx->watchers);
133int _uev_watcher_stop(
uev_t *w)
140 if (!_uev_watcher_active(w))
146 _UEV_REMOVE(w, w->
ctx->watchers);
149 if (epoll_ctl(w->
ctx->fd, EPOLL_CTL_DEL, w->
fd, NULL) < 0)
156int _uev_watcher_active(
uev_t *w)
161 return w->active > 0;
165int _uev_watcher_rearm(
uev_t *w)
167 struct epoll_event ev;
169 if (!w || w->
fd < 0) {
174 ev.events = w->events | EPOLLRDHUP;
176 if (epoll_ctl(w->
ctx->fd, EPOLL_CTL_MOD, w->
fd, &ev) < 0)
220 if (!ctx || maxevents < 1) {
228 memset(ctx, 0,
sizeof(*ctx));
229 ctx->maxevents = maxevents;
231 return _init(ctx, 0);
249 _UEV_FOREACH(w, ctx->watchers) {
251 _UEV_REMOVE(w, ctx->watchers);
253 if (!_uev_watcher_active(w))
261 case UEV_SIGNAL_TYPE:
276 ctx->watchers = NULL;
304 if (!ctx || ctx->fd < 0) {
316 _UEV_FOREACH(w, ctx->watchers) {
317 if (UEV_CRON_TYPE == w->type)
319 if (UEV_TIMER_TYPE == w->type)
323 while (ctx->running && ctx->watchers) {
325 int maxevents = ctx->maxevents;
326 int i, nfds, rerun = 0;
332 if (ctx->workaround) {
333 _UEV_FOREACH(w, ctx->watchers) {
334 if (w->active != -1 || !w->cb)
337 if (!has_data(w->
fd)) {
339 _UEV_REMOVE(w, ctx->watchers);
351 while ((nfds = epoll_wait(ctx->fd, ee, maxevents, timeout)) < 0) {
364 for (i = 0; ctx->running && i < nfds; i++) {
365 struct signalfd_siginfo fdsi;
366 ssize_t sz =
sizeof(fdsi);
370 w = (
uev_t *)ee[i].data.ptr;
371 events = ee[i].events;
375 if (events & (EPOLLHUP | EPOLLERR))
379 case UEV_SIGNAL_TYPE:
380 if (read(w->
fd, &fdsi, sz) != sz) {
391 if (read(w->
fd, &exp,
sizeof(exp)) !=
sizeof(exp)) {
403 if (read(w->
fd, &exp,
sizeof(exp)) !=
sizeof(exp)) {
405 if (errno != ECANCELED) {
411 if (!w->u.c.interval)
414 w->u.c.when += w->u.c.interval;
420 if (read(w->
fd, &exp,
sizeof(exp)) !=
sizeof(exp))
430 w->cb(w, w->arg, events & UEV_EVENT_MASK);
int uev_cron_set(uev_t *w, time_t when, time_t interval)
int uev_cron_stop(uev_t *w)
int uev_event_stop(uev_t *w)
int uev_io_stop(uev_t *w)
int uev_signal_stop(uev_t *w)
int uev_signal_start(uev_t *w)
struct signalfd_siginfo siginfo
int uev_timer_stop(uev_t *w)
int uev_timer_set(uev_t *w, int timeout, int period)
int uev_exit(uev_ctx_t *ctx)
int uev_run(uev_ctx_t *ctx, int flags)
int uev_init1(uev_ctx_t *ctx, int maxevents)
int uev_init(uev_ctx_t *ctx)
void uev_cb_t(uev_t *w, void *arg, int events)