From 1cb07f92f36687456564d55998617c633817b427 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 1b9d286..8fbdb0e 100644 --- a/misc.c +++ b/misc.c @@ -416,6 +416,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 e0e639d..81723eb 100644 --- a/misc.h +++ b/misc.h @@ -43,4 +43,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 79237a9..a0babfd 100644 --- a/options.h +++ b/options.h @@ -186,6 +186,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 *);