]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Add io_set_never_wait_alone()
authorTimo Sirainen <timo.sirainen@dovecot.fi>
Fri, 17 Aug 2018 08:32:10 +0000 (11:32 +0300)
committerVille Savolainen <ville.savolainen@dovecot.fi>
Wed, 12 Sep 2018 06:11:03 +0000 (09:11 +0300)
If ioloop is run without any timeouts and without IOs that don't have this
flag, assert-crash rather than going to infinite wait.

src/lib/ioloop-private.h
src/lib/ioloop.c
src/lib/ioloop.h

index d134b3f91cd2659d16070cb75db3ea8fc990e07f..dd39ad82d19f90c92e9a3e2e7f818fba22dac935 100644 (file)
@@ -42,6 +42,9 @@ struct io {
        /* trigger I/O callback even if OS doesn't think there is input
           pending */
        bool pending;
+       /* This IO event shouldn't be the only thing being waited on, because
+          it would just result in infinite wait. */
+       bool never_wait_alone;
 
        io_callback_t *callback;
         void *context;
index 650c6ebeacf5a9aa7dab7e5237d720a6261a91c0..dfdc357fd58badc55e5343d2ede8bb0cd4c0cdaa 100644 (file)
@@ -215,6 +215,11 @@ void io_set_pending(struct io *io)
        }
 }
 
+void io_set_never_wait_alone(struct io *io, bool set)
+{
+       io->never_wait_alone = set;
+}
+
 static void timeout_update_next(struct timeout *timeout, struct timeval *tv_now)
 {
        if (tv_now == NULL) {
@@ -512,9 +517,23 @@ static int io_loop_get_wait_time(struct ioloop *ioloop, struct timeval *tv_r)
        return msecs;
 }
 
+static bool io_loop_have_waitable_io_files(struct ioloop *ioloop)
+{
+       struct io_file *io;
+
+       for (io = ioloop->io_files; io != NULL; io = io->next) {
+               if (io->io.callback != NULL && !io->io.never_wait_alone)
+                       return TRUE;
+       }
+       return FALSE;
+}
+
 int io_loop_run_get_wait_time(struct ioloop *ioloop, struct timeval *tv_r)
 {
-       return io_loop_get_wait_time(ioloop, tv_r);
+       int msecs = io_loop_get_wait_time(ioloop, tv_r);
+       if (msecs < 0 && !io_loop_have_waitable_io_files(ioloop))
+               i_panic("BUG: No IOs or timeouts set. Not waiting for infinity.");
+       return msecs;
 }
 
 static int timeout_cmp(const void *p1, const void *p2)
index 7001327e94ced05a1c55706c69db5836264a9cc2..acb8ad957b2f6fc06c68fcaebdad80666b112df8 100644 (file)
@@ -104,6 +104,10 @@ void io_remove_closed(struct io **io);
    if some of the input has already read into some internal buffer and the
    caller wants to handle it the same way as if the fd itself had input. */
 void io_set_pending(struct io *io);
+/* If set, this IO shouldn't be the only thing being waited on, because
+   it would just result in infinite wait. In those situations rather just
+   crash to indicate that there's a bug. */
+void io_set_never_wait_alone(struct io *io, bool set);
 
 /* Timeout handlers */
 struct timeout *