mirror of
https://github.com/obsproject/obs-studio.git
synced 2024-09-19 20:32:15 +02:00
ipc-util: Fix potential ready_event hang
There is an expectation that ready_event will signal/wake 1:1, so the stray teardown signal may get lost. Add new stop_event for safety.
This commit is contained in:
parent
44f07f9b11
commit
6393c3f4cd
43
deps/ipc-util/ipc-util/pipe-windows.c
vendored
43
deps/ipc-util/ipc-util/pipe-windows.c
vendored
@ -20,8 +20,22 @@
|
||||
|
||||
static inline bool ipc_pipe_internal_create_events(ipc_pipe_server_t *pipe)
|
||||
{
|
||||
pipe->ready_event = CreateEvent(NULL, false, false, NULL);
|
||||
return !!pipe->ready_event;
|
||||
HANDLE ready_event = CreateEvent(NULL, false, false, NULL);
|
||||
HANDLE stop_event = CreateEvent(NULL, false, false, NULL);
|
||||
const bool success = ready_event && stop_event;
|
||||
if (!success) {
|
||||
if (ready_event) {
|
||||
CloseHandle(ready_event);
|
||||
ready_event = NULL;
|
||||
}
|
||||
if (stop_event) {
|
||||
CloseHandle(stop_event);
|
||||
stop_event = NULL;
|
||||
}
|
||||
}
|
||||
pipe->ready_event = ready_event;
|
||||
pipe->stop_event = stop_event;
|
||||
return success;
|
||||
}
|
||||
|
||||
static inline void *create_full_access_security_descriptor()
|
||||
@ -113,6 +127,7 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param)
|
||||
return 0;
|
||||
}
|
||||
|
||||
const HANDLE handles[] = {pipe->ready_event, pipe->stop_event};
|
||||
for (;;) {
|
||||
DWORD bytes = 0;
|
||||
bool success;
|
||||
@ -123,7 +138,8 @@ static DWORD CALLBACK ipc_pipe_internal_server_thread(LPVOID param)
|
||||
break;
|
||||
}
|
||||
|
||||
DWORD wait = WaitForSingleObject(pipe->ready_event, INFINITE);
|
||||
DWORD wait = WaitForMultipleObjects(_countof(handles), handles,
|
||||
FALSE, INFINITE);
|
||||
if (wait != WAIT_OBJECT_0) {
|
||||
break;
|
||||
}
|
||||
@ -216,16 +232,19 @@ void ipc_pipe_server_free(ipc_pipe_server_t *pipe)
|
||||
if (!pipe)
|
||||
return;
|
||||
|
||||
if (pipe->thread) {
|
||||
CancelIoEx(pipe->handle, &pipe->overlap);
|
||||
SetEvent(pipe->ready_event);
|
||||
WaitForSingleObject(pipe->thread, INFINITE);
|
||||
CloseHandle(pipe->thread);
|
||||
}
|
||||
if (pipe->ready_event)
|
||||
if (pipe->stop_event) {
|
||||
if (pipe->handle) {
|
||||
if (pipe->thread) {
|
||||
CancelIoEx(pipe->handle, &pipe->overlap);
|
||||
SetEvent(pipe->stop_event);
|
||||
WaitForSingleObject(pipe->thread, INFINITE);
|
||||
CloseHandle(pipe->thread);
|
||||
}
|
||||
CloseHandle(pipe->handle);
|
||||
}
|
||||
CloseHandle(pipe->stop_event);
|
||||
CloseHandle(pipe->ready_event);
|
||||
if (pipe->handle)
|
||||
CloseHandle(pipe->handle);
|
||||
}
|
||||
|
||||
free(pipe->read_data);
|
||||
memset(pipe, 0, sizeof(*pipe));
|
||||
|
1
deps/ipc-util/ipc-util/pipe-windows.h
vendored
1
deps/ipc-util/ipc-util/pipe-windows.h
vendored
@ -22,6 +22,7 @@ struct ipc_pipe_server {
|
||||
OVERLAPPED overlap;
|
||||
HANDLE handle;
|
||||
HANDLE ready_event;
|
||||
HANDLE stop_event;
|
||||
HANDLE thread;
|
||||
|
||||
uint8_t *read_data;
|
||||
|
Loading…
Reference in New Issue
Block a user