From 78ad9b85725c2d2e5462441c0affd7eb6db3b4aa Mon Sep 17 00:00:00 2001 From: Jan Vidar Krey Date: Thu, 21 Jan 2010 22:56:07 +0100 Subject: [PATCH] Fixed bad logic inside the timer scheduling. --- src/network/epoll.c | 7 +------ src/network/select.c | 7 +------ src/network/timer.c | 2 +- src/util/timeout.c | 41 ++++++++++++++++++++++++++--------------- 4 files changed, 29 insertions(+), 28 deletions(-) diff --git a/src/network/epoll.c b/src/network/epoll.c index dd1277a..bb9055e 100644 --- a/src/network/epoll.c +++ b/src/network/epoll.c @@ -226,12 +226,7 @@ void net_con_close(struct net_connection* con_) g_backend->num--; } - if (timeout_evt_is_scheduled(con->timeout)) - { - timeout_queue_remove(&g_backend->timeout_queue, con->timeout); - hub_free(con->timeout); - con->timeout = 0; - } + net_con_clear_timeout(con_); if (epoll_ctl(g_backend->epfd, EPOLL_CTL_DEL, con->sd, &con->ev) == -1) { diff --git a/src/network/select.c b/src/network/select.c index d70acc0..6b35f64 100644 --- a/src/network/select.c +++ b/src/network/select.c @@ -195,12 +195,7 @@ void net_con_close(struct net_connection* con) g_backend->num--; } - if (timeout_evt_is_scheduled(con->timeout)) - { - timeout_queue_remove(&g_backend->timeout_queue, con->timeout); - hub_free(con->timeout); - con->timeout = 0; - } + net_con_clear_timeout(con); net_con_print("DEL", (struct net_connection_select*) con); net_cleanup_delayed_free(g_backend->cleaner, con); diff --git a/src/network/timer.c b/src/network/timer.c index 9400cb7..48911d5 100644 --- a/src/network/timer.c +++ b/src/network/timer.c @@ -41,7 +41,7 @@ void net_con_set_timeout(struct net_connection* con, int seconds) void net_con_clear_timeout(struct net_connection* con) { - if (timeout_evt_is_scheduled(con->timeout)) + if (con->timeout && timeout_evt_is_scheduled(con->timeout)) { timeout_queue_remove(net_backend_get_timeout_queue(), con->timeout); hub_free(con->timeout); diff --git a/src/util/timeout.c b/src/util/timeout.c index 6b75eb6..c728f31 100644 --- a/src/util/timeout.c +++ b/src/util/timeout.c @@ -36,7 +36,6 @@ void timeout_evt_reset(struct timeout_evt* t) int timeout_evt_is_scheduled(struct timeout_evt* t) { - if (!t) return 0; return !!t->prev; } @@ -82,16 +81,18 @@ void timeout_queue_insert(struct timeout_queue* t, struct timeout_evt* evt, size first = t->events[pos]; - if (!first) + if (first) + { + first->prev->next = evt; + evt->prev = first->prev; + first->prev = evt; + } + else { t->events[pos] = evt; evt->prev = evt; } - else - { - evt->prev = first->prev; - first->prev = evt; - } + evt->next = 0; } void timeout_queue_remove(struct timeout_queue* t, struct timeout_evt* evt) @@ -99,23 +100,33 @@ void timeout_queue_remove(struct timeout_queue* t, struct timeout_evt* evt) size_t pos = (evt->timestamp % t->max); struct timeout_evt* first = t->events[pos]; - if (!first || !evt) + if (!first || !evt->prev) return; if (first == evt) { - if (first->next) - first->next->prev = first->prev; - t->events[pos] = first->next; + if (first->prev != first) + { + t->events[pos] = first->next; + t->events[pos]->prev = evt->prev; + } + else + { + t->events[pos] = 0; + } + } + else if (evt == first->prev) + { + first->prev = evt->prev; + evt->prev->next = 0; } else { evt->prev->next = evt->next; - if (evt->next) - evt->next->prev = evt->prev; - else - first->prev = evt->prev; + evt->next->prev = evt->prev; } + evt->next = 0; + evt->prev = 0; } void timeout_queue_reschedule(struct timeout_queue* t, struct timeout_evt* evt, size_t seconds)