}
}
-#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;
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);
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)
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);
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. */