diff options
author | wm4 <wm4@nowhere> | 2014-09-14 16:21:04 +0200 |
---|---|---|
committer | wm4 <wm4@nowhere> | 2014-09-14 16:24:01 +0200 |
commit | e0b4daf3ad240ecf70af73c13b6ca9b1062a507f (patch) | |
tree | e52d79650aa69c0288dd5d9c896ab943c692f88f /input/pipe.c | |
parent | b44571ababeb368e94df6665c1d370d817a51135 (diff) | |
download | mpv-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.c | 133 |
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; - } -} |