]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: fd: add fd_poll_{recv,send} for use when explicit polling is required
authorWilly Tarreau <w@1wt.eu>
Thu, 9 Aug 2012 10:14:03 +0000 (12:14 +0200)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Sep 2012 19:53:11 +0000 (21:53 +0200)
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.

include/proto/fd.h
include/types/fd.h
src/ev_epoll.c
src/ev_kqueue.c
src/ev_poll.c
src/ev_select.c
src/ev_sepoll.c

index 072d3f64106e64d6cb715ead509d4b620b6ff4b1..bfce1206d315276a7d263058eb2c50ffa4bc0065 100644 (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);
index 2e350b82896876425d04aa32bc9c06233562de74..c6e47f2033381b305d95cf2ed4a6be8600994c78 100644 (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 */
index 6c8408bc0d8a8d31ff806dcf193749de0b821a3f..a566917bac8855b07f6773667e21285e6091a111 100644 (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;
index 4bfbf1bf888b9bfb0bdb4ed953740230e3d848d8..e771c33a3162d63c062ee69ecac36ab67e3c0475 100644 (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;
index f72dfe286731e9703bc8e55a85a54ec0186b42be..b05fec14fea1b0e81142b9a2b4c9c7f75c9aa8d5 100644 (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;
 }
index cf4526216bfe403c39e3cd319f4ed35eb10a4c6a..100bc575659592e73beb8977097b8ad059b62875 100644 (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;
 }
index 62ee1156e22638751664b3087641c160479f1f93..506ab3103e975f27bc265cf4beddbf3ebd1e43f6 100644 (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;