summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefano Pigozzi <stefano.pigozzi@gmail.com>2013-08-13 14:40:17 +0200
committerStefano Pigozzi <stefano.pigozzi@gmail.com>2013-08-13 23:02:16 +0200
commit36586dd7b7ad0a9145ab28f0245a7f00227a7ce8 (patch)
tree56a6325afe86043758d560bca2b9e58e84ac021c
parent87ce0c3b8d4e7b668412315774e7ded84c4f8ad7 (diff)
downloadmpv-36586dd7b7ad0a9145ab28f0245a7f00227a7ce8.tar.bz2
mpv-36586dd7b7ad0a9145ab28f0245a7f00227a7ce8.tar.xz
input: make input queue thread safe
If pthreads are enabled the input queue accesses are regulated by acquiring a mutex. This is useful for platforms like OS X, where the events are created in the cocoa thread and added to the queue to then be dequeued in the playloop thread.
-rw-r--r--mpvcore/input/input.c41
1 files changed, 35 insertions, 6 deletions
diff --git a/mpvcore/input/input.c b/mpvcore/input/input.c
index f900b74357..ed3136a5d4 100644
--- a/mpvcore/input/input.c
+++ b/mpvcore/input/input.c
@@ -66,6 +66,16 @@
#define MP_MAX_KEY_DOWN 4
+#if HAVE_PTHREADS
+#include <pthread.h>
+static pthread_mutex_t queue_mutex = PTHREAD_MUTEX_INITIALIZER;
+#define queue_lock() pthread_mutex_lock(&queue_mutex)
+#define queue_unlock() pthread_mutex_unlock(&queue_mutex)
+#else
+#define queue_lock() 0
+#define queue_lock() 0
+#endif
+
struct cmd_bind {
int keys[MP_MAX_KEY_DOWN];
int num_keys;
@@ -653,23 +663,30 @@ bool mp_input_is_abort_cmd(int cmd_id)
static int queue_count_cmds(struct cmd_queue *queue)
{
+ queue_lock();
int res = 0;
for (struct mp_cmd *cmd = queue->first; cmd; cmd = cmd->queue_next)
res++;
+ queue_unlock();
return res;
}
static bool queue_has_abort_cmds(struct cmd_queue *queue)
{
- for (struct mp_cmd *cmd = queue->first; cmd; cmd = cmd->queue_next) {
- if (mp_input_is_abort_cmd(cmd->id))
- return true;
- }
- return false;
+ queue_lock();
+ bool ret = false;
+ for (struct mp_cmd *cmd = queue->first; cmd; cmd = cmd->queue_next)
+ if (mp_input_is_abort_cmd(cmd->id)) {
+ ret = true;
+ break;
+ }
+ queue_unlock();
+ return ret;
}
static void queue_remove(struct cmd_queue *queue, struct mp_cmd *cmd)
{
+ queue_lock();
struct mp_cmd **p_prev = &queue->first;
while (*p_prev != cmd) {
p_prev = &(*p_prev)->queue_next;
@@ -677,11 +694,13 @@ static void queue_remove(struct cmd_queue *queue, struct mp_cmd *cmd)
// if this fails, cmd was not in the queue
assert(*p_prev == cmd);
*p_prev = cmd->queue_next;
+ queue_unlock();
}
static void queue_add(struct cmd_queue *queue, struct mp_cmd *cmd,
bool at_head)
{
+ queue_lock();
if (at_head) {
cmd->queue_next = queue->first;
queue->first = cmd;
@@ -692,6 +711,16 @@ static void queue_add(struct cmd_queue *queue, struct mp_cmd *cmd,
*p_prev = cmd;
cmd->queue_next = NULL;
}
+ queue_unlock();
+}
+
+static struct mp_cmd *queue_peek(struct cmd_queue *queue)
+{
+ struct mp_cmd *ret = NULL;
+ queue_lock();
+ ret = queue->first;
+ queue_unlock();
+ return ret;
}
static struct input_fd *mp_input_add_fd(struct input_ctx *ictx)
@@ -1752,7 +1781,7 @@ mp_cmd_t *mp_input_get_cmd(struct input_ctx *ictx, int time, int peek_only)
if (repeated)
queue_add(queue, repeated, false);
}
- struct mp_cmd *ret = queue->first;
+ struct mp_cmd *ret = queue_peek(queue);
if (!ret)
return NULL;