From 34e98ea70d09195e8e047b3ea22c23506598687d Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Sun, 9 Aug 2009 09:09:54 +0200 Subject: [PATCH] [BUG] task: fix possible crash when some timeouts are not configured Cristian Ditoiu reported a major regression when testing 1.3.19 at transfer.ro. It would crash within a few minutes while 1.3.15.10 was OK. He offered to help so we could run gdb and debug the crash live. We finally found that the crash was the result of a regression introduced by recent fix 814c978fb67782ceeaf1db74abfe7083938bedff (task: fix possible timer drift after update) which makes it possible for a tree walk to start from a detached task if this task has got its timeout disabled due to a missing timeout. The trivial fix below has been extensively tested and confirmed not to crash anymore. Special thanks to Cristian who spontaneously provided a lot of help and trust to debug this issue which at first glance looked impossible after reading the code and traces, but took less than an hour to spot and fix when caught live in gdb ! That's really appreciated ! --- src/task.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/task.c b/src/task.c index 3094fde7e..268f8d9e9 100644 --- a/src/task.c +++ b/src/task.c @@ -155,9 +155,13 @@ void wake_expired_tasks(int *next) * to take care of this. Note that we might occasionally requeue it at * the same place, before , so we have to check if this happens, * and adjust , otherwise we may skip it which is not what we want. + * We may also not requeue the task (and not point eb at it) if its + * expiration time is not set. */ if (!tick_is_expired(task->expire, now_ms)) { - task_queue(task); + if (!tick_isset(task->expire)) + continue; + __task_queue(task); if (!eb || eb->key > task->wq.key) eb = &task->wq; continue;