From 6e35033f2e51efae4ba82c5745636cce024203a7 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Mon, 4 Mar 2019 13:06:30 +1100 Subject: [PATCH] [c-host] app: reinit on failure to capture a frame A failed to capture a frame should not be considered fatal as it may be due to a driver issue or bug, instead try to reinitialize first --- c-host/app.c | 57 ++++++++++++++++++++++++++++++++++------------------ 1 file changed, 38 insertions(+), 19 deletions(-) diff --git a/c-host/app.c b/c-host/app.c index fcee9205..3abb6fcd 100644 --- a/c-host/app.c +++ b/c-host/app.c @@ -48,6 +48,7 @@ struct app unsigned int frameOffset[MAX_FRAMES]; bool running; + bool reinit; osEventHandle * updateEvent; osThreadHandle * pointerThread; osEventHandle * pointerEvent; @@ -94,12 +95,19 @@ static int frameThread(void * opaque) CaptureFrame frame; frame.data = app.frame[frameIndex]; if (!app.iface->getFrame(&frame)) + { DEBUG_ERROR("Failed to get the frame"); + app.reinit = true; + os_signalEvent(app.updateEvent); + break; + } + os_signalEvent(app.updateEvent); // wait for the client to finish with the previous frame while(fi->flags & KVMFR_FRAME_FLAG_UPDATE) { + DEBUG_WARN("Waiting for the client"); // this generally never happens usleep(1000); } @@ -185,10 +193,31 @@ static bool captureStart() } DEBUG_INFO("Capture Size : %u MiB (%u)", maxFrameSize / 1048576, maxFrameSize); + // start signalled + os_signalEvent(app.updateEvent); + DEBUG_INFO("==== [ Capture Start ] ===="); return startThreads(); } +static bool captureRestart() +{ + DEBUG_INFO("==== [ Capture Restart ] ===="); + if (!stopThreads()) + return false; + + if (!app.iface->deinit() || !app.iface->init()) + { + DEBUG_ERROR("Failed to reinitialize the capture device"); + return false; + } + + if (!captureStart()) + return false; + + return true; +} + int app_main() { unsigned int shmemSize = os_shmemSize(); @@ -300,6 +329,13 @@ int app_main() if (!os_waitEvent(app.updateEvent) || !app.running) break; + if (app.reinit && !captureRestart()) + { + exitcode = -1; + goto exit; + } + app.reinit = false; + bool frameUpdate = false; bool pointerUpdate = false; @@ -313,28 +349,11 @@ retry_capture: continue; case CAPTURE_RESULT_REINIT: - DEBUG_INFO("==== [ Capture Reinit ] ===="); - if (!stopThreads()) + if (!captureRestart()) { exitcode = -1; - goto finish; + goto exit; } - - if (!iface->deinit() || !iface->init()) - { - DEBUG_ERROR("Failed to reinitialize the capture device"); - exitcode = -1; - goto finish; - } - - if (!captureStart()) - { - exitcode = -1; - goto finish; - } - - // start signalled - os_signalEvent(app.updateEvent); continue; case CAPTURE_RESULT_ERROR: