Index: chrome/browser/process_singleton_win.cc |
diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc |
index e92a5f2cbe655dd85f82fbeacc2b88a26724ed03..d71e67cbe1dcdb0b26f11911960ddea5c2aeb489 100644 |
--- a/chrome/browser/process_singleton_win.cc |
+++ b/chrome/browser/process_singleton_win.cc |
@@ -102,18 +102,37 @@ ProcessSingleton::ProcessSingleton(const FilePath& user_data_dir) |
remote_window_ = FindWindowEx(HWND_MESSAGE, NULL, |
chrome::kMessageWindowClass, |
user_data_dir.value().c_str()); |
- if (!remote_window_) |
- Create(); |
+ if (!remote_window_) { |
+ HINSTANCE hinst = |
+ base::GetModuleFromAddress(ProcessSingleton::WndProcStatic); |
+ |
+ WNDCLASSEX wc = {0}; |
+ wc.cbSize = sizeof(wc); |
+ wc.lpfnWndProc = |
+ base::win::WrappedWindowProc<ProcessSingleton::WndProcStatic>; |
+ wc.hInstance = hinst; |
+ wc.lpszClassName = chrome::kMessageWindowClass; |
+ ATOM clazz = RegisterClassEx(&wc); |
+ DCHECK(clazz); |
+ |
+ FilePath user_data_dir; |
+ PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
+ |
+ // Set the window's title to the path of our user data directory so other |
+ // Chrome instances can decide if they should forward to us or not. |
+ window_ = CreateWindow(chrome::kMessageWindowClass, |
+ user_data_dir.value().c_str(), |
+ 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0); |
+ ui::CheckWindowCreated(window_); |
+ ui::SetWindowUserData(window_, this); |
+ } |
BOOL success = ReleaseMutex(only_me); |
DCHECK(success) << "GetLastError = " << GetLastError(); |
} |
} |
ProcessSingleton::~ProcessSingleton() { |
- if (window_) { |
- DestroyWindow(window_); |
- UnregisterClass(chrome::kMessageWindowClass, GetModuleHandle(NULL)); |
- } |
+ Cleanup(); |
} |
ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcess() { |
@@ -197,42 +216,29 @@ ProcessSingleton::NotifyResult ProcessSingleton::NotifyOtherProcessOrCreate() { |
NotifyResult result = NotifyOtherProcess(); |
if (result != PROCESS_NONE) |
return result; |
- return Create() ? PROCESS_NONE : PROFILE_IN_USE; |
+ return window_ ? PROCESS_NONE : PROFILE_IN_USE; |
} |
-// For windows, there is no need to call Create() since the call is made in |
+// On Windows, there is no need to call Create() since the call is made in |
// the constructor but to avoid having more platform specific code in |
// browser_main.cc we tolerate a second call which will do nothing. |
bool ProcessSingleton::Create() { |
DCHECK(!remote_window_); |
- if (window_) |
- return true; |
- |
- HINSTANCE hinst = GetModuleHandle(NULL); |
- |
- WNDCLASSEX wc = {0}; |
- wc.cbSize = sizeof(wc); |
- wc.lpfnWndProc = |
- base::win::WrappedWindowProc<ProcessSingleton::WndProcStatic>; |
- wc.hInstance = hinst; |
- wc.lpszClassName = chrome::kMessageWindowClass; |
- ATOM clazz = RegisterClassEx(&wc); |
- DCHECK(clazz); |
- |
- FilePath user_data_dir; |
- PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); |
- |
- // Set the window's title to the path of our user data directory so other |
- // Chrome instances can decide if they should forward to us or not. |
- window_ = CreateWindow(chrome::kMessageWindowClass, |
- user_data_dir.value().c_str(), |
- 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, 0); |
- ui::CheckWindowCreated(window_); |
- ui::SetWindowUserData(window_, this); |
- return true; |
+ return window_ != NULL; |
} |
void ProcessSingleton::Cleanup() { |
+ // Window classes registered by DLLs are not cleaned up automatically on |
+ // process exit, so we must unregister at the earliest chance possible. |
+ // During the fast shutdown sequence, ProcessSingleton::Cleanup() is |
+ // called if our process was the first to start. Therefore we try cleaning |
+ // up here, and again in the destructor if needed to catch as many cases |
+ // as possible. |
+ if (window_) { |
+ DestroyWindow(window_); |
+ UnregisterClass(chrome::kMessageWindowClass, GetModuleHandle(NULL)); |
+ window_ = NULL; |
+ } |
} |
LRESULT ProcessSingleton::OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds) { |