mirror of
				https://github.com/gnif/LookingGlass.git
				synced 2025-10-30 20:21:56 +00:00 
			
		
		
		
	use a timer for the LGMP host instead of a thread
This commit is contained in:
		| @@ -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           ); | ||||
| @@ -298,3 +302,8 @@ const char * os_getExecutable() | ||||
| { | ||||
|   return app.executable; | ||||
| } | ||||
|  | ||||
| HWND os_getMessageWnd() | ||||
| { | ||||
|   return app.messageWnd; | ||||
| } | ||||
|   | ||||
| @@ -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 <lgmp/host.h> | ||||
|  | ||||
| @@ -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; | ||||
| } | ||||
|   | ||||
| @@ -20,6 +20,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA | ||||
| #pragma once | ||||
|  | ||||
| #include <stdint.h> | ||||
| #include <stdbool.h> | ||||
|  | ||||
| #if defined(_WIN32) | ||||
| #include <windows.h> | ||||
| @@ -28,6 +29,8 @@ Place, Suite 330, Boston, MA 02111-1307 USA | ||||
| #include <stdint.h> | ||||
| #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); | ||||
|   | ||||
| @@ -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 | ||||
|   | ||||
							
								
								
									
										72
									
								
								common/src/platform/windows/time.c
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								common/src/platform/windows/time.c
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | ||||
| /* | ||||
| Looking Glass - KVM FrameRelay (KVMFR) Client | ||||
| Copyright (C) 2017-2020 Geoffrey McRae <geoff@hostfission.com> | ||||
| 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); | ||||
| } | ||||
		Reference in New Issue
	
	Block a user
	 Geoffrey McRae
					Geoffrey McRae