Try to process all pending events after select().
authorGuus Sliepen <guus@tinc-vpn.org>
Wed, 28 Feb 2018 20:28:16 +0000 (21:28 +0100)
committerGuus Sliepen <guus@tinc-vpn.org>
Wed, 28 Feb 2018 20:28:16 +0000 (21:28 +0100)
If we break out of the loop every time at the first filedescriptor that
is read/writeable, we risk starving the other filedescriptors.

src/event.c

index 9cd7d07ae7246a0554db90c84760bd3445da0cec..8c7de4799e95f570d858d6a063585d018627a85f 100644 (file)
@@ -348,6 +348,8 @@ bool event_loop(void) {
                        continue;
                }
 
+               unsigned int curgen = io_tree.generation;
+
                for splay_each(io_t, io, &io_tree) {
                        if(FD_ISSET(io->fd, &writable)) {
                                io->cb(io->data, IO_WRITE);
@@ -360,10 +362,12 @@ bool event_loop(void) {
                        /*
                           There are scenarios in which the callback will remove another io_t from the tree
                           (e.g. closing a double connection). Since splay_each does not support that, we
-                          need to exit the loop now. That's okay, since any remaining events will get picked
-                          up by the next select() call.
+                          need to exit the loop if that happens. That's okay, since any remaining events will
+                          get picked up by the next select() call.
                         */
-                       break;
+                       if(curgen != io_tree.generation) {
+                               break;
+                       }
                }
        }