From a8b018d5da211c87eeebd513c3656dd8a444d144 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Mon, 4 Mar 2019 13:38:17 +1100 Subject: [PATCH] [c-host] app: fix updateEvent race problem --- c-host/app.c | 19 +++++++------------ c-host/app.h | 5 +++-- c-host/windows/capture/dxgi.c | 2 +- c-host/windows/platform.c | 15 +++++++++++++-- 4 files changed, 24 insertions(+), 17 deletions(-) diff --git a/c-host/app.c b/c-host/app.c index 3abb6fcd..206c148d 100644 --- a/c-host/app.c +++ b/c-host/app.c @@ -62,11 +62,8 @@ static int pointerThread(void * opaque) { DEBUG_INFO("Cursor thread started"); - while(app.running) + while(os_waitEvent(app.pointerEvent) && app.running) { - if (!os_waitEvent(app.pointerEvent) || !app.running) - break; - #if 0 CapturePointer pointer; pointer->data = app.pointerData; @@ -87,11 +84,8 @@ static int frameThread(void * opaque) int frameIndex = 0; volatile KVMFRFrame * fi = &(app.shmHeader->frame); - while(app.running) + while(os_waitEvent(app.frameEvent) && app.running) { - if (!os_waitEvent(app.frameEvent) || !app.running) - break; - CaptureFrame frame; frame.data = app.frame[frameIndex]; if (!app.iface->getFrame(&frame)) @@ -105,7 +99,7 @@ static int frameThread(void * opaque) os_signalEvent(app.updateEvent); // wait for the client to finish with the previous frame - while(fi->flags & KVMFR_FRAME_FLAG_UPDATE) + while(fi->flags & KVMFR_FRAME_FLAG_UPDATE && app.running) { DEBUG_WARN("Waiting for the client"); // this generally never happens @@ -277,7 +271,7 @@ int app_main() } app.iface = iface; - app.frameEvent = os_createEvent(); + app.frameEvent = os_createEvent(true); if (!app.frameEvent) { DEBUG_ERROR("Failed to create the frame event"); @@ -285,7 +279,7 @@ int app_main() goto exit; } - app.updateEvent = os_createEvent(); + app.updateEvent = os_createEvent(false); if (!app.updateEvent) { DEBUG_ERROR("Failed to create the update event"); @@ -293,7 +287,7 @@ int app_main() goto exit; } - app.pointerEvent = os_createEvent(); + app.pointerEvent = os_createEvent(true); if (!app.pointerEvent) { DEBUG_ERROR("Failed to create the pointer event"); @@ -365,6 +359,7 @@ retry_capture: if (!frameUpdate && !pointerUpdate) goto retry_capture; + os_resetEvent(app.updateEvent); if (frameUpdate && !os_signalEvent(app.frameEvent)) { DEBUG_ERROR("Failed to signal the frame thread"); diff --git a/c-host/app.h b/c-host/app.h index 1c4c894c..32783dd7 100644 --- a/c-host/app.h +++ b/c-host/app.h @@ -42,7 +42,8 @@ bool os_joinThread (osThreadHandle * handle, int * resultCode); typedef struct osEventHandle osEventHandle; -osEventHandle * os_createEvent(); +osEventHandle * os_createEvent(bool autoReset); void os_freeEvent (osEventHandle * handle); bool os_waitEvent (osEventHandle * handle); -bool os_signalEvent(osEventHandle * handle); \ No newline at end of file +bool os_signalEvent(osEventHandle * handle); +bool os_resetEvent (osEventHandle * handle); \ No newline at end of file diff --git a/c-host/windows/capture/dxgi.c b/c-host/windows/capture/dxgi.c index 2178ae56..f4d49b3b 100644 --- a/c-host/windows/capture/dxgi.c +++ b/c-host/windows/capture/dxgi.c @@ -76,7 +76,7 @@ static bool dxgi_create() return false; } - this->copyEvent = os_createEvent(); + this->copyEvent = os_createEvent(true); if (!this->copyEvent) { DEBUG_ERROR("failed to create the copy event"); diff --git a/c-host/windows/platform.c b/c-host/windows/platform.c index 33b20ccb..f8997815 100644 --- a/c-host/windows/platform.c +++ b/c-host/windows/platform.c @@ -300,9 +300,15 @@ bool os_joinThread(osThreadHandle * handle, int * resultCode) return false; } -osEventHandle * os_createEvent() +osEventHandle * os_createEvent(bool autoReset) { - HANDLE event = CreateEvent(NULL, FALSE, FALSE, NULL); + HANDLE event = CreateEvent(NULL, autoReset ? FALSE : TRUE, FALSE, NULL); + if (!event) + { + DEBUG_WINERROR("Failed to create the event", GetLastError()); + return NULL; + } + return (osEventHandle*)event; } @@ -337,4 +343,9 @@ bool os_waitEvent(osEventHandle * handle) bool os_signalEvent(osEventHandle * handle) { return SetEvent((HANDLE)handle); +} + +bool os_resetEvent(osEventHandle * handle) +{ + return ResetEvent((HANDLE)handle); } \ No newline at end of file