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:
Willy Tarreau 2012-08-09 12:14:03 +02:00
parent 49b046dddf
commit babd05a6c6
7 changed files with 36 additions and 0 deletions

View File

@ -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);

View File

@ -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 */

View File

@ -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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;