changeset 20943:5d1efb601d6c

lib: Fix kqueue io_loop_get_wait_time usage The code needs to take into consideration, when there is no IO to be waited, but possibly there is io_set_pending used, or just timeouts.
author Aki Tuomi <aki.tuomi@dovecot.fi>
date Mon, 24 Oct 2016 10:13:42 +0300
parents d8169b055abe
children 62ffcd1b9739
files src/lib/ioloop-kqueue.c
diffstat 1 files changed, 13 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/src/lib/ioloop-kqueue.c	Mon Oct 24 10:08:42 2016 +0300
+++ b/src/lib/ioloop-kqueue.c	Mon Oct 24 10:13:42 2016 +0300
@@ -117,18 +117,26 @@
 	struct timespec ts;
 	struct io_file *io;
 	unsigned int events_count;
-	int ret, i;
+	int ret, i, msecs;
 
 	/* get the time left for next timeout task */
-	io_loop_get_wait_time(ioloop, &tv);
+	msecs = io_loop_get_wait_time(ioloop, &tv);
 	ts.tv_sec = tv.tv_sec;
 	ts.tv_nsec = tv.tv_usec * 1000;
 
 	/* wait for events */
 	events = array_get_modifiable(&ctx->events, &events_count);
-	ret = kevent (ctx->kq, NULL, 0, events, events_count, &ts);
-	if (ret < 0 && errno != EINTR)
-		i_panic("kevent(): %m");
+
+	if (events_count > 0) {
+		ret = kevent (ctx->kq, NULL, 0, events, events_count, &ts);
+		if (ret < 0 && errno != EINTR)
+			i_panic("kevent() failed: %m");
+	} else {
+		if (msecs < 0)
+			i_panic("BUG: No IOs or timeouts set. Not waiting for infinity.");
+		usleep(msecs * 1000);
+		ret = 0;
+	}
 
 	/* reference all IOs */
 	for (i = 0; i < ret; i++) {