summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--demux/demux.c1
-rw-r--r--demux/demux_lavf.c1
-rw-r--r--demux/demux_mkv_timeline.c1
-rw-r--r--demux/demux_playlist.c1
-rw-r--r--misc/thread_tools.c130
-rw-r--r--misc/thread_tools.h28
-rw-r--r--osdep/subprocess-posix.c3
-rw-r--r--osdep/subprocess-win.c1
-rw-r--r--player/main.c2
-rw-r--r--stream/cache.c1
-rw-r--r--stream/stream.c136
-rw-r--r--stream/stream.h8
-rw-r--r--stream/stream_file.c1
-rw-r--r--stream/stream_lavf.c1
-rw-r--r--stream/stream_libarchive.c1
15 files changed, 171 insertions, 145 deletions
diff --git a/demux/demux.c b/demux/demux.c
index f386c3c2ae..0edfaa95bf 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -34,6 +34,7 @@
#include "mpv_talloc.h"
#include "common/msg.h"
#include "common/global.h"
+#include "misc/thread_tools.h"
#include "osdep/atomic.h"
#include "osdep/threads.h"
diff --git a/demux/demux_lavf.c b/demux/demux_lavf.c
index 60ae878398..a0b5ff7472 100644
--- a/demux/demux_lavf.c
+++ b/demux/demux_lavf.c
@@ -42,6 +42,7 @@
#include "common/av_common.h"
#include "misc/bstr.h"
#include "misc/charset_conv.h"
+#include "misc/thread_tools.h"
#include "stream/stream.h"
#include "demux.h"
diff --git a/demux/demux_mkv_timeline.c b/demux/demux_mkv_timeline.c
index 3ad24eb8a5..277ff9c1ee 100644
--- a/demux/demux_mkv_timeline.c
+++ b/demux/demux_mkv_timeline.c
@@ -39,6 +39,7 @@
#include "options/options.h"
#include "options/path.h"
#include "misc/bstr.h"
+#include "misc/thread_tools.h"
#include "common/common.h"
#include "common/playlist.h"
#include "stream/stream.h"
diff --git a/demux/demux_playlist.c b/demux/demux_playlist.c
index 3a65ada451..0aa542534d 100644
--- a/demux/demux_playlist.c
+++ b/demux/demux_playlist.c
@@ -25,6 +25,7 @@
#include "options/options.h"
#include "common/msg.h"
#include "common/playlist.h"
+#include "misc/thread_tools.h"
#include "options/path.h"
#include "stream/stream.h"
#include "osdep/io.h"
diff --git a/misc/thread_tools.c b/misc/thread_tools.c
index 4bcb952267..57a4900ad6 100644
--- a/misc/thread_tools.c
+++ b/misc/thread_tools.c
@@ -15,6 +15,19 @@
#include <assert.h>
#include <string.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#ifdef __MINGW32__
+#include <windows.h>
+#else
+#include <poll.h>
+#endif
+
+#include "common/common.h"
+#include "osdep/atomic.h"
+#include "osdep/io.h"
#include "thread_tools.h"
@@ -60,3 +73,120 @@ bool mp_waiter_poll(struct mp_waiter *waiter)
pthread_mutex_unlock(&waiter->lock);
return r;
}
+
+#ifndef __MINGW32__
+struct mp_cancel {
+ atomic_bool triggered;
+ int wakeup_pipe[2];
+};
+
+static void cancel_destroy(void *p)
+{
+ struct mp_cancel *c = p;
+ if (c->wakeup_pipe[0] >= 0) {
+ close(c->wakeup_pipe[0]);
+ close(c->wakeup_pipe[1]);
+ }
+}
+
+struct mp_cancel *mp_cancel_new(void *talloc_ctx)
+{
+ struct mp_cancel *c = talloc_ptrtype(talloc_ctx, c);
+ talloc_set_destructor(c, cancel_destroy);
+ *c = (struct mp_cancel){.triggered = ATOMIC_VAR_INIT(false)};
+ mp_make_wakeup_pipe(c->wakeup_pipe);
+ return c;
+}
+
+void mp_cancel_trigger(struct mp_cancel *c)
+{
+ atomic_store(&c->triggered, true);
+ (void)write(c->wakeup_pipe[1], &(char){0}, 1);
+}
+
+void mp_cancel_reset(struct mp_cancel *c)
+{
+ atomic_store(&c->triggered, false);
+ // Flush it fully.
+ while (1) {
+ int r = read(c->wakeup_pipe[0], &(char[256]){0}, 256);
+ if (r < 0 && errno == EINTR)
+ continue;
+ if (r <= 0)
+ break;
+ }
+}
+
+bool mp_cancel_test(struct mp_cancel *c)
+{
+ return c ? atomic_load_explicit(&c->triggered, memory_order_relaxed) : false;
+}
+
+bool mp_cancel_wait(struct mp_cancel *c, double timeout)
+{
+ struct pollfd fd = { .fd = c->wakeup_pipe[0], .events = POLLIN };
+ poll(&fd, 1, timeout * 1000);
+ return fd.revents & POLLIN;
+}
+
+int mp_cancel_get_fd(struct mp_cancel *c)
+{
+ return c->wakeup_pipe[0];
+}
+
+#else
+
+struct mp_cancel {
+ atomic_bool triggered;
+ HANDLE event;
+};
+
+static void cancel_destroy(void *p)
+{
+ struct mp_cancel *c = p;
+ CloseHandle(c->event);
+}
+
+struct mp_cancel *mp_cancel_new(void *talloc_ctx)
+{
+ struct mp_cancel *c = talloc_ptrtype(talloc_ctx, c);
+ talloc_set_destructor(c, cancel_destroy);
+ *c = (struct mp_cancel){.triggered = ATOMIC_VAR_INIT(false)};
+ c->event = CreateEventW(NULL, TRUE, FALSE, NULL);
+ return c;
+}
+
+void mp_cancel_trigger(struct mp_cancel *c)
+{
+ atomic_store(&c->triggered, true);
+ SetEvent(c->event);
+}
+
+void mp_cancel_reset(struct mp_cancel *c)
+{
+ atomic_store(&c->triggered, false);
+ ResetEvent(c->event);
+}
+
+bool mp_cancel_test(struct mp_cancel *c)
+{
+ return c ? atomic_load_explicit(&c->triggered, memory_order_relaxed) : false;
+}
+
+bool mp_cancel_wait(struct mp_cancel *c, double timeout)
+{
+ return WaitForSingleObject(c->event, timeout < 0 ? INFINITE : timeout * 1000)
+ == WAIT_OBJECT_0;
+}
+
+void *mp_cancel_get_event(struct mp_cancel *c)
+{
+ return c->event;
+}
+
+int mp_cancel_get_fd(struct mp_cancel *c)
+{
+ return -1;
+}
+
+#endif
diff --git a/misc/thread_tools.h b/misc/thread_tools.h
index 54f396dead..a734ac85b0 100644
--- a/misc/thread_tools.h
+++ b/misc/thread_tools.h
@@ -37,3 +37,31 @@ void mp_waiter_wakeup(struct mp_waiter *waiter, uintptr_t value);
// wakeup (in parallel to mp_waiter).
// You still need to call mp_waiter_wait() to free resources.
bool mp_waiter_poll(struct mp_waiter *waiter);
+
+// Basically a binary semaphore that supports signaling the semaphore value to
+// a bunch of other complicated mechanisms (such as wakeup pipes). It was made
+// for aborting I/O and thus has according naming.
+struct mp_cancel;
+
+struct mp_cancel *mp_cancel_new(void *talloc_ctx);
+
+// Request abort.
+void mp_cancel_trigger(struct mp_cancel *c);
+
+// Return whether the caller should abort.
+// For convenience, c==NULL is allowed.
+bool mp_cancel_test(struct mp_cancel *c);
+
+// Wait until the even is signaled. If the timeout (in seconds) expires, return
+// false. timeout==0 polls, timeout<0 waits forever.
+bool mp_cancel_wait(struct mp_cancel *c, double timeout);
+
+// Restore original state. (Allows reusing a mp_cancel.)
+void mp_cancel_reset(struct mp_cancel *c);
+
+// win32 "Event" HANDLE that indicates the current mp_cancel state.
+void *mp_cancel_get_event(struct mp_cancel *c);
+
+// The FD becomes readable if mp_cancel_test() would return true.
+// Don't actually read from it, just use it for poll().
+int mp_cancel_get_fd(struct mp_cancel *c);
diff --git a/osdep/subprocess-posix.c b/osdep/subprocess-posix.c
index a5fe43c6d4..ff78eb42f8 100644
--- a/osdep/subprocess-posix.c
+++ b/osdep/subprocess-posix.c
@@ -26,8 +26,9 @@
#include "osdep/subprocess.h"
-#include "osdep/io.h"
#include "common/common.h"
+#include "misc/thread_tools.h"
+#include "osdep/io.h"
#include "stream/stream.h"
extern char **environ;
diff --git a/osdep/subprocess-win.c b/osdep/subprocess-win.c
index bbb1f6f7fd..b5a9e1a24d 100644
--- a/osdep/subprocess-win.c
+++ b/osdep/subprocess-win.c
@@ -27,6 +27,7 @@
#include "common/common.h"
#include "stream/stream.h"
#include "misc/bstr.h"
+#include "misc/thread_tools.h"
static void write_arg(bstr *cmdline, char *arg)
{
diff --git a/player/main.c b/player/main.c
index c51f93a430..6d2b862e02 100644
--- a/player/main.c
+++ b/player/main.c
@@ -54,7 +54,7 @@
#include "audio/out/ao.h"
#include "demux/demux.h"
-#include "stream/stream.h"
+#include "misc/thread_tools.h"
#include "sub/osd.h"
#include "video/out/vo.h"
diff --git a/stream/cache.c b/stream/cache.c
index fb7927f0b1..424f27910f 100644
--- a/stream/cache.c
+++ b/stream/cache.c
@@ -54,6 +54,7 @@
#include "common/msg.h"
#include "common/tags.h"
+#include "misc/thread_tools.h"
#include "options/options.h"
#include "stream.h"
diff --git a/stream/stream.c b/stream/stream.c
index 4f63236d6a..072672d1ed 100644
--- a/stream/stream.c
+++ b/stream/stream.c
@@ -17,16 +17,12 @@
#include <stdio.h>
#include <stdlib.h>
-#include <sys/types.h>
-#include <unistd.h>
#include <limits.h>
-#include <errno.h>
#include <strings.h>
#include <assert.h>
#include <libavutil/common.h>
-#include "osdep/atomic.h"
#include "osdep/io.h"
#include "mpv_talloc.h"
@@ -36,6 +32,7 @@
#include "common/common.h"
#include "common/global.h"
#include "misc/bstr.h"
+#include "misc/thread_tools.h"
#include "common/msg.h"
#include "options/options.h"
#include "options/path.h"
@@ -45,12 +42,6 @@
#include "options/m_option.h"
#include "options/m_config.h"
-#ifdef __MINGW32__
-#include <windows.h>
-#else
-#include <poll.h>
-#endif
-
// Includes additional padding in case sizes get rounded up by sector size.
#define TOTAL_BUFFER_SIZE (STREAM_MAX_BUFFER_SIZE + STREAM_MAX_SECTOR_SIZE)
@@ -842,131 +833,6 @@ struct bstr stream_read_file(const char *filename, void *talloc_ctx,
return res;
}
-#ifndef __MINGW32__
-struct mp_cancel {
- atomic_bool triggered;
- int wakeup_pipe[2];
-};
-
-static void cancel_destroy(void *p)
-{
- struct mp_cancel *c = p;
- if (c->wakeup_pipe[0] >= 0) {
- close(c->wakeup_pipe[0]);
- close(c->wakeup_pipe[1]);
- }
-}
-
-struct mp_cancel *mp_cancel_new(void *talloc_ctx)
-{
- struct mp_cancel *c = talloc_ptrtype(talloc_ctx, c);
- talloc_set_destructor(c, cancel_destroy);
- *c = (struct mp_cancel){.triggered = ATOMIC_VAR_INIT(false)};
- mp_make_wakeup_pipe(c->wakeup_pipe);
- return c;
-}
-
-// Request abort.
-void mp_cancel_trigger(struct mp_cancel *c)
-{
- atomic_store(&c->triggered, true);
- (void)write(c->wakeup_pipe[1], &(char){0}, 1);
-}
-
-// Restore original state. (Allows reusing a mp_cancel.)
-void mp_cancel_reset(struct mp_cancel *c)
-{
- atomic_store(&c->triggered, false);
- // Flush it fully.
- while (1) {
- int r = read(c->wakeup_pipe[0], &(char[256]){0}, 256);
- if (r < 0 && errno == EINTR)
- continue;
- if (r <= 0)
- break;
- }
-}
-
-// Return whether the caller should abort.
-// For convenience, c==NULL is allowed.
-bool mp_cancel_test(struct mp_cancel *c)
-{
- return c ? atomic_load_explicit(&c->triggered, memory_order_relaxed) : false;
-}
-
-// Wait until the even is signaled. If the timeout (in seconds) expires, return
-// false. timeout==0 polls, timeout<0 waits forever.
-bool mp_cancel_wait(struct mp_cancel *c, double timeout)
-{
- struct pollfd fd = { .fd = c->wakeup_pipe[0], .events = POLLIN };
- poll(&fd, 1, timeout * 1000);
- return fd.revents & POLLIN;
-}
-
-// The FD becomes readable if mp_cancel_test() would return true.
-// Don't actually read from it, just use it for poll().
-int mp_cancel_get_fd(struct mp_cancel *c)
-{
- return c->wakeup_pipe[0];
-}
-
-#else
-
-struct mp_cancel {
- atomic_bool triggered;
- HANDLE event;
-};
-
-static void cancel_destroy(void *p)
-{
- struct mp_cancel *c = p;
- CloseHandle(c->event);
-}
-
-struct mp_cancel *mp_cancel_new(void *talloc_ctx)
-{
- struct mp_cancel *c = talloc_ptrtype(talloc_ctx, c);
- talloc_set_destructor(c, cancel_destroy);
- *c = (struct mp_cancel){.triggered = ATOMIC_VAR_INIT(false)};
- c->event = CreateEventW(NULL, TRUE, FALSE, NULL);
- return c;
-}
-
-void mp_cancel_trigger(struct mp_cancel *c)
-{
- atomic_store(&c->triggered, true);
- SetEvent(c->event);
-}
-
-void mp_cancel_reset(struct mp_cancel *c)
-{
- atomic_store(&c->triggered, false);
- ResetEvent(c->event);
-}
-
-bool mp_cancel_test(struct mp_cancel *c)
-{
- return c ? atomic_load_explicit(&c->triggered, memory_order_relaxed) : false;
-}
-
-bool mp_cancel_wait(struct mp_cancel *c, double timeout)
-{
- return WaitForSingleObject(c->event, timeout < 0 ? INFINITE : timeout * 1000)
- == WAIT_OBJECT_0;
-}
-
-void *mp_cancel_get_event(struct mp_cancel *c)
-{
- return c->event;
-}
-
-int mp_cancel_get_fd(struct mp_cancel *c)
-{
- return -1;
-}
-
-#endif
-
char **stream_get_proto_list(void)
{
char **list = NULL;
diff --git a/stream/stream.h b/stream/stream.h
index 3ce74ecd15..863c0cfd3c 100644
--- a/stream/stream.h
+++ b/stream/stream.h
@@ -254,14 +254,6 @@ stream_t *open_memory_stream(void *data, int len);
void mp_url_unescape_inplace(char *buf);
char *mp_url_escape(void *talloc_ctx, const char *s, const char *ok);
-struct mp_cancel *mp_cancel_new(void *talloc_ctx);
-void mp_cancel_trigger(struct mp_cancel *c);
-bool mp_cancel_test(struct mp_cancel *c);
-bool mp_cancel_wait(struct mp_cancel *c, double timeout);
-void mp_cancel_reset(struct mp_cancel *c);
-void *mp_cancel_get_event(struct mp_cancel *c); // win32 HANDLE
-int mp_cancel_get_fd(struct mp_cancel *c);
-
// stream_file.c
char *mp_file_url_to_filename(void *talloc_ctx, bstr url);
char *mp_file_get_path(void *talloc_ctx, bstr url);
diff --git a/stream/stream_file.c b/stream/stream_file.c
index 2d0e3457c0..73048baefb 100644
--- a/stream/stream_file.c
+++ b/stream/stream_file.c
@@ -34,6 +34,7 @@
#include "common/common.h"
#include "common/msg.h"
+#include "misc/thread_tools.h"
#include "stream.h"
#include "options/m_option.h"
#include "options/path.h"
diff --git a/stream/stream_lavf.c b/stream/stream_lavf.c
index 09866ff74f..fea6f4b62d 100644
--- a/stream/stream_lavf.c
+++ b/stream/stream_lavf.c
@@ -24,6 +24,7 @@
#include "common/msg.h"
#include "common/tags.h"
#include "common/av_common.h"
+#include "misc/thread_tools.h"
#include "stream.h"
#include "options/m_config.h"
#include "options/m_option.h"
diff --git a/stream/stream_libarchive.c b/stream/stream_libarchive.c
index bb25c6ad84..d02cb7e630 100644
--- a/stream/stream_libarchive.c
+++ b/stream/stream_libarchive.c
@@ -20,6 +20,7 @@
#include "misc/bstr.h"
#include "common/common.h"
+#include "misc/thread_tools.h"
#include "stream.h"
#include "stream_libarchive.h"