From 433fcee0f3925f9501795457caf54dbbeca009bd Mon Sep 17 00:00:00 2001 From: Selva Nair Date: Sun, 1 Apr 2018 12:37:21 -0400 Subject: [PATCH] Fix detection of running instance When openvpn is run with --help option it pops up a help message and exits when that window is closed. Such instances cannot accept any commands and should not be treated as a running instance. Fix by (i) When run with --help, promptly release the semaphore used to restrict to a single running instance. (ii) Wait for a short interval (200 msec) before timing out of locking the semaphore. This helps avoid race conditions. While at it also make sure the semaphore is released and closed on exit. Fixes issue: #237 Signed-off-by: Selva Nair --- main.c | 7 ++++++- misc.c | 10 ++++++++++ misc.h | 2 ++ options.c | 4 ++++ options.h | 1 + 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/main.c b/main.c index 21e22bf..c71f122 100644 --- a/main.c +++ b/main.c @@ -151,7 +151,7 @@ int WINAPI _tWinMain (HINSTANCE hThisInstance, /* try to lock the semaphore, else we are not the first instance */ if (session_semaphore && - WaitForSingleObject(session_semaphore, 0) != WAIT_OBJECT_0) + WaitForSingleObject(session_semaphore, 200) != WAIT_OBJECT_0) { first_instance = FALSE; } @@ -175,6 +175,8 @@ int WINAPI _tWinMain (HINSTANCE hThisInstance, /* initialize options to default state */ InitOptions(&o); + if (first_instance) + o.session_semaphore = session_semaphore; #ifdef DEBUG /* Open debug file for output */ @@ -308,6 +310,9 @@ int WINAPI _tWinMain (HINSTANCE hThisInstance, DispatchMessage(&messages); } + CloseSemaphore(o.session_semaphore); + o.session_semaphore = NULL; /* though we're going to die.. */ + /* The program return-value is 0 - The value that PostQuitMessage() gave */ return messages.wParam; } diff --git a/misc.c b/misc.c index 67d82c0..32ece36 100644 --- a/misc.c +++ b/misc.c @@ -410,6 +410,16 @@ InitSemaphore (WCHAR *name) return semaphore; } +void +CloseSemaphore(HANDLE sem) +{ + if (sem) + { + ReleaseSemaphore(sem, 1, NULL); + } + CloseHandle(sem); +} + /* Check access rights on an existing file */ BOOL CheckFileAccess (const TCHAR *path, int access) diff --git a/misc.h b/misc.h index a15bae7..bd29096 100644 --- a/misc.h +++ b/misc.h @@ -42,4 +42,6 @@ WCHAR *Widen(const char *utf8); BOOL validate_input(const WCHAR *input, const WCHAR *exclude); /* Concatenate two wide strings with a separator */ void wcs_concat2(WCHAR *dest, int len, const WCHAR *src1, const WCHAR *src2, const WCHAR *sep); +void CloseSemaphore(HANDLE sem); + #endif diff --git a/options.c b/options.c index bfbd371..8804bb0 100644 --- a/options.c +++ b/options.c @@ -85,6 +85,10 @@ add_option(options_t *options, int i, TCHAR **p) { TCHAR caption[200]; TCHAR msg[USAGE_BUF_SIZE]; + /* We only print help and exit: release the semapahore to allow another instance */ + CloseSemaphore(o.session_semaphore); /* OK to call even if semaphore is NULL */ + o.session_semaphore = NULL; + LoadLocalizedStringBuf(caption, _countof(caption), IDS_NFO_USAGECAPTION); LoadLocalizedStringBuf(msg, _countof(msg), IDS_NFO_USAGE); MessageBoxEx(NULL, msg, caption, MB_OK | MB_SETFOREGROUND, GetGUILanguage()); diff --git a/options.h b/options.h index c31250c..e970bdb 100644 --- a/options.h +++ b/options.h @@ -185,6 +185,7 @@ typedef struct { COLORREF clr_error; int action; /* action to send to a running instance */ TCHAR *action_arg; + HANDLE session_semaphore; } options_t; void InitOptions(options_t *);