]> git.saurik.com Git - wxWidgets.git/blob - src/msw/snglinst.cpp
465365814d25e47dabea9d822f548fcf9cb6e0c9
[wxWidgets.git] / src / msw / snglinst.cpp
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$
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 #if defined(__GNUG__) && !defined(NO_GCC_PRAGMA)
22 #pragma implementation "snglinst.h"
23 #endif
24
25 // For compilers that support precompilation, includes "wx.h".
26 #include "wx/wxprec.h"
27
28 #ifdef __BORLANDC__
29 #pragma hdrstop
30 #endif
31
32 #if wxUSE_SNGLINST_CHECKER && defined(__WIN32__)
33
34 #ifndef WX_PRECOMP
35 #include "wx/string.h"
36 #include "wx/log.h"
37 #endif //WX_PRECOMP
38
39 #include "wx/snglinst.h"
40
41 #include "wx/msw/private.h"
42
43 // ----------------------------------------------------------------------------
44 // wxSingleInstanceCheckerImpl: the real implementation class
45 // ----------------------------------------------------------------------------
46
47 class WXDLLEXPORT wxSingleInstanceCheckerImpl
48 {
49 public:
50 wxSingleInstanceCheckerImpl()
51 {
52 // we don't care about m_wasOpened, it can't be accessed before being
53 // initialized
54 m_hMutex = NULL;
55 }
56
57 bool Create(const wxString& name)
58 {
59 m_hMutex = ::CreateMutex(NULL, FALSE, name);
60 if ( !m_hMutex )
61 {
62 wxLogLastError(_T("CreateMutex"));
63
64 return false;
65 }
66
67 // mutex was either created or opened - see what really happened
68 m_wasOpened = ::GetLastError() == ERROR_ALREADY_EXISTS;
69
70 return true;
71 }
72
73 bool WasOpened() const
74 {
75 wxCHECK_MSG( m_hMutex, false,
76 _T("can't be called if mutex creation failed") );
77
78 return m_wasOpened;
79 }
80
81 ~wxSingleInstanceCheckerImpl()
82 {
83 if ( m_hMutex )
84 {
85 if ( !::CloseHandle(m_hMutex) )
86 {
87 wxLogLastError(_T("CloseHandle(mutex)"));
88 }
89 }
90 }
91
92 private:
93 // the result of the CreateMutex() call
94 bool m_wasOpened;
95
96 // the mutex handle, may be NULL
97 HANDLE m_hMutex;
98
99 DECLARE_NO_COPY_CLASS(wxSingleInstanceCheckerImpl)
100 };
101
102 // ============================================================================
103 // wxSingleInstanceChecker implementation
104 // ============================================================================
105
106 bool wxSingleInstanceChecker::Create(const wxString& name,
107 const wxString& WXUNUSED(path))
108 {
109 wxASSERT_MSG( !m_impl,
110 _T("calling wxSingleInstanceChecker::Create() twice?") );
111
112 // creating unnamed mutex doesn't have the same semantics!
113 wxASSERT_MSG( !name.empty(), _T("mutex name can't be empty") );
114
115 m_impl = new wxSingleInstanceCheckerImpl;
116
117 return m_impl->Create(name);
118 }
119
120 bool wxSingleInstanceChecker::IsAnotherRunning() const
121 {
122 wxCHECK_MSG( m_impl, false, _T("must call Create() first") );
123
124 // if the mutex had been opened, another instance is running - otherwise we
125 // would have created it
126 return m_impl->WasOpened();
127 }
128
129 wxSingleInstanceChecker::~wxSingleInstanceChecker()
130 {
131 delete m_impl;
132 }
133
134 #endif // wxUSE_SNGLINST_CHECKER