]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Poll: Prevent the improbable case of EAGAIN after POLLIN
authorJan Moskyto Matejka <mq@ucw.cz>
Tue, 15 Mar 2016 13:57:49 +0000 (14:57 +0100)
committerJan Moskyto Matejka <mq@ucw.cz>
Tue, 15 Mar 2016 13:57:49 +0000 (14:57 +0100)
proto/bfd/io.c
sysdep/unix/io.c

index fb15004083193c173a96fcbe5ec0c7ebd9c37258..79ed9af71e03e793921123af5d7309f9780bf992 100644 (file)
@@ -576,7 +576,7 @@ sockets_close_fds(struct birdloop *loop)
   loop->close_scheduled = 0;
 }
 
-int sk_read(sock *s);
+int sk_read(sock *s, int revents);
 int sk_write(sock *s);
 
 static void
@@ -605,7 +605,7 @@ sockets_fire(struct birdloop *loop)
 
     if (pfd->revents & POLLIN)
       while (e && *psk && (*psk)->rx_hook)
-       e = sk_read(*psk);
+       e = sk_read(*psk, 0);
 
     e = 1;
     if (pfd->revents & POLLOUT)
index bc212de1fe64a3aa4b1bc327959548c51933426d..b769de583d218cd485ae37b9f62a46952179f372 100644 (file)
@@ -1760,7 +1760,7 @@ sk_send_full(sock *s, unsigned len, struct iface *ifa,
  /* sk_read() and sk_write() are called from BFD's event loop */
 
 int
-sk_read(sock *s)
+sk_read(sock *s, int revents)
 {
   switch (s->type)
   {
@@ -1779,6 +1779,11 @@ sk_read(sock *s)
       {
        if (errno != EINTR && errno != EAGAIN)
          s->err_hook(s, errno);
+       else if (errno == EAGAIN && !(revents & POLLIN))
+       {
+         log(L_ERR "Got EAGAIN from read when revents=%x (without POLLIN)", revents);
+         s->err_hook(s, 0);
+       }
       }
       else if (!c)
        s->err_hook(s, 0);
@@ -2159,7 +2164,7 @@ io_loop(void)
                  {
                    steps--;
                    io_log_event(s->rx_hook, s->data);
-                   e = sk_read(s);
+                   e = sk_read(s, pfd[s->index].revents);
                    if (s != current_sock)
                      goto next;
                  }
@@ -2203,7 +2208,7 @@ io_loop(void)
                {
                  count++;
                  io_log_event(s->rx_hook, s->data);
-                 sk_read(s);
+                 sk_read(s, pfd[s->index].revents);
                  if (s != current_sock)
                      goto next2;
                }