diff options
author | Oliver Freyermuth <o.freyermuth@googlemail.com> | 2016-01-08 18:37:30 +0100 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2016-01-14 00:36:53 +0100 |
commit | c55b242b4ee89e91b4f9896e214c3bbe0ed46ea1 (patch) | |
tree | 49f7fa336fad5d906dc602d0465b95c2b0c04785 /stream/stream_dvb.c | |
parent | 1e46bda0f86d9d58c38135c7b9ddbb6dbb7c3572 (diff) | |
download | mpv-c55b242b4ee89e91b4f9896e214c3bbe0ed46ea1.tar.bz2 mpv-c55b242b4ee89e91b4f9896e214c3bbe0ed46ea1.tar.xz |
stream_dvb: global protection mutex and usage bit for global_dvb_state.
The mutex is used in dvbin_open and dvbin_close only since these are
the only entry / exit points to the stream.
When opening, it is first checked (mutexed) whether the state already exists
and is in use, then a STREAM_ERROR is returned,
since there may be only one stream_dvb active at a time.
State-creation itself is also protected by mutex.
In dvbin_close, the usage-bit is set to false (mutexed) in case
of channel switch.
In case of stream-teardown, the state is destructed
(also protected by mutex).
Diffstat (limited to 'stream/stream_dvb.c')
-rw-r--r-- | stream/stream_dvb.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/stream/stream_dvb.c b/stream/stream_dvb.c index 3f13828a5f..450f8500d0 100644 --- a/stream/stream_dvb.c +++ b/stream/stream_dvb.c @@ -40,6 +40,7 @@ #include <unistd.h> #include <fcntl.h> #include <errno.h> +#include <pthread.h> #include <libavutil/avstring.h> @@ -63,6 +64,7 @@ #define OPT_BASE_STRUCT struct dvb_params static dvb_state_t* global_dvb_state = NULL; +static pthread_mutex_t global_dvb_state_lock = PTHREAD_MUTEX_INITIALIZER; /// URL definition static const m_option_t stream_params[] = { @@ -820,9 +822,13 @@ static void dvbin_close(stream_t *stream) { dvb_priv_t *priv = (dvb_priv_t *) stream->priv; dvb_state_t* state = priv->state; + if (state->switching_channel && state->is_on) { // Prevent state destruction, reset channel-switch. state->switching_channel = false; + pthread_mutex_lock(&global_dvb_state_lock); + global_dvb_state->stream_used = false; + pthread_mutex_unlock(&global_dvb_state_lock); return; } @@ -838,8 +844,11 @@ static void dvbin_close(stream_t *stream) state->fe_fd = state->dvr_fd = -1; state->is_on = 0; + + pthread_mutex_lock(&global_dvb_state_lock); dvb_free_state(state); global_dvb_state = NULL; + pthread_mutex_unlock(&global_dvb_state_lock); } static int dvb_streaming_start(stream_t *stream, int tuner_type, char *progname) @@ -897,7 +906,17 @@ static int dvb_open(stream_t *stream) char *progname; int tuner_type = 0, i; + pthread_mutex_lock(&global_dvb_state_lock); + if (global_dvb_state && global_dvb_state->stream_used) { + MP_ERR(stream, "DVB stream already in use, only one DVB stream can exist at a time!"); + pthread_mutex_unlock(&global_dvb_state_lock); + return STREAM_ERROR; + } + dvb_state_t* state = dvb_get_state(stream); + state->stream_used = true; + pthread_mutex_unlock(&global_dvb_state_lock); + priv->state = state; if (state == NULL) { MP_ERR(stream, "DVB CONFIGURATION IS EMPTY, exit\n"); @@ -982,6 +1001,7 @@ dvb_state_t *dvb_get_state(stream_t *stream) state->count = 0; state->switching_channel = false; + state->stream_used = true; state->cards = NULL; state->fe_fd = state->dvr_fd = -1; for (int i = 0; i < MAX_CARDS; i++) { @@ -1073,7 +1093,6 @@ dvb_state_t *dvb_get_state(stream_t *stream) } global_dvb_state = state; - return state; } |