static void * mtimer_thread(void *aux) { mtimer_t *mti; mti_callback_t *cb; int64_t now, next; #if ENABLE_GTIMER_CHECK int64_t mtm; const char *id; const char *fcn; #endif 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 mtm = getmonoclock(); id = mti->mti_id; fcn = mti->mti_fcn; #endif cb = mti->mti_callback; LIST_REMOVE(mti, mti_link); mti->mti_callback = NULL; cb(mti->mti_opaque); #if ENABLE_GTIMER_CHECK mtm = getmonoclock() - mtm; if (mtm > 10000) tvhtrace("mtimer", "%s:%s duration %"PRId64"us", id, fcn, mtm); #endif } /* 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 * 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; }
/* * Read thread */ static void * iptv_file_thread ( void *aux ) { iptv_mux_t *im = aux; file_priv_t *fp = im->im_data; ssize_t r; int fd = fp->fd, pause = 0; char buf[32*1024]; off_t off = 0; int64_t mono; int e; #if defined(PLATFORM_DARWIN) fcntl(fd, F_NOCACHE, 1); #endif pthread_mutex_lock(&iptv_lock); while (!fp->shutdown && fd > 0) { while (!fp->shutdown && pause) { mono = mclk() + sec2mono(1); do { e = tvh_cond_timedwait(&fp->cond, &iptv_lock, mono); if (e == ETIMEDOUT) break; } while (ERRNO_AGAIN(e)); } if (fp->shutdown) break; pause = 0; pthread_mutex_unlock(&iptv_lock); r = read(fd, buf, sizeof(buf)); pthread_mutex_lock(&iptv_lock); if (r == 0) break; if (r < 0) { if (ERRNO_AGAIN(errno)) continue; break; } sbuf_append(&im->mm_iptv_buffer, buf, r); if (iptv_input_recv_packets(im, r) == 1) pause = 1; #ifndef PLATFORM_DARWIN #if !ENABLE_ANDROID posix_fadvise(fd, off, r, POSIX_FADV_DONTNEED); #endif #endif off += r; } pthread_mutex_unlock(&iptv_lock); return NULL; }
static void * tvhdhomerun_device_discovery_thread( void *aux ) { struct hdhomerun_discover_device_t result_list[MAX_HDHOMERUN_DEVICES]; int numDevices, brk; while (tvheadend_is_running()) { numDevices = hdhomerun_discover_find_devices_custom(0, HDHOMERUN_DEVICE_TYPE_TUNER, HDHOMERUN_DEVICE_ID_WILDCARD, result_list, MAX_HDHOMERUN_DEVICES); if (numDevices > 0) { while (numDevices > 0 ) { numDevices--; struct hdhomerun_discover_device_t* cDev = &result_list[numDevices]; if ( cDev->device_type == HDHOMERUN_DEVICE_TYPE_TUNER ) { pthread_mutex_lock(&global_lock); tvhdhomerun_device_t *existing = tvhdhomerun_device_find(cDev->device_id); if ( tvheadend_is_running() ) { if ( !existing ) { tvhinfo(LS_TVHDHOMERUN,"Found HDHomerun device %08x with %d tuners", cDev->device_id, cDev->tuner_count); tvhdhomerun_device_create(cDev); } else if ( ((struct sockaddr_in *)&existing->hd_info.ip_address)->sin_addr.s_addr != htonl(cDev->ip_addr) ) { struct sockaddr_storage detected_dev_addr; memset(&detected_dev_addr, 0, sizeof(detected_dev_addr)); detected_dev_addr.ss_family = AF_INET; ((struct sockaddr_in *)&detected_dev_addr)->sin_addr.s_addr = htonl(cDev->ip_addr); char existing_ip[64]; tcp_get_str_from_ip(&existing->hd_info.ip_address, existing_ip, sizeof(existing_ip)); char detected_ip[64]; tcp_get_str_from_ip(&detected_dev_addr, detected_ip, sizeof(detected_ip)); tvhinfo(LS_TVHDHOMERUN,"HDHomerun device %08x switched IPs from %s to %s, updating", cDev->device_id, existing_ip, detected_ip); tvhdhomerun_device_destroy(existing); tvhdhomerun_device_create(cDev); } } pthread_mutex_unlock(&global_lock); } } } pthread_mutex_lock(&tvhdhomerun_discovery_lock); brk = 0; if (tvheadend_is_running()) { brk = tvh_cond_timedwait(&tvhdhomerun_discovery_cond, &tvhdhomerun_discovery_lock, mclk() + sec2mono(15)); brk = !ERRNO_AGAIN(brk) && brk != ETIMEDOUT; } pthread_mutex_unlock(&tvhdhomerun_discovery_lock); if (brk) break; } return NULL; }