]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] task: fix possible timer drift after update
authorWilly Tarreau <w@1wt.eu>
Tue, 14 Jul 2009 21:48:55 +0000 (23:48 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 14 Jul 2009 21:48:55 +0000 (23:48 +0200)
When the scheduler detected that a task was misplaced in the timer
queue, it used to place it right again. Unfortunately, it did not
check whether it would still call the new task from its new place.
This resulted in some tasks not getting called on timeout once in
a while, causing a minor drift for repetitive timers. This effect
was only observable with slow health checks and without any activity
because no other task would cause the scheduler to be immediately
called again.

In practice, it does not affect any real-world configuration, but
it's still better to fix it.

src/task.c

index 5336c20e9db6ad1a845eb8221df2adcbe3b08cc4..3094fde7efbeb55f0bccc213d4a25faa67dc28b6 100644 (file)
@@ -152,10 +152,14 @@ void wake_expired_tasks(int *next)
                 * lot cheaper to proceed like this because we almost never update
                 * the tree. We may also find disabled expiration dates there. Since
                 * we have detached the task from the tree, we simply call task_queue
-                * to take care of this.
+                * to take care of this. Note that we might occasionally requeue it at
+                * the same place, before <eb>, so we have to check if this happens,
+                * and adjust <eb>, otherwise we may skip it which is not what we want.
                 */
                if (!tick_is_expired(task->expire, now_ms)) {
                        task_queue(task);
+                       if (!eb || eb->key > task->wq.key)
+                               eb = &task->wq;
                        continue;
                }
                task_wakeup(task, TASK_WOKEN_TIMER);