MEDIUM: fd: add fd_poll_{recv,send} for use when explicit polling is required
The old EV_FD_SET() macro was confusing, as it would enable receipt but there was no way to indicate that EAGAIN was received, hence the recently added FD_WAIT_* flags. They're not enough as we're still facing a conflict between EV_FD_* and FD_WAIT_*. So let's offer I/O functions what they need to explicitly request polling.
This commit is contained in:
parent
49b046dddf
commit
babd05a6c6
|
@ -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);
|
||||
|
|
|
@ -100,6 +100,7 @@ struct poller {
|
|||
int REGPRM2 (*is_set)(const int fd, int dir); /* check if <fd> is being polled for dir <dir> */
|
||||
void REGPRM2 (*set)(const int fd, int dir); /* set polling on <fd> for <dir> */
|
||||
void REGPRM2 (*clr)(const int fd, int dir); /* clear polling on <fd> for <dir> */
|
||||
void REGPRM2 (*wai)(const int fd, int dir); /* wait for polling on <fd> for <dir> */
|
||||
void REGPRM1 (*rem)(const int fd); /* remove any polling on <fd> */
|
||||
void REGPRM1 (*clo)(const int fd); /* mark <fd> as closed */
|
||||
void REGPRM2 (*poll)(struct poller *p, int exp); /* the poller itself */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue