static void *cache_thread(void *arg) { struct priv *s = arg; mpthread_set_name("cache"); pthread_mutex_lock(&s->mutex); update_cached_controls(s); double last = mp_time_sec(); while (s->control != CACHE_CTRL_QUIT) { if (mp_time_sec() - last > CACHE_UPDATE_CONTROLS_TIME) { update_cached_controls(s); last = mp_time_sec(); } if (s->control > 0) { cache_execute_control(s); } else { cache_fill(s); } if (s->control == CACHE_CTRL_PING) { pthread_cond_signal(&s->wakeup); s->control = CACHE_CTRL_NONE; } if (s->idle && s->control == CACHE_CTRL_NONE) { struct timespec ts = mp_rel_time_to_timespec(CACHE_IDLE_SLEEP_TIME); pthread_cond_timedwait(&s->wakeup, &s->mutex, &ts); } } pthread_cond_signal(&s->wakeup); pthread_mutex_unlock(&s->mutex); MP_VERBOSE(s, "Cache exiting...\n"); return NULL; }
static void *cache_thread(void *arg) { struct priv *s = arg; pthread_mutex_lock(&s->mutex); update_cached_controls(s); double last = mp_time_sec(); while (s->control != CACHE_CTRL_QUIT) { if (mp_time_sec() - last > CACHE_UPDATE_CONTROLS_TIME) { update_cached_controls(s); last = mp_time_sec(); } if (s->control > 0) { cache_execute_control(s); } else { cache_fill(s); } if (s->control == CACHE_CTRL_PING) { pthread_cond_signal(&s->wakeup); s->control = CACHE_CTRL_NONE; } if (s->idle && s->control == CACHE_CTRL_NONE) mpthread_cond_timed_wait(&s->wakeup, &s->mutex, CACHE_IDLE_SLEEP_TIME); } pthread_cond_signal(&s->wakeup); pthread_mutex_unlock(&s->mutex); mp_msg(MSGT_CACHE, MSGL_V, "Cache exiting...\n"); return NULL; }
// Runs in the cache thread static void cache_execute_control(struct priv *s) { uint64_t old_pos = stream_tell(s->stream); s->control_flush = false; switch (s->control) { case STREAM_CTRL_SET_CACHE_SIZE: s->control_res = resize_cache(s, *(int64_t *)s->control_arg); break; default: s->control_res = stream_control(s->stream, s->control, s->control_arg); } bool pos_changed = old_pos != stream_tell(s->stream); bool ok = s->control_res == STREAM_OK; if (pos_changed && !ok) { MP_ERR(s, "STREAM_CTRL changed stream pos but " "returned error, this is not allowed!\n"); } else if (pos_changed || (ok && control_needs_flush(s->control))) { MP_VERBOSE(s, "Dropping cache due to control()\n"); s->read_filepos = stream_tell(s->stream); s->control_flush = true; cache_drop_contents(s); } update_cached_controls(s); s->control = CACHE_CTRL_NONE; pthread_cond_signal(&s->wakeup); }