#define FD_POLL_DATA (FD_POLL_IN | FD_POLL_OUT)
#define FD_POLL_STICKY (FD_POLL_ERR | FD_POLL_HUP)
+/* flags that an I/O callback may return */
+#define FD_WAIT_READ 0x01
+#define FD_WAIT_WRITE 0x02
+#define FD_WAIT_BOTH (FD_WAIT_READ|FD_WAIT_WRITE)
+
/* bit values for fdtab[fd]->flags. Most of them are used to hold a value
* consecutive to a behaviour change.
*/
/* info about one given fd */
struct fdtab {
+ int (*iocb)(int fd); /* I/O handler, returns FD_WAIT_* */
struct {
int (*f)(int fd); /* read/write function */
} cb[DIR_SIZE];
fdtab[fd].owner = t;
fdtab[fd].cb[DIR_RD].f = &event_srv_chk_r;
fdtab[fd].cb[DIR_WR].f = &event_srv_chk_w;
+ fdtab[fd].iocb = NULL;
fdtab[fd].flags = FD_FL_TCP | FD_FL_TCP_NODELAY;
EV_FD_SET(fd, DIR_WR); /* for connect status */
#ifdef DEBUG_FULL
if ((si->ob->flags & BF_OUT_EMPTY) || si->send_proxy_ofs) {
fdtab[fd].cb[DIR_RD].f = tcp_connect_read;
fdtab[fd].cb[DIR_WR].f = tcp_connect_write;
+ fdtab[fd].iocb = NULL;
}
else {
fdtab[fd].cb[DIR_RD].f = si_data(si)->read;
fdtab[fd].cb[DIR_WR].f = si_data(si)->write;
+ fdtab[fd].iocb = NULL;
}
fd_insert(fd);
fdtab[fd].flags = FD_FL_TCP | ((listener->options & LI_O_NOLINGER) ? FD_FL_TCP_NOLING : 0);
fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
+ fdtab[fd].iocb = NULL;
fd_insert(fd);
tcp_return:
fd_insert(fd);
fdtab[fd].cb[DIR_RD].f = listener->proto->accept;
fdtab[fd].cb[DIR_WR].f = NULL; /* never called */
+ fdtab[fd].iocb = NULL;
fdtab[fd].owner = listener; /* reference the listener instead of a task */
return ERR_NONE;
err_rename:
fdtab[cfd].flags = 0;
fdtab[cfd].cb[DIR_RD].f = si_data(&s->si[0])->read;
fdtab[cfd].cb[DIR_WR].f = si_data(&s->si[0])->write;
+ fdtab[cfd].iocb = NULL;
EV_FD_SET(cfd, DIR_RD);
if (p->accept && (ret = p->accept(s)) <= 0) {