void *timeshift_writer ( void *aux ) { int run = 1; timeshift_t *ts = aux; streaming_queue_t *sq = &ts->wr_queue; streaming_message_t *sm; pthread_mutex_lock(&sq->sq_mutex); while (run) { /* Get message */ sm = TAILQ_FIRST(&sq->sq_queue); if (sm == NULL) { tvh_cond_wait(&sq->sq_cond, &sq->sq_mutex); continue; } streaming_queue_remove(sq, sm); pthread_mutex_unlock(&sq->sq_mutex); _process_msg(ts, sm, &run); pthread_mutex_lock(&sq->sq_mutex); } pthread_mutex_unlock(&sq->sq_mutex); return NULL; }
static void * mtimer_thread(void *aux) { mtimer_t *mti; mti_callback_t *cb; int64_t now, next; const char *id; pthread_mutex_lock(&global_lock); while (tvheadend_is_running() && atomic_get(&tvheadend_mainloop) == 0) tvh_cond_wait(&mtimer_cond, &global_lock); pthread_mutex_unlock(&global_lock); while (tvheadend_is_running()) { now = mdispatch_clock_update(); /* Global monoclock timers */ pthread_mutex_lock(&global_lock); next = now + sec2mono(3600); while((mti = LIST_FIRST(&mtimers)) != NULL) { if (mti->mti_expire > now) { next = mti->mti_expire; break; } #if ENABLE_GTIMER_CHECK id = mti->mti_id; #else id = NULL; #endif tprofile_start(&mtimer_profile, id); cb = mti->mti_callback; LIST_REMOVE(mti, mti_link); mti->mti_callback = NULL; cb(mti->mti_opaque); tprofile_finish(&mtimer_profile); } /* Periodic updates */ if (next > mtimer_periodic) next = mtimer_periodic; /* Wait */ tvh_cond_timedwait(&mtimer_cond, &global_lock, next); pthread_mutex_unlock(&global_lock); } return NULL; }
static void * tasklet_thread ( void *aux ) { tasklet_t *tsk; tsk_callback_t *tsk_cb; void *opaque; tvhthread_renice(20); pthread_mutex_lock(&tasklet_lock); while (tvheadend_is_running()) { tsk = TAILQ_FIRST(&tasklets); if (tsk == NULL) { tvh_cond_wait(&tasklet_cond, &tasklet_lock); continue; } /* the callback might re-initialize tasklet, save everything */ TAILQ_REMOVE(&tasklets, tsk, tsk_link); tsk_cb = tsk->tsk_callback; opaque = tsk->tsk_opaque; tsk->tsk_callback = NULL; if (tsk->tsk_free) { memoryinfo_free(&tasklet_memoryinfo, sizeof(*tsk)); tsk->tsk_free(tsk); } /* now, the callback can be safely called */ if (tsk_cb) { pthread_mutex_unlock(&tasklet_lock); tsk_cb(opaque, 0); pthread_mutex_lock(&tasklet_lock); } } pthread_mutex_unlock(&tasklet_lock); return NULL; }