From fdb9a9cca854df1152e9ec0fbfbe7f92d8ecc698 Mon Sep 17 00:00:00 2001 From: Geoffrey McRae Date: Fri, 24 Apr 2020 20:34:58 +1000 Subject: [PATCH] use a timer for the LGMP host instead of a thread --- VERSION | 2 +- c-host/include/interface/platform.h | 2 +- c-host/platform/Windows/src/platform.c | 11 +++- c-host/platform/Windows/src/platform.h | 2 +- c-host/src/app.c | 39 +++++------- common/include/common/time.h | 10 +++ common/src/platform/windows/CMakeLists.txt | 1 + common/src/platform/windows/time.c | 72 ++++++++++++++++++++++ 8 files changed, 111 insertions(+), 28 deletions(-) create mode 100644 common/src/platform/windows/time.c diff --git a/VERSION b/VERSION index a455c999..48dfdbab 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -B1-180-ge3cbdd18a0+1 \ No newline at end of file +B1-181-g243efcd51a+1 \ No newline at end of file diff --git a/c-host/include/interface/platform.h b/c-host/include/interface/platform.h index 5decd32c..f5165179 100644 --- a/c-host/include/interface/platform.h +++ b/c-host/include/interface/platform.h @@ -26,4 +26,4 @@ bool app_init(); void app_quit(); // these must be implemented for each OS -const char * os_getExecutable(); \ No newline at end of file +const char * os_getExecutable(); diff --git a/c-host/platform/Windows/src/platform.c b/c-host/platform/Windows/src/platform.c index b03a07b3..10d392e8 100644 --- a/c-host/platform/Windows/src/platform.c +++ b/c-host/platform/Windows/src/platform.c @@ -48,6 +48,7 @@ struct AppState }; static struct AppState app = {0}; +HWND MessageHWND; // undocumented API to adjust the system timer resolution (yes, its a nasty hack) typedef NTSTATUS (__stdcall *ZwSetTimerResolution_t)(ULONG RequestedResolution, BOOLEAN Set, PULONG ActualResolution); @@ -216,6 +217,9 @@ int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine } app.messageWnd = CreateWindowEx(0, "DUMMY_CLASS", "DUMMY_NAME", 0, 0, 0, 0, 0, HWND_MESSAGE, NULL, NULL, NULL); + // set the global + MessageHWND = app.messageWnd; + app.trayMenu = CreatePopupMenu(); AppendMenu(app.trayMenu, MF_STRING , ID_MENU_OPEN_LOG, "Open Log File"); AppendMenu(app.trayMenu, MF_SEPARATOR, 0 , NULL ); @@ -297,4 +301,9 @@ bool app_init() const char * os_getExecutable() { return app.executable; -} \ No newline at end of file +} + +HWND os_getMessageWnd() +{ + return app.messageWnd; +} diff --git a/c-host/platform/Windows/src/platform.h b/c-host/platform/Windows/src/platform.h index 296a1bdb..7290ccf2 100644 --- a/c-host/platform/Windows/src/platform.h +++ b/c-host/platform/Windows/src/platform.h @@ -30,4 +30,4 @@ struct MSG_CALL_FUNCTION LPARAM lParam; }; -LRESULT sendAppMessage(UINT Msg, WPARAM wParam, LPARAM lParam); \ No newline at end of file +LRESULT sendAppMessage(UINT Msg, WPARAM wParam, LPARAM lParam); diff --git a/c-host/src/app.c b/c-host/src/app.c index ce58c9fc..1860d4ba 100644 --- a/c-host/src/app.c +++ b/c-host/src/app.c @@ -28,6 +28,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include "common/thread.h" #include "common/ivshmem.h" #include "common/sysinfo.h" +#include "common/time.h" #include @@ -47,14 +48,14 @@ static const struct LGMPQueueConfig FRAME_QUEUE_CONFIG = { .queueID = LGMP_Q_FRAME, .numMessages = LGMP_Q_FRAME_LEN, - .subTimeout = 10000 + .subTimeout = 1000 }; static const struct LGMPQueueConfig POINTER_QUEUE_CONFIG = { .queueID = LGMP_Q_POINTER, .numMessages = LGMP_Q_POINTER_LEN, - .subTimeout = 10000 + .subTimeout = 1000 }; #define MAX_POINTER_SIZE (sizeof(KVMFRCursor) + (128 * 128 * 4)) @@ -78,32 +79,23 @@ struct app bool running; bool reinit; - LGThread * lgmpThread; + LGTimer * lgmpTimer; LGThread * frameThread; }; static struct app app; -static int lgmpThread(void * opaque) +static bool lgmpTimer(void * opaque) { LGMP_STATUS status; - while(app.running) + if ((status = lgmpHostProcess(app.lgmp)) != LGMP_OK) { - if ((status = lgmpHostProcess(app.lgmp)) != LGMP_OK) - { - DEBUG_ERROR("lgmpHostProcess Failed: %s", lgmpStatusString(status)); - break; - } - - /* - * do not decrease this value too far, see: - * https://lists.gnu.org/archive/html/qemu-devel/2020-01/msg06331.html - */ - usleep(100 * 1000); + DEBUG_ERROR("lgmpHostProcess Failed: %s", lgmpStatusString(status)); + app.running = false; + return false; } - app.running = false; - return 0; + return true; } static int frameThread(void * opaque) @@ -210,9 +202,9 @@ static int frameThread(void * opaque) bool startThreads() { app.running = true; - if (!lgCreateThread("LGMPThread", lgmpThread, NULL, &app.lgmpThread)) + if (!lgCreateTimer(100, lgmpTimer, NULL, &app.lgmpTimer)) { - DEBUG_ERROR("Failed to create the LGMP thread"); + DEBUG_ERROR("Failed to create the LGMP timer"); return false; } @@ -239,12 +231,11 @@ bool stopThreads() } app.frameThread = NULL; - if (app.lgmpThread && !lgJoinThread(app.lgmpThread, NULL)) + if (app.lgmpTimer) { - DEBUG_WARN("Failed to join the LGMP thread"); - ok = false; + lgTimerDestroy(app.lgmpTimer); + app.lgmpTimer = NULL; } - app.lgmpThread = NULL; return ok; } diff --git a/common/include/common/time.h b/common/include/common/time.h index ece0baae..b1b0d9d0 100644 --- a/common/include/common/time.h +++ b/common/include/common/time.h @@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA #pragma once #include +#include #if defined(_WIN32) #include @@ -28,6 +29,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA #include #endif +typedef struct LGTimer LGTimer; + static inline uint64_t microtime() { #if defined(_WIN32) @@ -64,3 +67,10 @@ static inline void nsleep(uint64_t ns) nanosleep(&ts, NULL); } #endif + +typedef bool (*LGTimerFn)(void * udata); + +bool lgCreateTimer(const unsigned int intervalMS, LGTimerFn fn, + void * udata, LGTimer ** result); + +void lgTimerDestroy(LGTimer * timer); diff --git a/common/src/platform/windows/CMakeLists.txt b/common/src/platform/windows/CMakeLists.txt index 7d3d8ab2..6954b5b8 100644 --- a/common/src/platform/windows/CMakeLists.txt +++ b/common/src/platform/windows/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(lg_common_platform_code STATIC event.c windebug.c ivshmem.c + time.c ) target_link_libraries(lg_common_platform_code diff --git a/common/src/platform/windows/time.c b/common/src/platform/windows/time.c new file mode 100644 index 00000000..b5c8352f --- /dev/null +++ b/common/src/platform/windows/time.c @@ -0,0 +1,72 @@ +/* +Looking Glass - KVM FrameRelay (KVMFR) Client +Copyright (C) 2017-2020 Geoffrey McRae +https://looking-glass.hostfission.com + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A +PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with +this program; if not, write to the Free Software Foundation, Inc., 59 Temple +Place, Suite 330, Boston, MA 02111-1307 USA +*/ + +#include "common/time.h" +#include "common/debug.h" + +// decared by the platform +extern HWND MessageHWND; + +struct LGTimer +{ + LGTimerFn fn; + void * udata; + UINT_PTR handle; + bool running; +}; + +static void TimerProc(HWND Arg1, UINT Arg2, UINT_PTR Arg3, DWORD Arg4) +{ + LGTimer * timer = (LGTimer *)Arg3; + if (!timer->fn(timer->udata)) + { + KillTimer(Arg1, timer->handle); + timer->running = false; + } +} + +bool lgCreateTimer(const unsigned int intervalMS, LGTimerFn fn, + void * udata, LGTimer ** result) +{ + LGTimer * ret = malloc(sizeof(LGTimer)); + if (!ret) + { + DEBUG_ERROR("failed to malloc LGTimer struct"); + return false; + } + + ret->fn = fn; + ret->udata = udata; + ret->running = true; + ret->handle = SetTimer(MessageHWND, (UINT_PTR)ret, intervalMS, TimerProc); + + *result = ret; + return true; +} + +void lgTimerDestroy(LGTimer * timer) +{ + if (timer->running) + { + if (!KillTimer(MessageHWND, timer->handle)) + DEBUG_ERROR("failed to destroy the timer"); + } + + free(timer); +}