static void mainloop(void) { gtimer_t *gti; gti_callback_t *cb; while(running) { sleep(1); spawn_reaper(); time(&dispatch_clock); comet_flush(); /* Flush idle comet mailboxes */ pthread_mutex_lock(&global_lock); while((gti = LIST_FIRST(>imers)) != NULL) { if(gti->gti_expire > dispatch_clock) break; cb = gti->gti_callback; LIST_REMOVE(gti, gti_link); gti->gti_callback = NULL; cb(gti->gti_opaque); } pthread_mutex_unlock(&global_lock); } }
static void mainloop(void) { gtimer_t *gti; gti_callback_t *cb; struct timespec ts; while(tvheadend_running) { clock_gettime(CLOCK_REALTIME, &ts); /* 1sec stuff */ if (ts.tv_sec > dispatch_clock) { dispatch_clock = ts.tv_sec; comet_flush(); /* Flush idle comet mailboxes */ } /* Global timers */ pthread_mutex_lock(&global_lock); // TODO: there is a risk that if timers re-insert themselves to // the top of the list with a 0 offset we could loop indefinitely #if 0 tvhdebug("gtimer", "now %ld.%09ld", ts.tv_sec, ts.tv_nsec); LIST_FOREACH(gti, >imers, gti_link) tvhdebug("gtimer", " gti %p expire %ld.%08ld", gti, gti->gti_expire.tv_sec, gti->gti_expire.tv_nsec); #endif while((gti = LIST_FIRST(>imers)) != NULL) { if ((gti->gti_expire.tv_sec > ts.tv_sec) || ((gti->gti_expire.tv_sec == ts.tv_sec) && (gti->gti_expire.tv_nsec > ts.tv_nsec))) { ts = gti->gti_expire; break; } cb = gti->gti_callback; //tvhdebug("gtimer", "%p callback", gti); LIST_REMOVE(gti, gti_link); gti->gti_callback = NULL; cb(gti->gti_opaque); } /* Bound wait */ if ((LIST_FIRST(>imers) == NULL) || (ts.tv_sec > (dispatch_clock + 1))) { ts.tv_sec = dispatch_clock + 1; ts.tv_nsec = 0; } /* Wait */ //tvhdebug("gtimer", "wait till %ld.%09ld", ts.tv_sec, ts.tv_nsec); pthread_cond_timedwait(>imer_cond, &global_lock, &ts); pthread_mutex_unlock(&global_lock); } }
static int64_t mdispatch_clock_update(void) { int64_t mono = getmonoclock(); if (mono > atomic_get_s64(&mtimer_periodic)) { atomic_set_s64(&mtimer_periodic, mono + MONOCLOCK_RESOLUTION); gdispatch_clock_update(); /* gclk() update */ comet_flush(); /* Flush idle comet mailboxes */ } atomic_set_s64(&__mdispatch_clock, mono); return mono; }
time_t dispatch_clock_update(struct timespec *ts) { struct timespec ts1; if (ts == NULL) ts = &ts1; clock_gettime(CLOCK_REALTIME, ts); /* 1sec stuff */ if (ts->tv_sec > dispatch_clock) { dispatch_clock = ts->tv_sec; comet_flush(); /* Flush idle comet mailboxes */ } return dispatch_clock; }
static void mainloop(void) { gtimer_t *gti; gti_callback_t *cb; struct timespec ts; #if ENABLE_GTIMER_CHECK int64_t mtm; const char *id; const char *fcn; #endif while(tvheadend_running) { clock_gettime(CLOCK_REALTIME, &ts); /* 1sec stuff */ if (ts.tv_sec > dispatch_clock) { dispatch_clock = ts.tv_sec; comet_flush(); /* Flush idle comet mailboxes */ } /* Global timers */ pthread_mutex_lock(&global_lock); // TODO: there is a risk that if timers re-insert themselves to // the top of the list with a 0 offset we could loop indefinitely #if 0 tvhdebug("gtimer", "now %ld.%09ld", ts.tv_sec, ts.tv_nsec); LIST_FOREACH(gti, >imers, gti_link) tvhdebug("gtimer", " gti %p expire %ld.%08ld", gti, gti->gti_expire.tv_sec, gti->gti_expire.tv_nsec); #endif while((gti = LIST_FIRST(>imers)) != NULL) { if ((gti->gti_expire.tv_sec > ts.tv_sec) || ((gti->gti_expire.tv_sec == ts.tv_sec) && (gti->gti_expire.tv_nsec > ts.tv_nsec))) { ts = gti->gti_expire; break; } #if ENABLE_GTIMER_CHECK mtm = getmonoclock(); id = gti->gti_id; fcn = gti->gti_fcn; #endif cb = gti->gti_callback; LIST_REMOVE(gti, gti_link); gti->gti_callback = NULL; cb(gti->gti_opaque); #if ENABLE_GTIMER_CHECK tvhtrace("gtimer", "%s:%s duration %"PRId64"ns", id, fcn, getmonoclock() - mtm); #endif } /* Bound wait */ if ((LIST_FIRST(>imers) == NULL) || (ts.tv_sec > (dispatch_clock + 1))) { ts.tv_sec = dispatch_clock + 1; ts.tv_nsec = 0; } /* Wait */ pthread_cond_timedwait(>imer_cond, &global_lock, &ts); pthread_mutex_unlock(&global_lock); } }