History

io: support mp_make_wakeup_pipe on Windows

Misaki Kasumi committed 2 years ago

Commit f7530491 parent 91f1f4f1 file · +95 −17Browse files

Unified · Split

osdep/io.c+95−17
@@ -62,13 +62,7 @@ bool mp_set_cloexec(int fd) · 61 unmodified lines
6262 return true;
6363 }
6464
65−#ifdef _WIN32
66−int mp_make_cloexec_pipe(int pipes[2])
67−{
68− pipes[0] = pipes[1] = -1;
69− return -1;
70−}
71−#else
65+#ifndef _WIN32
7266 int mp_make_cloexec_pipe(int pipes[2])
7367 {
7468 if (pipe(pipes) != 0) {
@@ -80,14 +74,7 @@ int mp_make_cloexec_pipe(int pipes[2]) · 5 unmodified lines
8074 mp_set_cloexec(pipes[i]);
8175 return 0;
8276 }
83−#endif
8477
85−#ifdef _WIN32
86−int mp_make_wakeup_pipe(int pipes[2])
87−{
88− return mp_make_cloexec_pipe(pipes);
89−}
90−#else
9178 // create a pipe, and set it to non-blocking (and also set FD_CLOEXEC)
9279 int mp_make_wakeup_pipe(int pipes[2])
9380 {
@@ -100,15 +87,13 @@ int mp_make_wakeup_pipe(int pipes[2]) · 6 unmodified lines
10087 }
10188 return 0;
10289 }
103−#endif
10490
10591 void mp_flush_wakeup_pipe(int pipe_end)
10692 {
107−#ifndef _WIN32
10893 char buf[100];
10994 (void)read(pipe_end, buf, sizeof(buf));
110−#endif
11195 }
96+#endif
11297
11398 #ifdef _WIN32
11499
@@ -146,9 +131,13 @@ char *mp_to_utf8(void *talloc_ctx, const wchar_t *s) · 31 unmodified lines
146131
147132 #ifdef _WIN32
148133
134+#include <stdatomic.h>
135+
149136 #include <io.h>
150137 #include <fcntl.h>
138+
151139 #include "osdep/threads.h"
140+#include "osdep/getpid.h"
152141
153142 static void set_errno_from_lasterror(void)
154143 {
@@ -878,4 +867,93 @@ void freelocale(locale_t locobj) · 723 unmodified lines
878867 {
879868 }
880869
870+#define MP_PIPE_BUF_SIZE 65536
871+
872+int mp_make_cloexec_pipe(int pipes[2])
873+{
874+ if (_pipe(pipes, MP_PIPE_BUF_SIZE, _O_BINARY | _O_NOINHERIT) != 0) {
875+ pipes[0] = pipes[1] = -1;
876+ return -1;
877+ }
878+ return 0;
879+}
880+
881+int mp_make_wakeup_pipe(int pipes[2])
882+{
883+ static atomic_ulong pipe_id = 0;
884+
885+ pipes[0] = pipes[1] = -1;
886+ HANDLE handles[2];
887+ handles[0] = handles[1] = INVALID_HANDLE_VALUE;
888+
889+ const char *pipe_name = mp_tprintf(55, "\\\\?\\pipe\\mpv\\%lu-%lu", mp_getpid(), atomic_fetch_add_explicit(&pipe_id, 1, memory_order_relaxed));
890+
891+ handles[1] = CreateNamedPipeA(
892+ pipe_name,
893+ PIPE_ACCESS_OUTBOUND | FILE_FLAG_FIRST_PIPE_INSTANCE | FILE_FLAG_OVERLAPPED,
894+ 0,
895+ 1,
896+ MP_PIPE_BUF_SIZE,
897+ MP_PIPE_BUF_SIZE,
898+ 0,
899+ NULL
900+ );
901+ if (handles[1] == INVALID_HANDLE_VALUE) {
902+ set_errno_from_lasterror();
903+ goto error;
904+ }
905+
906+ handles[0] = CreateFileA(
907+ pipe_name,
908+ GENERIC_READ,
909+ 0,
910+ NULL,
911+ OPEN_EXISTING,
912+ FILE_FLAG_OVERLAPPED,
913+ NULL
914+ );
915+ if (handles[0] == INVALID_HANDLE_VALUE) {
916+ set_errno_from_lasterror();
917+ goto error;
918+ }
919+
920+ if (!ConnectNamedPipe(handles[1], NULL) && GetLastError() != ERROR_PIPE_CONNECTED) {
921+ set_errno_from_lasterror();
922+ goto error;
923+ }
924+
925+ for (int i = 0; i < 2; i++) {
926+ pipes[i] = _open_osfhandle((intptr_t)handles[i], 0);
927+ if (pipes[i] == -1)
928+ goto error;
929+ }
930+
931+ return 0;
932+
933+error:
934+ for (int i = 0; i < 2; i++) {
935+ if (pipes[i] != -1) {
936+ _close(pipes[i]);
937+ pipes[i] = -1;
938+ } else if (handles[i] != INVALID_HANDLE_VALUE) {
939+ CloseHandle(handles[i]);
940+ }
941+ }
942+
943+ return -1;
944+}
945+
946+void mp_flush_wakeup_pipe(int pipe_end)
947+{
948+ char buf[100];
949+ OVERLAPPED operation = {};
950+ HANDLE handle = (HANDLE)_get_osfhandle(pipe_end);
951+ if (handle == INVALID_HANDLE_VALUE)
952+ return;
953+ if (!ReadFile(handle, buf, sizeof(buf), NULL, &operation)) {
954+ if (GetLastError() != ERROR_IO_PENDING || !CancelIoEx(handle, &operation))
955+ set_errno_from_lasterror();
956+ }
957+}
958+
881959 #endif // __MINGW32__

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t