From 74649ddb969ee12bc1a54ca59b2cbfa2dc51636d Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Tue, 11 Aug 2020 14:30:44 +1000 Subject: [PATCH] [client] gracefully restart if the host application restarts --- VERSION | 2 +- client/include/interface/renderer.h | 3 +++ client/renderers/EGL/egl.c | 11 ++++++++++ client/renderers/OpenGL/opengl.c | 7 +++++++ client/src/main.c | 31 +++++++++++++++++++++++++++-- client/src/main.h | 1 + repos/LGMP | 2 +- 7 files changed, 53 insertions(+), 4 deletions(-) diff --git a/VERSION b/VERSION index dad4e0b1..a57d1f21 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -B2-rc3-7-gea74ee6e25+1 \ No newline at end of file +B2-rc3-8-g4619ddef5d+1 \ No newline at end of file diff --git a/client/include/interface/renderer.h b/client/include/interface/renderer.h index 33d3502b..b2b81a92 100644 --- a/client/include/interface/renderer.h +++ b/client/include/interface/renderer.h @@ -33,6 +33,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA (x)->create && \ (x)->initialize && \ (x)->deinitialize && \ + (x)->on_restart && \ (x)->on_resize && \ (x)->on_mouse_shape && \ (x)->on_mouse_event && \ @@ -87,6 +88,7 @@ typedef void (* LG_RendererSetup)(); typedef bool (* LG_RendererCreate )(void ** opaque, const LG_RendererParams params); typedef bool (* LG_RendererInitialize )(void * opaque, Uint32 * sdlFlags); typedef void (* LG_RendererDeInitialize)(void * opaque); +typedef void (* LG_RendererOnRestart )(void * opaque); typedef void (* LG_RendererOnResize )(void * opaque, const int width, const int height, const LG_RendererRect destRect); typedef bool (* LG_RendererOnMouseShape)(void * opaque, const LG_RendererCursor cursor, const int width, const int height, const int pitch, const uint8_t * data); typedef bool (* LG_RendererOnMouseEvent)(void * opaque, const bool visible , const int x, const int y); @@ -103,6 +105,7 @@ typedef struct LG_Renderer LG_RendererCreate create; LG_RendererInitialize initialize; LG_RendererDeInitialize deinitialize; + LG_RendererOnRestart on_restart; LG_RendererOnResize on_resize; LG_RendererOnMouseShape on_mouse_shape; LG_RendererOnMouseEvent on_mouse_event; diff --git a/client/renderers/EGL/egl.c b/client/renderers/EGL/egl.c index 666fb337..b758e040 100644 --- a/client/renderers/EGL/egl.c +++ b/client/renderers/EGL/egl.c @@ -225,6 +225,16 @@ void egl_deinitialize(void * opaque) free(this); } +void egl_on_restart(void * opaque) +{ + struct Inst * this = (struct Inst *)opaque; + + eglDestroyContext(this->display, this->frameContext); + this->frameContext = NULL; + this->waitFadeTime = 0; + this->waitDone = false; +} + void egl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect) { struct Inst * this = (struct Inst *)opaque; @@ -595,6 +605,7 @@ struct LG_Renderer LGR_EGL = .create = egl_create, .initialize = egl_initialize, .deinitialize = egl_deinitialize, + .on_restart = egl_on_restart, .on_resize = egl_on_resize, .on_mouse_shape = egl_on_mouse_shape, .on_mouse_event = egl_on_mouse_event, diff --git a/client/renderers/OpenGL/opengl.c b/client/renderers/OpenGL/opengl.c index 2047ae50..9108f50b 100644 --- a/client/renderers/OpenGL/opengl.c +++ b/client/renderers/OpenGL/opengl.c @@ -295,6 +295,12 @@ void opengl_deinitialize(void * opaque) free(this); } +void opengl_on_restart(void * opaque) +{ + struct Inst * this = (struct Inst *)opaque; + this->waiting = true; +} + void opengl_on_resize(void * opaque, const int width, const int height, const LG_RendererRect destRect) { struct Inst * this = (struct Inst *)opaque; @@ -823,6 +829,7 @@ const LG_Renderer LGR_OpenGL = .create = opengl_create, .initialize = opengl_initialize, .deinitialize = opengl_deinitialize, + .on_restart = opengl_on_restart, .on_resize = opengl_on_resize, .on_mouse_shape = opengl_on_mouse_shape, .on_mouse_event = opengl_on_mouse_event, diff --git a/client/src/main.c b/client/src/main.c index f8c44de5..42a18f87 100644 --- a/client/src/main.c +++ b/client/src/main.c @@ -155,7 +155,7 @@ static int renderThread(void * unused) struct timespec time; clock_gettime(CLOCK_REALTIME, &time); - while(state.running) + while(state.running || state.restart) { if (state.frameTime > 0) { @@ -287,6 +287,9 @@ static int cursorThread(void * unused) continue; } + if (status == LGMP_ERR_INVALID_SESSION) + state.restart = true; + DEBUG_ERROR("lgmpClientProcess Failed: %s", lgmpStatusString(status)); state.running = false; break; @@ -395,6 +398,9 @@ static int frameThread(void * unused) continue; } + if (status == LGMP_ERR_INVALID_SESSION) + state.restart = true; + DEBUG_ERROR("lgmpClientProcess Failed: %s", lgmpStatusString(status)); break; } @@ -1442,6 +1448,8 @@ static int lg_run() LGMP_STATUS status; +restart: + while(state.running) { if ((status = lgmpClientInit(state.shm.mem, state.shm.size, &state.lgmp)) == LGMP_OK) @@ -1457,8 +1465,9 @@ static int lg_run() uint32_t udataSize; KVMFR *udata; + int waitCount; - int waitCount = 0; + waitCount = 0; while(state.running) { if ((status = lgmpClientSessionInit(state.lgmp, &udataSize, (uint8_t **)&udata)) == LGMP_OK) @@ -1531,12 +1540,30 @@ static int lg_run() { if (!lgmpClientSessionValid(state.lgmp)) { + state.restart = true; DEBUG_WARN("Session is invalid, has the host shutdown?"); break; } SDL_WaitEventTimeout(NULL, 1000); } + if (state.restart) + { + state.running = false; + lgSignalEvent(e_startup); + lgSignalEvent(e_frame); + lgJoinThread(t_frame , NULL); + lgJoinThread(t_cursor, NULL); + state.running = true; + state.restart = false; + + state.lgr->on_restart(state.lgrData); + + lgmpClientFree(&state.lgmp); + DEBUG_INFO("Waiting for the host to restart..."); + goto restart; + } + return 0; } diff --git a/client/src/main.h b/client/src/main.h index ff5bc67c..dd6e05ca 100644 --- a/client/src/main.h +++ b/client/src/main.h @@ -32,6 +32,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA struct AppState { bool running; + bool restart; bool ignoreInput; bool escapeActive; SDL_Scancode escapeAction; diff --git a/repos/LGMP b/repos/LGMP index 6a41b4c2..7d3b8a1d 160000 --- a/repos/LGMP +++ b/repos/LGMP @@ -1 +1 @@ -Subproject commit 6a41b4c23754a4748e77e14e8cff4ab5c789fced +Subproject commit 7d3b8a1d8b8a24f3812fb250b6e853f2c37ec483