diff --git a/daemon/timerthread.c b/daemon/timerthread.c index 2f694523e..609a8b5b0 100644 --- a/daemon/timerthread.c +++ b/daemon/timerthread.c @@ -14,6 +14,7 @@ static void timerthread_thread_init(struct timerthread_thread *tt, struct timert mutex_init(&tt->lock); cond_init(&tt->cond); tt->parent = parent; + ZERO(tt->next_wake); } void timerthread_init(struct timerthread *tt, unsigned int num, void (*func)(void *)) { @@ -72,6 +73,7 @@ static void timerthread_run(void *p) { rtpe_now = tt_obj->next_check; ZERO(tt_obj->next_check); tt_obj->last_run = rtpe_now; + ZERO(tt->next_wake); mutex_unlock(&tt->lock); // run and release @@ -88,6 +90,7 @@ sleep:; sleeptime = MIN(10000000, sleeptime); /* 100 ms at the most */ struct timeval tv = rtpe_now; timeval_add_usec(&tv, sleeptime); + tt->next_wake = tv; cond_timedwait(&tt->cond, &tt->lock, &tv); } @@ -114,7 +117,9 @@ void timerthread_obj_schedule_abs_nl(struct timerthread_obj *tt_obj, const struc obj_hold(tt_obj); /* if it wasn't removed, we make a new reference */ tt_obj->next_check = *tv; g_tree_insert(tt->tree, tt_obj, tt_obj); - cond_signal(&tt->cond); + // need to wake the thread? + if (tt->next_wake.tv_sec && timeval_cmp(tv, &tt->next_wake) < 0) + cond_signal(&tt->cond); } void timerthread_obj_deschedule(struct timerthread_obj *tt_obj) { diff --git a/include/timerthread.h b/include/timerthread.h index 0e3c38132..58b65a34b 100644 --- a/include/timerthread.h +++ b/include/timerthread.h @@ -14,6 +14,7 @@ struct timerthread_thread { GTree *tree; // XXX investigate other structures mutex_t lock; cond_t cond; + struct timeval next_wake; }; struct timerthread {