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 * spawn_pipe_thread(void *aux) { tvhpoll_event_t ev[2]; tvhpoll_t *efd = tvhpoll_create(2); int nfds; memset(ev, 0, sizeof(ev)); ev[0].events = TVHPOLL_IN; ev[0].fd = spawn_pipe_info.rd; ev[0].data.ptr = &spawn_pipe_info; ev[1].events = TVHPOLL_IN; ev[1].fd = spawn_pipe_error.rd; ev[1].data.ptr = &spawn_pipe_error; tvhpoll_add(efd, ev, 2); while (spawn_pipe_running) { nfds = tvhpoll_wait(efd, ev, 2, 500); if (nfds > 0) { spawn_pipe_read(&spawn_pipe_info, &spawn_info_buf, LOG_INFO); spawn_pipe_read(&spawn_pipe_error, &spawn_error_buf, LOG_ERR); } spawn_reaper(); } tvhpoll_destroy(efd); return NULL; }
/** * Kill the pid (only if waiting) */ int spawn_kill(pid_t pid, int sig) { int r = -ESRCH; spawn_t *s; if (pid > 0) { spawn_reaper(); pthread_mutex_lock(&spawn_mutex); LIST_FOREACH(s, &spawns, link) if(s->pid == pid) break; if (s) { r = kill(pid, sig); if (r < 0) r = -errno; } pthread_mutex_unlock(&spawn_mutex); }
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; spawn_reaper(); /* reap spawned processes */ 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); } }