From 56aa9b9efa1c6f1d34fd1e852d427b7831e339e1 Mon Sep 17 00:00:00 2001
From: Russell Bryant <russell@russellbryant.com>
Date: Wed, 7 May 2008 21:11:33 +0000
Subject: [PATCH] Fix up a problem that was introduced into the scheduler when
 it was converted to use doubly linked lists.  The schedule() function had an
 optimization that had it try to guess which direction would be better for the
 traversal to insert the task into the scheduler queue.  However, if the code
 chose the path where it traversed the queue in reverse, and the result was
 that the task should be at the head of the queue, then the code would
 actually put it at the tail, instead.

(Problem found by bbryant, debugged and fixed by bbryant and me)


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@115537 65c4cc65-6c06-0410-ace0-fbb531ad65f3
---
 main/sched.c | 19 +++++++++++++++----
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/main/sched.c b/main/sched.c
index d877417b63..64ef413eab 100644
--- a/main/sched.c
+++ b/main/sched.c
@@ -198,34 +198,45 @@ static void schedule(struct sched_context *con, struct sched *s)
 	int de = 0;
 	struct sched *first = AST_DLLIST_FIRST(&con->schedq);
 	struct sched *last = AST_DLLIST_LAST(&con->schedq);
+
 	if (first)
 		df = ast_tvdiff_us(s->when, first->when);
 	if (last)
 		de = ast_tvdiff_us(s->when, last->when);
+
 	if (df < 0)
 		df = -df;
 	if (de < 0)
 		de = -de;
-	if (df < de)
+
+	if (df < de) {
 		AST_DLLIST_TRAVERSE(&con->schedq, cur, list) {
 			if (ast_tvcmp(s->when, cur->when) == -1) {
 				AST_DLLIST_INSERT_BEFORE(&con->schedq, cur, s, list);
 				break;
 			}
 		}
-	else
+		if (!cur) {
+			AST_DLLIST_INSERT_TAIL(&con->schedq, s, list);
+		}
+	} else {
 		AST_DLLIST_TRAVERSE_BACKWARDS(&con->schedq, cur, list) {
 			if (ast_tvcmp(s->when, cur->when) == 1) {
 				AST_DLLIST_INSERT_AFTER(&con->schedq, cur, s, list);
 				break;
 			}
 		}
-	if (!cur)
-		AST_DLLIST_INSERT_TAIL(&con->schedq, s, list);
+		if (!cur) {
+			AST_DLLIST_INSERT_HEAD(&con->schedq, s, list);
+		}
+	}
+
 	ret = ast_hashtab_insert_safe(con->schedq_ht, s);
 	if (!ret)
 		ast_log(LOG_WARNING,"Schedule Queue entry %d is already in table!\n",s->id);
+
 	con->schedcnt++;
+
 	if (con->schedcnt > con->highwater)
 		con->highwater = con->schedcnt;
 }
-- 
GitLab