aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar wm4 <wm4@nowhere>2016-03-10 00:06:13 +0100
committerGravatar wm4 <wm4@nowhere>2016-03-10 00:08:04 +0100
commitd8b27ee4de4e26d594855960a4421b99db9e76ea (patch)
treea0e4131f77c36439902c590795688171c0f24edd
parent953ff6b3908bcfdd69a9189c991e55f362d2d2dc (diff)
demux: remove pausing mechanism
This is simpler, because it doesn't have to wait from both threads for synchronization. Apart from being simpler/cleaner, this serves vague plans to stop/start the demuxer thread itself automatically on demand (for the purpose of reducing unneeded resource usage).
-rw-r--r--demux/demux.c65
1 files changed, 22 insertions, 43 deletions
diff --git a/demux/demux.c b/demux/demux.c
index 2770413938..fe23d0ac02 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -93,15 +93,13 @@ struct demux_internal {
struct demuxer *d_buffer; // protected by lock; used to sync d_user/thread
// The lock protects the packet queues (struct demux_stream), d_buffer,
- // and some minor fields like thread_paused.
+ // and the fields below.
pthread_mutex_t lock;
pthread_cond_t wakeup;
pthread_t thread;
// -- All the following fields are protected by lock.
- bool thread_paused;
- int thread_request_pause; // counter, if >0, make demuxer thread pause
bool thread_terminate;
bool threading;
void (*wakeup_cb)(void *ctx);
@@ -132,6 +130,9 @@ struct demux_internal {
double ts_offset; // timestamp offset to apply everything
+ void (*run_fn)(void *); // if non-NULL, function queued to be run on
+ void *run_fn_arg; // the thread as run_fn(run_fn_arg)
+
// Cached state.
bool force_cache_update;
double time_length;
@@ -633,10 +634,10 @@ static void *demux_thread(void *pctx)
mpthread_set_name("demux");
pthread_mutex_lock(&in->lock);
while (!in->thread_terminate) {
- in->thread_paused = in->thread_request_pause > 0;
- if (in->thread_paused) {
+ if (in->run_fn) {
+ in->run_fn(in->run_fn_arg);
+ in->run_fn = NULL;
pthread_cond_signal(&in->wakeup);
- pthread_cond_wait(&in->wakeup, &in->lock);
continue;
}
if (in->tracks_switched) {
@@ -1593,47 +1594,25 @@ int demux_stream_control(demuxer_t *demuxer, int ctrl, void *arg)
return c.res;
}
-// Make the demuxer thread stop doing anything.
-// demux_unpause() wakes up the thread again.
-// Can be nested with other calls, but trying to read packets may deadlock.
-static void demux_pause(demuxer_t *demuxer)
-{
- struct demux_internal *in = demuxer->in;
- assert(demuxer == in->d_user);
-
- if (!in->threading)
- return;
-
- MP_VERBOSE(in, "pause demux thread\n");
-
- pthread_mutex_lock(&in->lock);
- in->thread_request_pause++;
- pthread_cond_signal(&in->wakeup);
- while (!in->thread_paused)
- pthread_cond_wait(&in->wakeup, &in->lock);
- pthread_mutex_unlock(&in->lock);
-}
-
-static void demux_unpause(demuxer_t *demuxer)
+void demux_run_on_thread(struct demuxer *demuxer, void (*fn)(void *), void *ctx)
{
struct demux_internal *in = demuxer->in;
assert(demuxer == in->d_user);
- if (!in->threading)
- return;
-
- pthread_mutex_lock(&in->lock);
- assert(in->thread_request_pause > 0);
- in->thread_request_pause--;
- pthread_cond_signal(&in->wakeup);
- pthread_mutex_unlock(&in->lock);
-}
-
-void demux_run_on_thread(struct demuxer *demuxer, void (*fn)(void *), void *ctx)
-{
- demux_pause(demuxer);
- fn(ctx);
- demux_unpause(demuxer);
+ if (in->threading) {
+ MP_VERBOSE(in, "blocking on demuxer thread\n");
+ pthread_mutex_lock(&in->lock);
+ while (in->run_fn)
+ pthread_cond_wait(&in->wakeup, &in->lock);
+ in->run_fn = fn;
+ in->run_fn_arg = ctx;
+ pthread_cond_signal(&in->wakeup);
+ while (in->run_fn)
+ pthread_cond_wait(&in->wakeup, &in->lock);
+ pthread_mutex_unlock(&in->lock);
+ } else {
+ fn(ctx);
+ }
}
bool demux_cancel_test(struct demuxer *demuxer)