Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(923)

Side by Side Diff: base/single_instance.cc

Issue 624713003: Keep only base/extractor.[cc|h]. (Closed) Base URL: https://chromium.googlesource.com/external/omaha.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « base/single_instance.h ('k') | base/singleton.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2003-2009 Google Inc.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 // ========================================================================
15 //
16 // Synchronization functions
17
18 #include "omaha/base/single_instance.h"
19 #include "omaha/base/constants.h"
20 #include "omaha/base/debug.h"
21 #include "omaha/base/logging.h"
22 #include "omaha/base/scoped_any.h"
23 #include "omaha/base/synchronized.h"
24 #include "omaha/base/utils.h"
25
26 namespace omaha {
27
28 // Check to see whether an instance is already running across all sessions.
29 // If not, enter single instance protection. The user must call Shutdown()
30 // on that SingleInstance once single instance protection is no longer needed.
31 bool SingleInstance::StartupSingleInstance(const TCHAR* id) {
32 ASSERT1(id);
33
34 bool already_running = false, already_running_in_different_session = false;
35 HRESULT hr = Startup(id,
36 &already_running,
37 &already_running_in_different_session);
38 ASSERT(SUCCEEDED(hr), (_T("")));
39
40 return already_running || already_running_in_different_session;
41 }
42
43 // Check to see whether an instance is already running in this session. If not,
44 // enter session-only single instance protection. The user must call Shutdown()
45 // on that SingleInstance once single instance protection is no longer needed.
46 bool SingleInstance::StartupSingleSessionInstance(const TCHAR* id) {
47 ASSERT1(id);
48
49 bool already_running = false;
50 HRESULT hr = Startup(id, &already_running, NULL);
51 ASSERT(SUCCEEDED(hr), (_T("")));
52
53 return already_running;
54 }
55
56 // Startup a single instance protection. The user must call Shutdown() on
57 // that SingleInstance once the single instance protection is no longer needed.
58 //
59 // Returns whether or not the process is already running
60 // already_running means "already running in same session".
61 // already_running_in_different_session means "already running on machine"
62 HRESULT SingleInstance::Startup(const TCHAR* id,
63 bool* already_running,
64 bool* already_running_in_different_session) {
65 ASSERT1(id);
66 ASSERT1(already_running);
67
68 CString mutex_id;
69
70 // Use two mutexes: one to check for being the only instance in this
71 // session, and one for being the only instance in any terminal session.
72 // Only create (and check) the global mutex for one-per-machine check if
73 // the result is asked for.
74 // We don't actually obtain ownership of the mutex
75 // For information on the "Local" and "Global" namespace prefixes, see MSDN
76 // article "Kernel Object Namespaces".
77
78 // Create a user level mutex
79 CreateSyncId(id, SYNC_USER, &mutex_id);
80 RET_IF_FAILED(CreateInstanceMutex(mutex_id,
81 &user_mutex_handle_,
82 already_running));
83
84 // Create a global mutex
85 if (already_running_in_different_session) {
86 CreateSyncId(id, SYNC_GLOBAL, &mutex_id);
87 RET_IF_FAILED(CreateInstanceMutex(mutex_id,
88 &global_mutex_handle_,
89 already_running_in_different_session));
90 }
91
92 return S_OK;
93 }
94
95 // Create a mutex
96 HRESULT SingleInstance::CreateInstanceMutex(const TCHAR* mutex_id,
97 HANDLE* mutex_handle,
98 bool* already_running) {
99 ASSERT1(mutex_id && *mutex_id);
100 ASSERT1(mutex_handle);
101 ASSERT1(already_running);
102
103 *already_running = false;
104
105 *mutex_handle = ::CreateMutex(NULL, false, mutex_id);
106 DWORD last_error = ::GetLastError();
107
108 // We check for both values because we sometimes see access
109 // denied. We expect this to mean that the mutex was created by a
110 // different set of user credentials, which shouldn't happen under
111 // normal circumstances in our applications, but in fact we did
112 // see it happen.
113 if (last_error == ERROR_ALREADY_EXISTS || last_error == ERROR_ACCESS_DENIED) {
114 *already_running = true;
115 return S_OK;
116 }
117
118 if (*mutex_handle == NULL) {
119 HRESULT hr = HRESULT_FROM_WIN32(last_error);
120 ASSERT(false, (_T("[SingleInstance::CreateInstanceMutex]")
121 _T("[failed to create mutex][%s][0x%x]"), mutex_id, hr));
122 return hr;
123 }
124
125 return S_OK;
126 }
127
128 // Shutdown a single instance protection
129 HRESULT SingleInstance::Shutdown() {
130 if (user_mutex_handle_) {
131 VERIFY(::CloseHandle(user_mutex_handle_), (_T("")));
132 user_mutex_handle_ = NULL;
133 }
134
135 if (global_mutex_handle_) {
136 VERIFY(::CloseHandle(global_mutex_handle_), (_T("")));
137 global_mutex_handle_ = NULL;
138 }
139
140 return S_OK;
141 }
142
143 // Check to see whether an instance is already running
144 HRESULT SingleInstance::CheckAlreadyRunning(
145 const TCHAR* id,
146 bool* already_running,
147 bool* already_running_in_different_session) {
148 ASSERT1(id);
149 ASSERT1(already_running);
150
151 CString mutex_id;
152
153 // Open a user level mutex
154 CreateSyncId(id, SYNC_USER, &mutex_id);
155 RET_IF_FAILED(OpenInstanceMutex(mutex_id, already_running));
156
157 // Open a global mutex
158 if (already_running_in_different_session) {
159 CreateSyncId(id, SYNC_GLOBAL, &mutex_id);
160 RET_IF_FAILED(OpenInstanceMutex(mutex_id,
161 already_running_in_different_session));
162 }
163
164 return S_OK;
165 }
166
167 // Open a mutex
168 HRESULT SingleInstance::OpenInstanceMutex(const TCHAR* mutex_id,
169 bool* already_running) {
170 ASSERT1(mutex_id && *mutex_id);
171 ASSERT1(already_running);
172
173 *already_running = false;
174
175 scoped_handle mutex_handle(::OpenMutex(NULL, false, mutex_id));
176 DWORD last_error = ::GetLastError();
177
178 if (get(mutex_handle) || last_error == ERROR_ACCESS_DENIED) {
179 UTIL_LOG(L3, (_T("[SingleInstance::OpenInstanceMutex]")
180 _T("[already running][0x%x]"), last_error));
181 *already_running = true;
182 return S_OK;
183 }
184
185 if (last_error != ERROR_FILE_NOT_FOUND) {
186 HRESULT hr = HRESULT_FROM_WIN32(last_error);
187 ASSERT(false, (_T("[SingleInstance::OpenInstanceMutex]")
188 _T("[failed to open mutex][%s][0x%x]"), mutex_id, hr));
189 return hr;
190 }
191
192 return S_OK;
193 }
194
195 } // namespace omaha
196
OLDNEW
« no previous file with comments | « base/single_instance.h ('k') | base/singleton.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698