diff --git a/include/proto/fd.h b/include/proto/fd.h index 072d3f641..bfce1206d 100644 --- a/include/proto/fd.h +++ b/include/proto/fd.h @@ -83,6 +83,11 @@ static inline void fd_stop_recv(int fd) cur_poller.clr(fd, DIR_RD); } +static inline void fd_poll_recv(int fd) +{ + cur_poller.wai(fd, DIR_RD); +} + static inline void fd_want_send(int fd) { cur_poller.set(fd, DIR_WR); @@ -93,6 +98,11 @@ static inline void fd_stop_send(int fd) cur_poller.clr(fd, DIR_WR); } +static inline void fd_poll_send(int fd) +{ + cur_poller.wai(fd, DIR_WR); +} + static inline void fd_stop_both(int fd) { cur_poller.rem(fd); diff --git a/include/types/fd.h b/include/types/fd.h index 2e350b828..c6e47f203 100644 --- a/include/types/fd.h +++ b/include/types/fd.h @@ -100,6 +100,7 @@ struct poller { int REGPRM2 (*is_set)(const int fd, int dir); /* check if is being polled for dir */ void REGPRM2 (*set)(const int fd, int dir); /* set polling on for */ void REGPRM2 (*clr)(const int fd, int dir); /* clear polling on for */ + void REGPRM2 (*wai)(const int fd, int dir); /* wait for polling on for */ void REGPRM1 (*rem)(const int fd); /* remove any polling on */ void REGPRM1 (*clo)(const int fd); /* mark as closed */ void REGPRM2 (*poll)(struct poller *p, int exp); /* the poller itself */ diff --git a/src/ev_epoll.c b/src/ev_epoll.c index 6c8408bc0..a566917ba 100644 --- a/src/ev_epoll.c +++ b/src/ev_epoll.c @@ -396,6 +396,7 @@ static void _do_register(void) p->is_set = __fd_is_set; p->set = __fd_set; + p->wai = __fd_set; p->clr = __fd_clr; p->rem = __fd_rem; p->clo = __fd_clo; diff --git a/src/ev_kqueue.c b/src/ev_kqueue.c index 4bfbf1bf8..e771c33a3 100644 --- a/src/ev_kqueue.c +++ b/src/ev_kqueue.c @@ -274,6 +274,7 @@ static void _do_register(void) p->is_set = __fd_is_set; p->set = __fd_set; + p->wai = __fd_set; p->clr = __fd_clr; p->rem = __fd_rem; p->clo = __fd_clo; diff --git a/src/ev_poll.c b/src/ev_poll.c index f72dfe286..b05fec14f 100644 --- a/src/ev_poll.c +++ b/src/ev_poll.c @@ -230,6 +230,7 @@ static void _do_register(void) p->poll = _do_poll; p->is_set = __fd_is_set; p->set = __fd_set; + p->wai = __fd_set; p->clr = __fd_clr; p->clo = p->rem = __fd_rem; } diff --git a/src/ev_select.c b/src/ev_select.c index cf4526216..100bc5756 100644 --- a/src/ev_select.c +++ b/src/ev_select.c @@ -227,6 +227,7 @@ static void _do_register(void) p->poll = _do_poll; p->is_set = __fd_is_set; p->set = __fd_set; + p->wai = __fd_set; p->clr = __fd_clr; p->clo = p->rem = __fd_rem; } diff --git a/src/ev_sepoll.c b/src/ev_sepoll.c index 62ee1156e..506ab3103 100644 --- a/src/ev_sepoll.c +++ b/src/ev_sepoll.c @@ -215,6 +215,26 @@ REGPRM2 static int __fd_is_set(const int fd, int dir) * Don't worry about the strange constructs in __fd_set/__fd_clr, they are * designed like this in order to reduce the number of jumps (verified). */ +REGPRM2 static void __fd_wai(const int fd, int dir) +{ + unsigned int i; + +#if DEBUG_DEV + if (!fdtab[fd].owner) { + fprintf(stderr, "sepoll.fd_wai called on closed fd #%d.\n", fd); + ABORT_NOW(); + } +#endif + i = ((unsigned)fdtab[fd].spec.e >> dir) & FD_EV_MASK_DIR; + + if (!(i & FD_EV_IN_SL)) { + if (i == FD_EV_WAIT) + return; /* already in desired state */ + alloc_spec_entry(fd); /* need a spec entry */ + } + fdtab[fd].spec.e ^= (i ^ (unsigned int)FD_EV_IN_PL) << dir; +} + REGPRM2 static void __fd_set(const int fd, int dir) { unsigned int i; @@ -592,6 +612,7 @@ static void _do_register(void) p->is_set = __fd_is_set; p->set = __fd_set; + p->wai = __fd_wai; p->clr = __fd_clr; p->rem = __fd_rem; p->clo = __fd_clo;