From: Vadim Zeitlin Date: Fri, 8 Jun 2001 01:28:49 +0000 (+0000) Subject: added wxSingleInstanceChecker class X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/68a602fcd2b0856bad6f79b957fa48beb6e10635 added wxSingleInstanceChecker class git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@10453 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/distrib/msw/tmake/filelist.txt b/distrib/msw/tmake/filelist.txt index 23403c1c87..762a37048a 100644 --- a/distrib/msw/tmake/filelist.txt +++ b/distrib/msw/tmake/filelist.txt @@ -299,6 +299,7 @@ scrolbar.cpp M settings.cpp M slider95.cpp M 32 slidrmsw.cpp M 16 +snglinst.cpp M B spinbutt.cpp M spinctrl.cpp M statbmp.cpp M @@ -327,6 +328,7 @@ dir.cpp U B fontenum.cpp U fontutil.cpp U mimetype.cpp U B +snglinst.cpp U B threadpsx.cpp U B utilsunx.cpp U B gsocket.c U B @@ -710,6 +712,7 @@ setup.h W B sizer.h W slider.h W socket.h W B +snglinst.h W B spinbutt.h W spinctrl.h W splash.h W diff --git a/docs/latex/wx/category.tex b/docs/latex/wx/category.tex index 02bd4f95fc..ce41326a43 100644 --- a/docs/latex/wx/category.tex +++ b/docs/latex/wx/category.tex @@ -549,5 +549,6 @@ using any of them in the new programs: \twocolitem{\helpref{wxEncodingConverter}{wxencodingconverter}}{Encoding conversions} \twocolitem{\helpref{wxCalendarDateAttr}{wxcalendardateattr}}{Used with \helpref{wxCalendarCtrl}{wxcalendarctrl}} \twocolitem{\helpref{wxQuantize}{wxquantize}}{Class to perform quantization, or colour reduction} +\twocolitem{\helpref{wxSingleInstanceChecker}{wxsingleinstancechecker}}{Check that only single program instance is running} \end{twocollist} diff --git a/docs/latex/wx/classes.tex b/docs/latex/wx/classes.tex index 611c89f6b2..39acb57aef 100644 --- a/docs/latex/wx/classes.tex +++ b/docs/latex/wx/classes.tex @@ -276,6 +276,7 @@ \input strlist.tex \input propslv.tex \input tokenizr.tex +\input snglinst.tex \input sysclevt.tex \input settings.tex \input tab.tex diff --git a/docs/latex/wx/snglinst.tex b/docs/latex/wx/snglinst.tex new file mode 100644 index 0000000000..98ffe82ff0 --- /dev/null +++ b/docs/latex/wx/snglinst.tex @@ -0,0 +1,112 @@ +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% +%% Name: snglinst.tex +%% Purpose: wxSingleInstanceChecker documentation +%% Author: Vadim Zeitlin +%% Modified by: +%% Created: 08.06.01 +%% RCS-ID: $Id$ +%% Copyright: (c) 2001 Vadim Zeitlin +%% License: wxWindows license +%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% + +\section{\class{wxSingleInstanceChecker}}\label{wxsingleinstancechecker} + +wxSingleInstanceChecker class allows to check that only a single instance of a +program is running. To do it, you should create an object of this class. As +long as this object is alive, calls to +\helpref{IsAnotherRunning()}{wxsingleinstancecheckerisanotherrunning} from +other processes will return {\tt TRUE}. + +As the object should have the life span as big as possible, it makes sense to +create it either as a global or in \helpref{wxApp::OnInit}{wxapponinit}. For +example: + +\begin{verbatim} +bool MyApp::OnInit() +{ + m_checker = new wxSingleInstanceChecker(GetAppName()); + if ( m_checker->IsAnotherRunning() ) + { + wxLogError(_("Another program instance is already running, aborting.")); + + return FALSE; + } + + ... more initializations ... + + return TRUE; +} + +int MyApp::OnExit() +{ + delete m_checker; + + return 0; +} +\end{verbatim} + +This class is implemented for Win32 and Unix platforms supporting {\tt fcntl()} +system call only. + +\wxheading{Derived from} + +No base class + +\wxheading{Data structures} + +\latexignore{\rtfignore{\wxheading{Members}}} + +\membersection{wxSingleInstanceChecker::wxSingleInstanceChecker}\label{wxsingleinstancecheckerctor} + +\func{}{wxSingleInstanceChecker}{\void} + +Default ctor, use \helpref{Create()}{wxsingleinstancecheckercreate} after it. + +\membersection{wxSingleInstanceChecker::wxSingleInstanceChecker}\label{wxsingleinstancecheckerwxsingleinstancechecker} + +\func{}{wxSingleInstanceChecker}{\param{const wxString\& }{name}, \param{const wxString\& }{path = wxEmptyString}} + +Like \helpref{Create()}{wxsingleinstancecheckercreate} but without +error checking. + +\membersection{wxSingleInstanceChecker::Create}\label{wxsingleinstancecheckercreate} + +\func{bool}{Create}{\param{const wxString\& }{name}, \param{const wxString\& }{path = wxEmptyString}} + +Initialize the object if it had been created using the default constructor. +Note that you can't call Create() more than once, so calling it if the +\helpref{non default ctor}{wxsingleinstancecheckerwxsingleinstancechecker} +had been used is an error. + +\wxheading{Parameters} + +\docparam{name}{must be given and be as unique as possible, it is used as the +mutex name under Win32 and the lock file name under Unix. +\helpref{GetAppName()}{wxappgetappname} may be a good value for this parameter} + +\docparam{path}{is optional and is ignored under Win32 and used as the directory to +create the lock file in under Unix (default is +\helpref{wxGetHomeDir()}{wxgethomedir}) + +\wxheading{Return value} + +Returns {\tt FALSE} if initialization failed, it doesn't mean that another +instance is running - use +\helpref{IsAnotherRunning()}{wxsingleinstancecheckerisanotherrunning} to check +for it. + +\membersection{wxSingleInstanceChecker::IsAnotherRunning}\label{wxsingleinstancecheckerisanotherrunning} + +\constfunc{bool}{IsAnotherRunning}{\void} + +Returns {\tt TRUE} if another copy of this program is already running, {\tt +FALSE} otherwise. + +\membersection{wxSingleInstanceChecker::\destruct{wxSingleInstanceChecker}}\label{wxsingleinstancecheckerdtor} + +\func{}{\destruct{wxSingleInstanceChecker}}{\void} + +Destructor frees the associated resources. + +Note that it is not virtual, this class is not meant to be used polymorphically + diff --git a/include/wx/msw/setup0.h b/include/wx/msw/setup0.h index 716e3ede3d..57beb40297 100644 --- a/include/wx/msw/setup0.h +++ b/include/wx/msw/setup0.h @@ -486,13 +486,6 @@ // smaller library. #define wxUSE_HTML 1 -// wxPlot is a class to display functions plots in wxWindow. -// -// Default is 1. -// -// Recommended setting: 1 -#define wxUSE_PLOT 1 - // OpenGL canvas #define wxUSE_GLCANVAS 0 @@ -503,6 +496,15 @@ // miscellaneous settings // ---------------------------------------------------------------------------- +// wxSingleInstanceChecker class allows to verify at startup if another program +// instance is running (it is only available under Win32) +// +// Default is 1 +// +// Recommended setting: 1 (the class is tiny, disabling it won't save much +// space) +#define wxUSE_SNGLINST_CHECKER 1 + #define wxUSE_IPC 1 // 0 for no interprocess comms #define wxUSE_HELP 1 diff --git a/include/wx/snglinst.h b/include/wx/snglinst.h new file mode 100644 index 0000000000..2bcce17a82 --- /dev/null +++ b/include/wx/snglinst.h @@ -0,0 +1,67 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: wx/snglinst.h +// Purpose: wxSingleInstanceChecker can be used to restrict the number of +// simultaneously running copies of a program to one +// Author: Vadim Zeitlin +// Modified by: +// Created: 08.06.01 +// RCS-ID: $Id$ +// Copyright: (c) 2001 Vadim Zeitlin +// Licence: wxWindows licence +/////////////////////////////////////////////////////////////////////////////// + +#ifndef _WX_SNGLINST_H_ +#define _WX_SNGLINST_H_ + +#ifdef __GNUG__ + #pragma interface "snglinst.h" +#endif + +#if wxUSE_SNGLINST_CHECKER + +// ---------------------------------------------------------------------------- +// wxSingleInstanceChecker +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxSingleInstanceChecker +{ +public: + // default ctor, use Create() after it + wxSingleInstanceChecker() { Init(); } + + // like Create() but no error checking (dangerous!) + wxSingleInstanceChecker(const wxString& name, + const wxString& path = wxEmptyString) + { + Init(); + Create(name, path); + } + + // name must be given and be as unique as possible, it is used as the mutex + // name under Win32 and the lock file name under Unix - + // wxTheApp->GetAppName() may be a good value for this parameter + // + // path is optional and is ignored under Win32 and used as the directory to + // create the lock file in under Unix (default is wxGetHomeDir()) + // + // returns FALSE if initialization failed, it doesn't mean that another + // instance is running - use IsAnotherRunning() to check it + bool Create(const wxString& name, const wxString& path = wxEmptyString); + + // is another copy of this program already running? + bool IsAnotherRunning() const; + + // dtor is not virtual, this class is not meant to be used polymorphically + ~wxSingleInstanceChecker(); + +private: + // common part of all ctors + void Init() { m_impl = NULL; } + + // the implementation details (platform specific) + class WXDLLEXPORT wxSingleInstanceCheckerImpl *m_impl; +}; + +#endif // wxUSE_SNGLINST_CHECKER + +#endif // _WX_SNGLINST_H_ diff --git a/src/msw/snglinst.cpp b/src/msw/snglinst.cpp new file mode 100644 index 0000000000..0f9ba06276 --- /dev/null +++ b/src/msw/snglinst.cpp @@ -0,0 +1,132 @@ +/////////////////////////////////////////////////////////////////////////////// +// Name: msw/snglinst.cpp +// Purpose: implements wxSingleInstanceChecker class for Win32 using +// named mutexes +// Author: Vadim Zeitlin +// Modified by: +// Created: 08.06.01 +// RCS-ID: $Id$ +// Copyright: (c) 2001 Vadim Zeitlin +// License: wxWindows license +/////////////////////////////////////////////////////////////////////////////// + +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +#ifdef __GNUG__ + #pragma implementation "snglinst.h" +#endif + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __BORLANDC__ + #pragma hdrstop +#endif + +#if wxUSE_SNGLINST_CHECKER && defined(__WIN32__) + +#ifndef WX_PRECOMP + #include "wx/string.h" + #include "wx/log.h" +#endif //WX_PRECOMP + +#include "wx/snglinst.h" + +#include "wx/msw/private.h" + +// ---------------------------------------------------------------------------- +// wxSingleInstanceCheckerImpl: the real implementation class +// ---------------------------------------------------------------------------- + +class WXDLLEXPORT wxSingleInstanceCheckerImpl +{ +public: + wxSingleInstanceCheckerImpl() + { + // we don't care about m_wasOpened, it can't be accessed before being + // initialized + m_hMutex = NULL; + } + + bool Create(const wxString& name) + { + m_hMutex = ::CreateMutex(NULL, FALSE, name); + if ( !m_hMutex ) + { + wxLogLastError(_T("CreateMutex")); + + return FALSE; + } + + // mutex was either created or opened - see what really happened + m_wasOpened = ::GetLastError() == ERROR_ALREADY_EXISTS; + + return TRUE; + } + + bool WasOpened() const + { + wxCHECK_MSG( m_hMutex, FALSE, + _T("can't be called if mutex creation failed") ); + + return m_wasOpened; + } + + ~wxSingleInstanceCheckerImpl() + { + if ( m_hMutex ) + { + if ( !::CloseHandle(m_hMutex) ) + { + wxLogLastError(_T("CloseHandle(mutex)")); + } + } + } + +private: + // the result of the CreateMutex() call + bool m_wasOpened; + + // the mutex handle, may be NULL + HANDLE m_hMutex; +}; + +// ============================================================================ +// wxSingleInstanceChecker implementation +// ============================================================================ + +bool wxSingleInstanceChecker::Create(const wxString& name, + const wxString& path) +{ + wxASSERT_MSG( !m_impl, + _T("calling wxSingleInstanceChecker::Create() twice?") ); + + // creating unnamed mutex doesn't have the same semantics! + wxASSERT_MSG( !name.empty(), _T("mutex name can't be empty") ); + + m_impl = new wxSingleInstanceCheckerImpl; + + return m_impl->Create(name); +} + +bool wxSingleInstanceChecker::IsAnotherRunning() const +{ + wxCHECK_MSG( m_impl, FALSE, _T("must call Create() first") ); + + // if the mutex had been opened, another instance is running - otherwise we + // would have created it + return m_impl->WasOpened(); +} + +wxSingleInstanceChecker::~wxSingleInstanceChecker() +{ + delete m_impl; +} + +#endif // wxUSE_SNGLINST_CHECKER