]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[MAJOR] fixed some expiration dates on tasks
authorWilly Tarreau <w@1wt.eu>
Tue, 8 May 2007 22:54:10 +0000 (00:54 +0200)
committerWilly Tarreau <w@1wt.eu>
Tue, 8 May 2007 22:54:10 +0000 (00:54 +0200)
The time subsystem really needs fixing. It was still possible
that some tasks with expiration date below the millisecond in
the future caused busy loop around poll() waiting for the
timeout to happen.

src/checks.c
src/task.c

index ec56453a54f76ab75ba4976ac5af6b9ad50aec2e..83a539eea1b02c4c875e15545ea5e4316ae01fb8 100644 (file)
@@ -277,9 +277,11 @@ static int event_srv_chk_r(int fd)
  */
 int process_chk(struct task *t)
 {
+       __label__ new_chk, out;
        struct server *s = t->context;
        struct sockaddr_in sa;
        int fd;
+       int next_time;
 
        //fprintf(stderr, "process_chk: task=%p\n", t);
 
@@ -289,7 +291,8 @@ int process_chk(struct task *t)
                //fprintf(stderr, "process_chk: 2\n");
                if (!tv_ms_le2(&t->expire, &now)) { /* not good time yet */
                        task_queue(t);  /* restore t to its place in the task list */
-                       return tv_ms_remain2(&now, &t->expire);
+                       next_time = tv_ms_remain2(&now, &t->expire);
+                       goto out;
                }
 
                /* we don't send any health-checks when the proxy is stopped or when
@@ -299,7 +302,8 @@ int process_chk(struct task *t)
                        while (tv_ms_le2(&t->expire, &now))
                                tv_ms_add(&t->expire, &t->expire, s->inter);
                        task_queue(t);  /* restore t to its place in the task list */
-                       return tv_ms_remain2(&now, &t->expire);
+                       next_time = tv_ms_remain2(&now, &t->expire);
+                       goto out;
                }
 
                /* we'll initiate a new check */
@@ -508,7 +512,12 @@ int process_chk(struct task *t)
        //fprintf(stderr, "process_chk: 11\n");
        s->result = 0;
        task_queue(t);  /* restore t to its place in the task list */
-       return tv_ms_remain2(&now, &t->expire);
+       next_time = tv_ms_remain2(&now, &t->expire);
+ out:
+       /* Ensure that we don't report sub-millisecond timeouts */
+       if (next_time != TIME_ETERNITY)
+               next_time++;
+       return next_time;
 }
 
 
index d236d9fdc7ec023fe3c1b911cd0281cfe87f2247..89055812848cbf31decede2025f17a1043246c37 100644 (file)
@@ -88,6 +88,7 @@ struct task *task_queue(struct task *task)
  */
 int wake_expired_tasks()
 {
+       __label__ out;
        int slen;
        struct task *task;
        void *data;
@@ -100,8 +101,10 @@ int wake_expired_tasks()
 
        if (likely(timer_wq.data != NULL)) {
                task = LIST_ELEM(timer_wq.data, struct task *, qlist);
-               if (likely(__tv_isge(&task->expire, &now) > 0))
-                       return tv_ms_remain(&now, &task->expire);
+               if (likely(__tv_isge(&task->expire, &now) > 0)) {
+                       next_time = tv_ms_remain(&now, &task->expire);
+                       goto out;
+               }
        }
 
        /* OK we lose. Let's scan the tree then. */
@@ -127,6 +130,10 @@ int wake_expired_tasks()
                        task->state = TASK_RUNNING;
                }
        }
+ out:
+       /* Ensure that we don't report sub-millisecond timeouts */
+       if (next_time != TIME_ETERNITY)
+               next_time++;
        return next_time;
 }