diff --git a/DOCS/compile-windows.md b/DOCS/compile-windows.md index 9acd6e269e..a0e27baf4b 100644 --- a/DOCS/compile-windows.md +++ b/DOCS/compile-windows.md @@ -188,25 +188,3 @@ a pthreads wrapper or you want to build mpv without one, configure with: ```bash ./waf configure --enable-win32-internal-pthreads ``` - -libwaio -------- - -If you want to use ``--input-file``, you need libwaio. It's available from -git://midipix.org/waio - -To compile libwaio in MSYS2, run: - -```bash -git clone git://midipix.org/waio && cd waio - -# 32-bit build, run from mingw32_shell.bat -./build-mingw-nt32 lib-static CC=gcc AR=ar -cp -r include/waio /mingw32/include -cp lib32/libwaio.a /mingw32/lib - -# 64-bit build, run from mingw64_shell.bat -./build-mingw-nt64 lib-static CC=gcc AR=ar -cp -r include/waio /mingw64/include -cp lib64/libwaio.a /mingw64/lib -``` diff --git a/TOOLS/old-configure b/TOOLS/old-configure index 6b5635c2e1..3dea7029ed 100755 --- a/TOOLS/old-configure +++ b/TOOLS/old-configure @@ -954,7 +954,6 @@ cat > $TMPC << EOF #define HAVE_GLOB 1 #define HAVE_NANOSLEEP 1 #define HAVE_SDL1 0 -#define HAVE_WAIO 0 #define HAVE_POSIX_SPAWN 1 #define HAVE_GLIBC_THREAD_NAME (!!__GLIBC__) #define HAVE_OSX_THREAD_NAME 0 diff --git a/input/input.c b/input/input.c index 5b3370736a..e1dfe2e616 100644 --- a/input/input.c +++ b/input/input.c @@ -1265,11 +1265,7 @@ void mp_input_load(struct input_ctx *ictx) #if defined(__MINGW32__) if (ictx->global->opts->input_file && *ictx->global->opts->input_file) -#if HAVE_WAIO mp_input_pipe_add(ictx, ictx->global->opts->input_file); -#else - MP_ERR(ictx, "Pipes not available.\n"); -#endif #endif } diff --git a/input/pipe-win32.c b/input/pipe-win32.c index 4077ea84ee..3d47fb66c1 100644 --- a/input/pipe-win32.c +++ b/input/pipe-win32.c @@ -1,98 +1,107 @@ -#include -#include +/* + * This file is part of mpv. + * + * mpv is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * mpv is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with mpv. If not, see . + */ + #include #include -#include -#include - #include "common/msg.h" +#include "osdep/atomics.h" #include "osdep/io.h" #include "input.h" +struct priv { + atomic_bool cancel_requested; + int fd; + bool close_fd; + HANDLE file; + HANDLE thread; +}; + static void request_cancel(struct mp_input_src *src) { - HANDLE terminate = src->priv; + struct priv *p = src->priv; MP_VERBOSE(src, "Exiting...\n"); - SetEvent(terminate); + atomic_store(&p->cancel_requested, true); + + // The thread might not be peforming I/O at the exact moment when + // CancelIoEx is called, so call it in a loop until it succeeds or the + // thread exits + do { + if (CancelIoEx(p->file, NULL)) + break; + } while (WaitForSingleObject(p->thread, 1) != WAIT_OBJECT_0); } static void uninit(struct mp_input_src *src) { - HANDLE terminate = src->priv; + struct priv *p = src->priv; + + CloseHandle(p->thread); + if (p->close_fd) + close(p->fd); - CloseHandle(terminate); MP_VERBOSE(src, "Exited.\n"); } static void read_pipe_thread(struct mp_input_src *src, void *param) { char *filename = talloc_strdup(src, param); + struct priv *p = talloc_zero(src, struct priv); - struct waio_cx_interface *waio = NULL; - int mode = O_RDONLY; - int fd = -1; - bool close_fd = true; + p->fd = -1; + p->close_fd = true; if (strcmp(filename, "/dev/stdin") == 0) { // for symmetry with unix - fd = STDIN_FILENO; - close_fd = false; + p->fd = STDIN_FILENO; + p->close_fd = false; } - if (fd < 0) - fd = open(filename, mode); - if (fd < 0) { + if (p->fd < 0) + p->fd = open(filename, O_RDONLY); + if (p->fd < 0) { MP_ERR(src, "Can't open %s.\n", filename); - goto done; + return; } - // If we're reading from stdin, unset it. All I/O on synchronous handles is - // serialized, so stupid DLLs that call GetFileType on stdin can hang the - // process if they do it while we're reading from it. At least, the - // VirtualBox OpenGL ICD is affected by this, but only on Windows XP. - // GetFileType works differently in later versions of Windows. See: - // https://support.microsoft.com/kb/2009703 - // http://blogs.msdn.com/b/oldnewthing/archive/2011/12/02/10243553.aspx - if ((void*)_get_osfhandle(fd) == GetStdHandle(STD_INPUT_HANDLE)) - SetStdHandle(STD_INPUT_HANDLE, NULL); - - waio = waio_alloc((void *)_get_osfhandle(fd), 0, NULL, NULL); - if (!waio) { - MP_ERR(src, "Can't initialize win32 file reader.\n"); - goto done; + p->file = (HANDLE)_get_osfhandle(p->fd); + if (!p->file || p->file == INVALID_HANDLE_VALUE) { + MP_ERR(src, "Can't open %s.\n", filename); + return; } - HANDLE terminate = CreateEvent(NULL, TRUE, FALSE, NULL); - if (!terminate) - goto done; + atomic_store(&p->cancel_requested, false); + if (!DuplicateHandle(GetCurrentProcess(), GetCurrentThread(), + GetCurrentProcess(), &p->thread, SYNCHRONIZE, FALSE, 0)) + return; - src->priv = terminate; + src->priv = p; src->cancel = request_cancel; src->uninit = uninit; mp_input_src_init_done(src); - char buffer[128]; - struct waio_aiocb cb = { - .aio_buf = buffer, - .aio_nbytes = sizeof(buffer), - .hsignal = terminate, - }; - while (1) { - if (waio_read(waio, &cb)) { - MP_ERR(src, "Read operation failed.\n"); + char buffer[4096]; + while (!atomic_load(&p->cancel_requested)) { + DWORD r; + if (!ReadFile(p->file, buffer, 4096, &r, NULL)) { + if (GetLastError() != ERROR_OPERATION_ABORTED) + MP_ERR(src, "Read operation failed.\n"); break; } - if (waio_suspend(waio, (const struct waio_aiocb *[]){&cb}, 1, NULL)) - break; - ssize_t r = waio_return(waio, &cb); - if (r <= 0) - break; // EOF or error mp_input_src_feed_cmd_text(src, buffer, r); } - -done: - waio_free(waio); - if (close_fd) - close(fd); } void mp_input_pipe_add(struct input_ctx *ictx, const char *filename) diff --git a/wscript b/wscript index 9d09170fac..00a67009a8 100644 --- a/wscript +++ b/wscript @@ -198,12 +198,6 @@ iconv support use --disable-iconv.", 'desc': 'w32/dos paths', 'deps_any': [ 'os-win32', 'os-cygwin' ], 'func': check_true - }, { - 'name': '--waio', - 'desc': 'libwaio for win32', - 'deps': [ 'os-win32', 'mingw' ], - 'func': check_libs(['waio'], - check_statement('waio/waio.h', 'waio_alloc(0, 0, 0, 0)')), }, { 'name': '--termios', 'desc': 'termios', diff --git a/wscript_build.py b/wscript_build.py index a6ec6795b5..46ff204b59 100644 --- a/wscript_build.py +++ b/wscript_build.py @@ -180,7 +180,7 @@ def build(ctx): ( "input/input.c" ), ( "input/ipc.c", "!mingw" ), ( "input/keycodes.c" ), - ( "input/pipe-win32.c", "waio" ), + ( "input/pipe-win32.c", "mingw" ), ## Misc ( "misc/bstr.c" ),