1/////////////////////////////////////////////////////////////////////////////// 2// Name: msw/snglinst.cpp 3// Purpose: implements wxSingleInstanceChecker class for Win32 using 4// named mutexes 5// Author: Vadim Zeitlin 6// Modified by: 7// Created: 08.06.01 8// RCS-ID: $Id: snglinst.cpp 35650 2005-09-23 12:56:45Z MR $ 9// Copyright: (c) 2001 Vadim Zeitlin <zeitlin@dptmaths.ens-cachan.fr> 10// License: wxWindows licence 11/////////////////////////////////////////////////////////////////////////////// 12 13// ============================================================================ 14// declarations 15// ============================================================================ 16 17// ---------------------------------------------------------------------------- 18// headers 19// ---------------------------------------------------------------------------- 20 21// For compilers that support precompilation, includes "wx.h". 22#include "wx/wxprec.h" 23 24#ifdef __BORLANDC__ 25 #pragma hdrstop 26#endif 27 28#if wxUSE_SNGLINST_CHECKER && defined(__WIN32__) 29 30#ifndef WX_PRECOMP 31 #include "wx/string.h" 32 #include "wx/log.h" 33#endif //WX_PRECOMP 34 35#include "wx/snglinst.h" 36 37#include "wx/msw/private.h" 38 39// ---------------------------------------------------------------------------- 40// wxSingleInstanceCheckerImpl: the real implementation class 41// ---------------------------------------------------------------------------- 42 43class WXDLLEXPORT wxSingleInstanceCheckerImpl 44{ 45public: 46 wxSingleInstanceCheckerImpl() 47 { 48 // we don't care about m_wasOpened, it can't be accessed before being 49 // initialized 50 m_hMutex = NULL; 51 } 52 53 bool Create(const wxString& name) 54 { 55 m_hMutex = ::CreateMutex(NULL, FALSE, name); 56 if ( !m_hMutex ) 57 { 58 wxLogLastError(_T("CreateMutex")); 59 60 return false; 61 } 62 63 // mutex was either created or opened - see what really happened 64 m_wasOpened = ::GetLastError() == ERROR_ALREADY_EXISTS; 65 66 return true; 67 } 68 69 bool WasOpened() const 70 { 71 wxCHECK_MSG( m_hMutex, false, 72 _T("can't be called if mutex creation failed") ); 73 74 return m_wasOpened; 75 } 76 77 ~wxSingleInstanceCheckerImpl() 78 { 79 if ( m_hMutex ) 80 { 81 if ( !::CloseHandle(m_hMutex) ) 82 { 83 wxLogLastError(_T("CloseHandle(mutex)")); 84 } 85 } 86 } 87 88private: 89 // the result of the CreateMutex() call 90 bool m_wasOpened; 91 92 // the mutex handle, may be NULL 93 HANDLE m_hMutex; 94 95 DECLARE_NO_COPY_CLASS(wxSingleInstanceCheckerImpl) 96}; 97 98// ============================================================================ 99// wxSingleInstanceChecker implementation 100// ============================================================================ 101 102bool wxSingleInstanceChecker::Create(const wxString& name, 103 const wxString& WXUNUSED(path)) 104{ 105 wxASSERT_MSG( !m_impl, 106 _T("calling wxSingleInstanceChecker::Create() twice?") ); 107 108 // creating unnamed mutex doesn't have the same semantics! 109 wxASSERT_MSG( !name.empty(), _T("mutex name can't be empty") ); 110 111 m_impl = new wxSingleInstanceCheckerImpl; 112 113 return m_impl->Create(name); 114} 115 116bool wxSingleInstanceChecker::IsAnotherRunning() const 117{ 118 wxCHECK_MSG( m_impl, false, _T("must call Create() first") ); 119 120 // if the mutex had been opened, another instance is running - otherwise we 121 // would have created it 122 return m_impl->WasOpened(); 123} 124 125wxSingleInstanceChecker::~wxSingleInstanceChecker() 126{ 127 delete m_impl; 128} 129 130#endif // wxUSE_SNGLINST_CHECKER 131