1
mirror of https://github.com/mpv-player/mpv synced 2024-10-30 04:46:41 +01:00

stream: signal a Windows event object on cancel

This will be used in the following commit to cancel subprocesses started
by Lua.
This commit is contained in:
James Ross-Gowan 2014-11-18 13:18:22 +11:00 committed by wm4
parent 67132750a6
commit 9e77ba8003
2 changed files with 35 additions and 0 deletions

View File

@ -45,6 +45,10 @@
#include "options/m_option.h"
#include "options/m_config.h"
#ifdef __MINGW32__
#include <windows.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)
@ -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)
{

View File

@ -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);