aboutsummaryrefslogtreecommitdiffstats
path: root/main/sched.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-05-07 21:11:33 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2008-05-07 21:11:33 +0000
commit6a3cb06cc04e46106199a684f6964138c52b278d (patch)
tree00ec8dd5212d50dc50276768ea9f6c2f7c203dc9 /main/sched.c
parent2c0065d862ffa9a8320a4df37ac6891c9fc36fb8 (diff)
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: http://svn.digium.com/svn/asterisk/trunk@115537 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'main/sched.c')
-rw-r--r--main/sched.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/main/sched.c b/main/sched.c
index d877417b6..64ef413ea 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;
}