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 <selva.nair@gmail.com>
pull/255/head
Selva Nair 2018-04-01 12:37:21 -04:00 committed by Samuli Seppänen
parent c51fd4450d
commit 1cb07f92f3
5 changed files with 23 additions and 1 deletions

7
main.c
View File

@ -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;
}

10
misc.c
View File

@ -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)

2
misc.h
View File

@ -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

View File

@ -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());

View File

@ -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 *);