]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib: Added support for setting timeouts at absolute time, rather than relative to...
authorStephan Bosch <stephan@rename-it.nl>
Tue, 30 Sep 2014 21:03:17 +0000 (00:03 +0300)
committerStephan Bosch <stephan@rename-it.nl>
Tue, 30 Sep 2014 21:03:17 +0000 (00:03 +0300)
src/lib/ioloop-private.h
src/lib/ioloop.c
src/lib/ioloop.h

index db6753de43c81f1c8c855543d3aa49af6fd0ff3f..bd81f35fcd05436d946b00607d7a3e770159fc60 100644 (file)
@@ -69,6 +69,8 @@ struct timeout {
 
        struct ioloop *ioloop;
        struct ioloop_context *ctx;
+
+       unsigned int one_shot:1;
 };
 
 struct ioloop_context_callback {
index 35e592e689189e4d3b1028b89f8da99a68e32c06..37c00e2ceab70db668de7396e09a5352ef54c469 100644 (file)
@@ -194,15 +194,14 @@ static void timeout_update_next(struct timeout *timeout, struct timeval *tv_now)
        }
 }
 
-#undef timeout_add
-struct timeout *timeout_add(unsigned int msecs, unsigned int source_linenum,
+static struct timeout *
+timeout_add_common(unsigned int source_linenum,
                            timeout_callback_t *callback, void *context)
 {
        struct timeout *timeout;
 
        timeout = i_new(struct timeout, 1);
         timeout->source_linenum = source_linenum;
-        timeout->msecs = msecs;
        timeout->ioloop = current_ioloop;
 
        timeout->callback = callback;
@@ -213,6 +212,18 @@ struct timeout *timeout_add(unsigned int msecs, unsigned int source_linenum,
                io_loop_context_ref(timeout->ctx);
        }
 
+       return timeout;
+}
+
+#undef timeout_add
+struct timeout *timeout_add(unsigned int msecs, unsigned int source_linenum,
+                           timeout_callback_t *callback, void *context)
+{
+       struct timeout *timeout;
+
+       timeout = timeout_add_common(source_linenum, callback, context);
+       timeout->msecs = msecs;
+
        timeout_update_next(timeout, timeout->ioloop->running ?
                            NULL : &ioloop_timeval);
        priorityq_add(timeout->ioloop->timeouts, &timeout->item);
@@ -227,6 +238,20 @@ timeout_add_short(unsigned int msecs, unsigned int source_linenum,
        return timeout_add(msecs, source_linenum, callback, context);
 }
 
+#undef timeout_add_absolute
+struct timeout *timeout_add_absolute(const struct timeval *time,
+                           unsigned int source_linenum,
+                           timeout_callback_t *callback, void *context)
+{
+       struct timeout *timeout;
+
+       timeout = timeout_add_common(source_linenum, callback, context);
+       timeout->one_shot = TRUE;
+
+       priorityq_add(timeout->ioloop->timeouts, &timeout->item);
+       return timeout;
+}
+
 static void timeout_free(struct timeout *timeout)
 {
        if (timeout->ctx != NULL)
@@ -407,8 +432,10 @@ static void io_loop_handle_timeouts_real(struct ioloop *ioloop)
                if (timeout_get_wait_time(timeout, &tv, &tv_call) > 0)
                        break;
 
-               /* update timeout's next_run and reposition it in the queue */
-               timeout_reset_timeval(timeout, &tv_call);
+               if (!timeout->one_shot) {
+                       /* update timeout's next_run and reposition it in the queue */
+                       timeout_reset_timeval(timeout, &tv_call);
+               }
 
                if (timeout->ctx != NULL)
                        io_loop_context_activate(timeout->ctx);
index 8cc5577a20b9c2edac9aaf924dfc8f639f74c2c4..f1f131b0e8fc243be65ef003110736449a659491 100644 (file)
@@ -97,6 +97,13 @@ timeout_add_short(unsigned int msecs, unsigned int source_linenum,
        timeout_add_short(msecs, __LINE__ + \
                CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
                (io_callback_t *)callback, context)
+struct timeout *timeout_add_absolute(const struct timeval *time,
+                           unsigned int source_linenum,
+                           timeout_callback_t *callback, void *context) ATTR_NULL(4);
+#define timeout_add_absolute(time, callback, context) \
+       timeout_add_absolute(time, __LINE__ + \
+               CALLBACK_TYPECHECK(callback, void (*)(typeof(context))), \
+               (io_callback_t *)callback, context)
 /* Remove timeout handler, and set timeout pointer to NULL. */
 void timeout_remove(struct timeout **timeout);
 /* Reset timeout so it's next run after now+msecs. */