OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/process_singleton.h" | 5 #include "chrome/browser/process_singleton.h" |
6 | 6 |
7 #include "base/base_paths.h" | 7 #include "base/base_paths.h" |
8 #include "base/command_line.h" | 8 #include "base/command_line.h" |
9 #include "base/file_path.h" | 9 #include "base/file_path.h" |
10 #include "base/path_service.h" | 10 #include "base/path_service.h" |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
95 DCHECK(result == WAIT_OBJECT_0) << "Result = " << result << | 95 DCHECK(result == WAIT_OBJECT_0) << "Result = " << result << |
96 "GetLastError = " << GetLastError(); | 96 "GetLastError = " << GetLastError(); |
97 | 97 |
98 // We now own the mutex so we are the only process that can create the | 98 // We now own the mutex so we are the only process that can create the |
99 // window at this time, but we must still check if someone created it | 99 // window at this time, but we must still check if someone created it |
100 // between the time where we looked for it above and the time the mutex | 100 // between the time where we looked for it above and the time the mutex |
101 // was given to us. | 101 // was given to us. |
102 remote_window_ = FindWindowEx(HWND_MESSAGE, NULL, | 102 remote_window_ = FindWindowEx(HWND_MESSAGE, NULL, |
103 chrome::kMessageWindowClass, | 103 chrome::kMessageWindowClass, |
104 user_data_dir.value().c_str()); | 104 user_data_dir.value().c_str()); |
105 if (!remote_window_) | 105 if (!remote_window_) { |
106 Create(); | 106 HINSTANCE hinst = |
| 107 base::GetModuleFromAddress(ProcessSingleton::WndProcStatic); |
| 108 |
| 109 WNDCLASSEX wc = {0}; |
| 110 wc.cbSize = sizeof(wc); |
| 111 wc.lpfnWndProc = |
| 112 base::win::WrappedWindowProc<ProcessSingleton::WndProcStatic>; |
| 113 wc.hInstance = hinst; |
| 114 wc.lpszClassName = chrome::kMessageWindowClass; |
| 115 ATOM clazz = RegisterClassEx(&wc); |
| 116 DCHECK(clazz); |
| 117 |
| 118 FilePath user_data_dir; |
| 119 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
| 120 |
| 121 // Set the window's title to the path of our user data directory so other |
| 122 // Chrome instances can decide if they should forward to us or not. |
| 123 window_ = CreateWindow(chrome::kMessageWindowClass, |
| 124 user_data_dir.value().c_str(), |
| 125 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0); |
| 126 ui::CheckWindowCreated(window_); |
| 127 ui::SetWindowUserData(window_, this); |
| 128 } |
107 BOOL success = ReleaseMutex(only_me); | 129 BOOL success = ReleaseMutex(only_me); |
108 DCHECK(success) << "GetLastError = " << GetLastError(); | 130 DCHECK(success) << "GetLastError = " << GetLastError(); |
109 } | 131 } |
110 } | 132 } |
111 | 133 |
112 ProcessSingleton::~ProcessSingleton() { | 134 ProcessSingleton::~ProcessSingleton() { |
113 if (window_) { | 135 Cleanup(); |
114 DestroyWindow(window_); | |
115 UnregisterClass(chrome::kMessageWindowClass, GetModuleHandle(NULL)); | |
116 } | |
117 } | 136 } |
118 | 137 |
119 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { | 138 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
120 if (is_virtualized_) | 139 if (is_virtualized_) |
121 return PROCESS_NOTIFIED; // We already spawned the process in this case. | 140 return PROCESS_NOTIFIED; // We already spawned the process in this case. |
122 else if (!remote_window_) | 141 else if (!remote_window_) |
123 return PROCESS_NONE; | 142 return PROCESS_NONE; |
124 | 143 |
125 // Found another window, send our command line to it | 144 // Found another window, send our command line to it |
126 // format is "START\0<<<current directory>>>\0<<<commandline>>>". | 145 // format is "START\0<<<current directory>>>\0<<<commandline>>>". |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
190 // Time to take action. Kill the browser process. | 209 // Time to take action. Kill the browser process. |
191 base::KillProcessById(process_id, content::RESULT_CODE_HUNG, true); | 210 base::KillProcessById(process_id, content::RESULT_CODE_HUNG, true); |
192 remote_window_ = NULL; | 211 remote_window_ = NULL; |
193 return PROCESS_NONE; | 212 return PROCESS_NONE; |
194 } | 213 } |
195 | 214 |
196 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { | 215 ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { |
197 NotifyResult result = NotifyOtherProcess(); | 216 NotifyResult result = NotifyOtherProcess(); |
198 if (result != PROCESS_NONE) | 217 if (result != PROCESS_NONE) |
199 return result; | 218 return result; |
200 return Create() ? PROCESS_NONE : PROFILE_IN_USE; | 219 return window_ ? PROCESS_NONE : PROFILE_IN_USE; |
201 } | 220 } |
202 | 221 |
203 // For windows, there is no need to call Create() since the call is made in | 222 // On Windows, there is no need to call Create() since the call is made in |
204 // the constructor but to avoid having more platform specific code in | 223 // the constructor but to avoid having more platform specific code in |
205 // browser_main.cc we tolerate a second call which will do nothing. | 224 // browser_main.cc we tolerate a second call which will do nothing. |
206 bool ProcessSingleton::Create() { | 225 bool ProcessSingleton::Create() { |
207 DCHECK(!remote_window_); | 226 DCHECK(!remote_window_); |
208 if (window_) | 227 return window_ != NULL; |
209 return true; | |
210 | |
211 HINSTANCE hinst = GetModuleHandle(NULL); | |
212 | |
213 WNDCLASSEX wc = {0}; | |
214 wc.cbSize = sizeof(wc); | |
215 wc.lpfnWndProc = | |
216 base::win::WrappedWindowProc<ProcessSingleton::WndProcStatic>; | |
217 wc.hInstance = hinst; | |
218 wc.lpszClassName = chrome::kMessageWindowClass; | |
219 ATOM clazz = RegisterClassEx(&wc); | |
220 DCHECK(clazz); | |
221 | |
222 FilePath user_data_dir; | |
223 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); | |
224 | |
225 // Set the window's title to the path of our user data directory so other | |
226 // Chrome instances can decide if they should forward to us or not. | |
227 window_ = CreateWindow(chrome::kMessageWindowClass, | |
228 user_data_dir.value().c_str(), | |
229 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0); | |
230 ui::CheckWindowCreated(window_); | |
231 ui::SetWindowUserData(window_, this); | |
232 return true; | |
233 } | 228 } |
234 | 229 |
235 void ProcessSingleton::Cleanup() { | 230 void ProcessSingleton::Cleanup() { |
| 231 // Window classes registered by DLLs are not cleaned up automatically on |
| 232 // process exit, so we must unregister at the earliest chance possible. |
| 233 // During the fast shutdown sequence, ProcessSingleton::Cleanup() is |
| 234 // called if our process was the first to start. Therefore we try cleaning |
| 235 // up here, and again in the destructor if needed to catch as many cases |
| 236 // as possible. |
| 237 if (window_) { |
| 238 DestroyWindow(window_); |
| 239 UnregisterClass(chrome::kMessageWindowClass, GetModuleHandle(NULL)); |
| 240 window_ = NULL; |
| 241 } |
236 } | 242 } |
237 | 243 |
238 LRESULT ProcessSingleton::OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds) { | 244 LRESULT ProcessSingleton::OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds) { |
239 // If locked, it means we are not ready to process this message because | 245 // If locked, it means we are not ready to process this message because |
240 // we are probably in a first run critical phase. | 246 // we are probably in a first run critical phase. |
241 if (locked_) { | 247 if (locked_) { |
242 #if defined(USE_AURA) | 248 #if defined(USE_AURA) |
243 NOTIMPLEMENTED(); | 249 NOTIMPLEMENTED(); |
244 #else | 250 #else |
245 // Attempt to place ourselves in the foreground / flash the task bar. | 251 // Attempt to place ourselves in the foreground / flash the task bar. |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
345 switch (message) { | 351 switch (message) { |
346 case WM_COPYDATA: | 352 case WM_COPYDATA: |
347 return OnCopyData(reinterpret_cast<HWND>(wparam), | 353 return OnCopyData(reinterpret_cast<HWND>(wparam), |
348 reinterpret_cast<COPYDATASTRUCT*>(lparam)); | 354 reinterpret_cast<COPYDATASTRUCT*>(lparam)); |
349 default: | 355 default: |
350 break; | 356 break; |
351 } | 357 } |
352 | 358 |
353 return ::DefWindowProc(hwnd, message, wparam, lparam); | 359 return ::DefWindowProc(hwnd, message, wparam, lparam); |
354 } | 360 } |
OLD | NEW |