summaryrefslogtreecommitdiffstats
path: root/input/pipe.c
diff options
context:
space:
mode:
authorwm4 <wm4@nowhere>2014-09-14 16:21:04 +0200
committerwm4 <wm4@nowhere>2014-09-14 16:24:01 +0200
commite0b4daf3ad240ecf70af73c13b6ca9b1062a507f (patch)
treee52d79650aa69c0288dd5d9c896ab943c692f88f /input/pipe.c
parentb44571ababeb368e94df6665c1d370d817a51135 (diff)
downloadmpv-e0b4daf3ad240ecf70af73c13b6ca9b1062a507f.tar.bz2
mpv-e0b4daf3ad240ecf70af73c13b6ca9b1062a507f.tar.xz
input: use libwaio for pipe input on Windows
Use libwaio to read from pipes (stdin or named pipes) on Windows. This liberates us from nasty issues, such as pipes (as created by most programs) not being possible to read in a non-blocking or event-driven way. Although it would be possible to do that in a somewhat sane way on Vista+, it's still not easy, and on XP it's especially hard. libwaio handles these things for us. Move pipe.c to pipe-unix.c, and remove Windows specific things. Also adjust the input.c code to make this work cleanly.
Diffstat (limited to 'input/pipe.c')
-rw-r--r--input/pipe.c133
1 files changed, 0 insertions, 133 deletions
diff --git a/input/pipe.c b/input/pipe.c
deleted file mode 100644
index 12922f590c..0000000000
--- a/input/pipe.c
+++ /dev/null
@@ -1,133 +0,0 @@
-#include <pthread.h>
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <unistd.h>
-
-#ifndef __MINGW32__
-#include <poll.h>
-#endif
-
-#include "common/msg.h"
-#include "misc/bstr.h"
-#include "osdep/io.h"
-#include "input.h"
-#include "cmd_parse.h"
-
-static pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
-
-struct priv {
- struct mp_log *log;
- char *filename;
- struct mp_input_src *src;
- int wakeup_pipe[2];
-};
-
-static void *reader_thread(void *ctx)
-{
- struct priv *p = ctx;
- pthread_detach(pthread_self());
-
- int mode = O_RDONLY;
-#ifndef __MINGW32__
- // Use RDWR for FIFOs to ensure they stay open over multiple accesses.
- // Note that on Windows due to how the API works, using RDONLY should
- // be ok.
- struct stat st;
- if (stat(p->filename, &st) == 0 && S_ISFIFO(st.st_mode))
- mode = O_RDWR;
-#endif
- int fd = -1;
- bool close_fd = true;
- if (strcmp(p->filename, "/dev/stdin") == 0) { // mainly for win32
- fd = STDIN_FILENO;
- close_fd = false;
- }
- if (fd < 0)
- fd = open(p->filename, mode);
- if (fd < 0) {
- MP_ERR(p, "Can't open %s.\n", p->filename);
- goto done;
- }
-
- while (1) {
-#ifndef __MINGW32__
- struct pollfd fds[2] = {
- { .fd = fd, .events = POLLIN },
- { .fd = p->wakeup_pipe[0], .events = POLLIN },
- };
- poll(fds, 2, -1);
- if (!(fds[0].revents & POLLIN))
- break;
-#endif
- char buffer[128];
- int r = read(fd, buffer, sizeof(buffer));
- if (r <= 0)
- break;
-
- pthread_mutex_lock(&lock);
- if (!p->src) {
- pthread_mutex_unlock(&lock);
- break;
- }
- mp_input_src_feed_cmd_text(p->src, buffer, r);
- pthread_mutex_unlock(&lock);
- }
-
- if (close_fd)
- close(fd);
-
-done:
- pthread_mutex_lock(&lock);
- if (p->src)
- p->src->priv = NULL;
- pthread_mutex_unlock(&lock);
- close(p->wakeup_pipe[0]);
- close(p->wakeup_pipe[1]);
- talloc_free(p);
- return NULL;
-}
-
-static void close_pipe(struct mp_input_src *src)
-{
- pthread_mutex_lock(&lock);
- struct priv *p = src->priv;
- // Windows pipe have a severe problem: they can't be made non-blocking (not
- // after creation), and you can't wait on them. The only things that work
- // are cancellation (Vista+, broken in wine) or forceful thread termination.
- // So don't bother with "correct" termination, and just abandon the reader
- // thread.
- // On Unix, we interrupt it using the wakeup pipe.
- if (p) {
-#ifndef __MINGW32__
- write(p->wakeup_pipe[1], &(char){0}, 1);
-#endif
- p->src = NULL;
- }
- pthread_mutex_unlock(&lock);
-}
-
-void mp_input_add_pipe(struct input_ctx *ictx, const char *filename)
-{
- struct mp_input_src *src = mp_input_add_src(ictx);
- if (!src)
- return;
-
- struct priv *p = talloc_zero(NULL, struct priv);
- src->priv = p;
- p->filename = talloc_strdup(p, filename);
- p->src = src;
- p->log = mp_log_new(p, src->log, NULL);
- mp_make_wakeup_pipe(p->wakeup_pipe);
-
- pthread_t thread;
- if (pthread_create(&thread, NULL, reader_thread, p)) {
- close(p->wakeup_pipe[0]);
- close(p->wakeup_pipe[1]);
- talloc_free(p);
- mp_input_src_kill(src);
- } else {
- src->close = close_pipe;
- }
-}