From 9e77ba8003240f69ac95f0cad16ea0d424c46c18 Mon Sep 17 00:00:00 2001 From: James Ross-Gowan Date: Tue, 18 Nov 2014 13:18:22 +1100 Subject: [PATCH] stream: signal a Windows event object on cancel This will be used in the following commit to cancel subprocesses started by Lua. --- stream/stream.c | 31 +++++++++++++++++++++++++++++++ stream/stream.h | 4 ++++ 2 files changed, 35 insertions(+) diff --git a/stream/stream.c b/stream/stream.c index e51a1666f0..e87e5cab07 100644 --- a/stream/stream.c +++ b/stream/stream.c @@ -45,6 +45,10 @@ #include "options/m_option.h" #include "options/m_config.h" +#ifdef __MINGW32__ +#include +#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) @@ -986,14 +990,22 @@ struct bstr stream_read_complete(struct stream *s, void *talloc_ctx, struct mp_cancel { atomic_bool triggered; +#ifdef __MINGW32__ + HANDLE event; +#else int wakeup_pipe[2]; +#endif }; static void cancel_destroy(void *p) { struct mp_cancel *c = p; +#ifdef __MINGW32__ + CloseHandle(c->event); +#else close(c->wakeup_pipe[0]); close(c->wakeup_pipe[1]); +#endif } struct mp_cancel *mp_cancel_new(void *talloc_ctx) @@ -1001,7 +1013,11 @@ 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)}; +#ifdef __MINGW32__ + c->event = CreateEventW(NULL, TRUE, FALSE, NULL); +#else mp_make_wakeup_pipe(c->wakeup_pipe); +#endif return c; } @@ -1009,13 +1025,20 @@ struct mp_cancel *mp_cancel_new(void *talloc_ctx) void mp_cancel_trigger(struct mp_cancel *c) { atomic_store(&c->triggered, true); +#ifdef __MINGW32__ + SetEvent(c->event); +#else write(c->wakeup_pipe[1], &(char){0}, 1); +#endif } // Restore original state. (Allows reusing a mp_cancel.) void mp_cancel_reset(struct mp_cancel *c) { atomic_store(&c->triggered, false); +#ifdef __MINGW32__ + ResetEvent(c->event); +#else // Flush it fully. while (1) { int r = read(c->wakeup_pipe[0], &(char[256]){0}, 256); @@ -1024,6 +1047,7 @@ void mp_cancel_reset(struct mp_cancel *c) if (r <= 0) break; } +#endif } // Return whether the caller should abort. @@ -1033,12 +1057,19 @@ bool mp_cancel_test(struct mp_cancel *c) return c ? atomic_load(&c->triggered) : false; } +#ifdef __MINGW32__ +void *mp_cancel_get_event(struct mp_cancel *c) +{ + return c->event; +} +#else // 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]; } +#endif void stream_print_proto_list(struct mp_log *log) { diff --git a/stream/stream.h b/stream/stream.h index 5cf3487462..e017eef1fd 100644 --- a/stream/stream.h +++ b/stream/stream.h @@ -264,7 +264,11 @@ 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); void mp_cancel_reset(struct mp_cancel *c); +#ifdef __MINGW32__ +void *mp_cancel_get_event(struct mp_cancel *c); +#else int mp_cancel_get_fd(struct mp_cancel *c); +#endif // stream_file.c char *mp_file_url_to_filename(void *talloc_ctx, bstr url);