diff --git a/io.h b/io.h index 7762f65..cd0d5ca 100644 --- a/io.h +++ b/io.h @@ -249,12 +249,16 @@ enum { IOM_WRITE=2, IOM_ERROR=4 }; +/* signal interest in events from a socket */ /* return -1 if error, events can be IOM_READ or IOM_WRITE */ int iom_add(iomux_t* c,int64 s,unsigned int events); +/* signal interest in more events from a socket */ +int iom_requeue(iomux_t* c,int64 s,unsigned int events); + /* Blocking wait for single event, timeout in milliseconds */ /* return -1 if error, 0 if ok; s set to fd, revents set to known events on that fd */ -/* when done with the fd, call iom_add on it again! */ +/* when done with the fd, call iom_requeue on it to receive more events! */ /* This can be called by multiple threads in parallel */ int iom_wait(iomux_t* c,int64* s,unsigned int* revents,unsigned long timeout); diff --git a/io/iom_requeue.c b/io/iom_requeue.c new file mode 100644 index 0000000..f08e81d --- /dev/null +++ b/io/iom_requeue.c @@ -0,0 +1,28 @@ +#include "io_internal.h" +#ifdef HAVE_EPOLL +#include +#endif +#ifdef HAVE_KQUEUE +#include +#include +#include +#endif + +int iom_requeue(iomux_t* c,int64 s,unsigned int events) { +#ifdef HAVE_EPOLL + struct epoll_event e = { .events=EPOLLONESHOT, .data.fd=s }; + if (events & IOM_READ) e.events|=EPOLLIN; + if (events & IOM_WRITE) e.events|=EPOLLOUT; + return epoll_ctl(c->ctx, EPOLL_CTL_MOD, s, &e); +#elif defined(HAVE_KQUEUE) + struct kevent kev; + struct timespec ts = { 0 }; + EV_SET(&kev, s, + (events & IOM_READ ? EVFILT_READ : 0) + + (events & IOM_WRITE ? EVFILT_WRITE : 0), + EV_ADD | EV_ENABLE | EV_ONESHOT, 0, 0, (void*)s); + return kevent(c->ctx, &kev, 1, 0, 0, &ts); +#else +#warning "only epoll and kqueue supported for now" +#endif +}