fix timers so that they work when theres lots of repeating timers in the queue..

This commit is contained in:
Dana Jansens 2008-01-16 00:54:17 -05:00
parent ba6dcc15f8
commit ff78d28f8b
2 changed files with 8 additions and 22 deletions

View file

@ -504,10 +504,8 @@ void ob_main_loop_fd_remove(ObMainLoop *loop,
static glong timecompare(GTimeVal *a, GTimeVal *b) static glong timecompare(GTimeVal *a, GTimeVal *b)
{ {
glong r; glong r;
if ((r = a->tv_sec - b->tv_sec)) return r;
if ((r = b->tv_sec - a->tv_sec)) return r; return a->tv_usec - b->tv_usec;
return b->tv_usec - a->tv_usec;
} }
static void insert_timer(ObMainLoop *loop, ObMainLoopTimer *ins) static void insert_timer(ObMainLoop *loop, ObMainLoopTimer *ins)
@ -515,7 +513,7 @@ static void insert_timer(ObMainLoop *loop, ObMainLoopTimer *ins)
GSList *it; GSList *it;
for (it = loop->timers; it; it = g_slist_next(it)) { for (it = loop->timers; it; it = g_slist_next(it)) {
ObMainLoopTimer *t = it->data; ObMainLoopTimer *t = it->data;
if (timecompare(&ins->timeout, &t->timeout) >= 0) { if (timecompare(&ins->timeout, &t->timeout) <= 0) {
loop->timers = g_slist_insert_before(loop->timers, it, ins); loop->timers = g_slist_insert_before(loop->timers, it, ins);
break; break;
} }
@ -562,11 +560,9 @@ void ob_main_loop_timeout_remove_data(ObMainLoop *loop, GSourceFunc handler,
{ {
GSList *it; GSList *it;
ob_debug("removing data 0x%x\n", data);
for (it = loop->timers; it; it = g_slist_next(it)) { for (it = loop->timers; it; it = g_slist_next(it)) {
ObMainLoopTimer *t = it->data; ObMainLoopTimer *t = it->data;
if (t->func == handler && t->equal(t->data, data)) { if (t->func == handler && t->equal(t->data, data)) {
ob_debug("found data 0x%x\n", data);
t->del_me = TRUE; t->del_me = TRUE;
if (cancel_dest) if (cancel_dest)
t->destroy = NULL; t->destroy = NULL;
@ -603,12 +599,6 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait)
g_get_current_time(&loop->now); g_get_current_time(&loop->now);
/* do this first, cuz the list can get reordered */
for (it = loop->timers; it; it = g_slist_next(it)) {
ObMainLoopTimer *curr = it->data;
curr->fired = FALSE;
}
for (it = loop->timers; it; it = next) { for (it = loop->timers; it; it = next) {
ObMainLoopTimer *curr; ObMainLoopTimer *curr;
@ -630,15 +620,9 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait)
/* the queue is sorted, so if this timer shouldn't fire, none are /* the queue is sorted, so if this timer shouldn't fire, none are
ready */ ready */
if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) < 0) if (timecompare(&NEAREST_TIMEOUT(loop), &loop->now) > 0)
break; break;
/* don't let it fire again this time around. otherwise, if the first
timer in the queue becomes ready, we'll loop on the later ones
forever if they repeat */
if (curr->fired)
continue;
/* we set the last fired time to delay msec after the previous firing, /* we set the last fired time to delay msec after the previous firing,
then re-insert. timers maintain their order and may trigger more then re-insert. timers maintain their order and may trigger more
than once if they've waited more than one delay's worth of time. than once if they've waited more than one delay's worth of time.
@ -654,7 +638,10 @@ static void timer_dispatch(ObMainLoop *loop, GTimeVal **wait)
g_free(curr); g_free(curr);
} }
curr->fired = TRUE; /* the timer queue has been shuffled, start from the beginning
(which is the next one to fire) */
next = loop->timers;
fired = TRUE; fired = TRUE;
} }

View file

@ -108,7 +108,6 @@ static void ping_send(ObPingTarget *t)
{ {
t->sent = event_get_server_time(); t->sent = event_get_server_time();
/*ob_debug("PING: '%s' (timestamp %lu)\n", t->client->title, t->sent);*/ /*ob_debug("PING: '%s' (timestamp %lu)\n", t->client->title, t->sent);*/
ob_debug("PINGing client %s at %lu\n", t->client->title, t->sent);
PROP_MSG_TO(t->client->window, t->client->window, wm_protocols, PROP_MSG_TO(t->client->window, t->client->window, wm_protocols,
prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0, prop_atoms.net_wm_ping, t->sent, t->client->window, 0, 0,
NoEventMask); NoEventMask);