From: Vadim Zeitlin Date: Wed, 16 Sep 2009 12:38:00 +0000 (+0000) Subject: Allow creating wxSingleInstanceChecker with default name. X-Git-Url: https://git.saurik.com/wxWidgets.git/commitdiff_plain/956b3d92ef079324cd880ddcc321291195130d5f Allow creating wxSingleInstanceChecker with default name. This makes it easier to use in common cases: there is no need to come up with a unique name for the checker any more as sufficiently unique combination of wxApp::GetAppName() and wxGetUserId() is used if no name was explicitly given. This is done by calling the new CreateDefault() on demand from IsAnotherRunning() instead of simply creating the checker with the default name in the default ctor for compatibility (you had to call Create() after using the default ctor before and it can only be called once) and because wxTheApp might not exist yet when wxSingleInstanceChecker is created. Closes #11166. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@61945 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- diff --git a/include/wx/snglinst.h b/include/wx/snglinst.h index a8f508aefb..e62d6cfc01 100644 --- a/include/wx/snglinst.h +++ b/include/wx/snglinst.h @@ -15,6 +15,9 @@ #if wxUSE_SNGLINST_CHECKER +#include "wx/app.h" +#include "wx/utils.h" + // ---------------------------------------------------------------------------- // wxSingleInstanceChecker // ---------------------------------------------------------------------------- @@ -33,9 +36,11 @@ public: 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 + // notice that calling Create() is optional now, if you don't do it before + // calling IsAnotherRunning(), CreateDefault() is used automatically + // + // name it is used as the mutex name under Win32 and the lock file name + // under Unix so it should be as unique as possible and must be non-empty // // path is optional and is ignored under Win32 and used as the directory to // create the lock file in under Unix (default is wxGetHomeDir()) @@ -44,8 +49,32 @@ public: // instance is running - use IsAnotherRunning() to check it bool Create(const wxString& name, const wxString& path = wxEmptyString); + // use the default name, which is a combination of wxTheApp->GetAppName() + // and wxGetUserId() for mutex/lock file + // + // this is called implicitly by IsAnotherRunning() if the checker hadn't + // been created until then + bool CreateDefault() + { + wxCHECK_MSG( wxTheApp, false, "must have application instance" ); + return Create(wxTheApp->GetAppName() + '-' + wxGetUserId()); + } + // is another copy of this program already running? - bool IsAnotherRunning() const; + bool IsAnotherRunning() const + { + if ( !m_impl ) + { + if ( !const_cast(this)->CreateDefault() ) + { + // if creation failed, return false as it's better to not + // prevent this instance from starting up if there is an error + return false; + } + } + + return DoIsAnotherRunning(); + } // dtor is not virtual, this class is not meant to be used polymorphically ~wxSingleInstanceChecker(); @@ -54,6 +83,9 @@ private: // common part of all ctors void Init() { m_impl = NULL; } + // do check if another instance is running, called only if m_impl != NULL + bool DoIsAnotherRunning() const; + // the implementation details (platform specific) class WXDLLIMPEXP_FWD_BASE wxSingleInstanceCheckerImpl *m_impl; diff --git a/interface/wx/snglinst.h b/interface/wx/snglinst.h index 4d240abe65..a7c7c0b460 100644 --- a/interface/wx/snglinst.h +++ b/interface/wx/snglinst.h @@ -23,8 +23,7 @@ @code bool MyApp::OnInit() { - const wxString name = wxString::Format("MyApp-%s", wxGetUserId().c_str()); - m_checker = new wxSingleInstanceChecker(name); + m_checker = new wxSingleInstanceChecker; if ( m_checker-IsAnotherRunning() ) { wxLogError(_("Another program instance is already running, aborting.")); @@ -48,10 +47,12 @@ } @endcode - Note using wxGetUserId() to construct the name: this allows different user - to run the application concurrently which is usually the intended goal. - If you don't use the user name in the wxSingleInstanceChecker name, only - one user would be able to run the application at a time. + Note that by default wxSingleInstanceChecker::CreateDefault() is used to + create the checker meaning that it will be initialized differently for + different users and thus will allow different users to run the application + concurrently which is usually the required behaviour. However if only a + single instance of a program should be running system-wide, you need to + call Create() with a custom name which does @em not include wxGetUserId(). This class is implemented for Win32 and Unix platforms (supporting @c fcntl() system call, but almost all of modern Unix systems do) only. @@ -63,43 +64,53 @@ class wxSingleInstanceChecker { public: /** - Default ctor, use Create() after it. + Default constructor. + + You may call Create() after using it or directly call + IsAnotherRunning() in which case CreateDefault() will be implicitly + used. */ wxSingleInstanceChecker(); /** - Like Create() but without error checking. + Constructor calling Create(). + + This constructor does exactly the same thing as Create() but doesn't + allow to check for errors. */ wxSingleInstanceChecker(const wxString& name, const wxString& path = wxEmptyString); /** Destructor frees the associated resources. + Note that it is not virtual, this class is not meant to be used polymorphically. */ ~wxSingleInstanceChecker(); /** 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 - @ref wxSingleInstanceChecker() "non default ctor" had been used is an error. + non default ctor had been used is an error. @param 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. - GetAppName() and wxGetUserId() are commonly used to construct + wxApp::GetAppName() and wxGetUserId() are commonly used to construct this parameter. @param path The path is optional and is ignored under Win32 and used as the directory to create the lock file in under Unix (default is wxGetHomeDir()). - @return Returns @false if initialization failed, it doesn't mean that - another instance is running - use IsAnotherRunning() to check - for it. + @return + Returns @false if initialization failed, it doesn't mean that + another instance is running -- use IsAnotherRunning() to check for + it. @note - One of possible reasons while Create may fail on Unix is that the lock + One of possible reasons while Create() may fail on Unix is that the lock file used for checking already exists but was not created by the user. Therefore applications shouldn't treat failure of this function as fatal condition, because doing so would open them to the possibility of a @@ -111,8 +122,25 @@ public: const wxString& path = wxEmptyString); /** - Returns @true if another copy of this program is already running, @false - otherwise. + Calls Create() with default name. + + This method simply calls Create() with a string composed of + wxApp::GetAppName() and wxGetUserId(). + + Because this method uses wxApp::GetAppName(), it may only be called + after the global application was constructed. + + @since 2.9.1 + */ + bool CreateDefault(); + + /** + Returns @true if another copy of this program is already running and + @false otherwise. + + Notice that if the object was created using the default constructor + Create() hadn't been called before this method, it will call + CreateDefault() automatically. */ bool IsAnotherRunning() const; }; diff --git a/src/msw/snglinst.cpp b/src/msw/snglinst.cpp index 8f69ec5698..1e5d08ef79 100644 --- a/src/msw/snglinst.cpp +++ b/src/msw/snglinst.cpp @@ -113,7 +113,7 @@ bool wxSingleInstanceChecker::Create(const wxString& name, return m_impl->Create(name); } -bool wxSingleInstanceChecker::IsAnotherRunning() const +bool wxSingleInstanceChecker::DoIsAnotherRunning() const { wxCHECK_MSG( m_impl, false, wxT("must call Create() first") ); diff --git a/src/os2/snglinst.cpp b/src/os2/snglinst.cpp index f1c4b184b1..499ad0d1a2 100644 --- a/src/os2/snglinst.cpp +++ b/src/os2/snglinst.cpp @@ -117,7 +117,7 @@ bool wxSingleInstanceChecker::Create(const wxString& name, return m_impl->Create(name); } -bool wxSingleInstanceChecker::IsAnotherRunning() const +bool wxSingleInstanceChecker::DoIsAnotherRunning() const { wxCHECK_MSG( m_impl, false, wxT("must call Create() first") ); diff --git a/src/unix/snglinst.cpp b/src/unix/snglinst.cpp index 43674249af..ce8e9e38f7 100644 --- a/src/unix/snglinst.cpp +++ b/src/unix/snglinst.cpp @@ -371,7 +371,7 @@ bool wxSingleInstanceChecker::Create(const wxString& name, return m_impl->Create(fullname); } -bool wxSingleInstanceChecker::IsAnotherRunning() const +bool wxSingleInstanceChecker::DoIsAnotherRunning() const { wxCHECK_MSG( m_impl, false, wxT("must call Create() first") );