| Index: chrome/browser/process_singleton_win.cc
|
| diff --git a/chrome/browser/process_singleton_win.cc b/chrome/browser/process_singleton_win.cc
|
| index 74c063d98d9a24c5a7ba2e1b86c117467bdca6b5..4d20415b10d1a88f3d4eeecf19e6f9345216f262 100644
|
| --- a/chrome/browser/process_singleton_win.cc
|
| +++ b/chrome/browser/process_singleton_win.cc
|
| @@ -91,6 +91,8 @@ bool ProcessSingleton::EscapeVirtualization(const FilePath& user_data_dir) {
|
| }
|
|
|
| // Look for a Chrome instance that uses the same profile directory.
|
| +// If there isn't one, create a message window with its title set to
|
| +// the profile directory path.
|
| ProcessSingleton::ProcessSingleton(const FilePath& user_data_dir)
|
| : window_(NULL), locked_(false), foreground_window_(NULL),
|
| is_virtualized_(false) {
|
| @@ -120,18 +122,34 @@ 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(&ThunkWndProc);
|
| +
|
| + WNDCLASSEX wc = {0};
|
| + wc.cbSize = sizeof(wc);
|
| + wc.lpfnWndProc = base::win::WrappedWindowProc<ThunkWndProc>;
|
| + 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(MAKEINTATOM(clazz),
|
| + user_data_dir.value().c_str(),
|
| + 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, this);
|
| + CHECK(window_);
|
| + }
|
| 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() {
|
| @@ -215,45 +233,31 @@ 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
|
| -// the constructor but to avoid having more platform specific code in
|
| -// browser_main.cc we tolerate a second call which will do nothing.
|
| +// On Windows, there is no need to call Create() since the message
|
| +// window is created in the constructor but to avoid having more
|
| +// platform specific code in browser_main.cc we tolerate calls to
|
| +// Create(), which will do nothing.
|
| bool ProcessSingleton::Create() {
|
| DCHECK(!remote_window_);
|
| - if (window_)
|
| - return true;
|
| -
|
| - HINSTANCE hinst = 0;
|
| - if (!::GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
|
| - reinterpret_cast<char*>(&ThunkWndProc),
|
| - &hinst)) {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - WNDCLASSEX wc = {0};
|
| - wc.cbSize = sizeof(wc);
|
| - wc.lpfnWndProc = base::win::WrappedWindowProc<ThunkWndProc>;
|
| - 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(MAKEINTATOM(clazz),
|
| - user_data_dir.value().c_str(),
|
| - 0, 0, 0, 0, 0, HWND_MESSAGE, 0, hinst, this);
|
| - CHECK(window_);
|
| - 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,
|
| + base::GetModuleFromAddress(&ThunkWndProc));
|
| + window_ = NULL;
|
| + }
|
| }
|
|
|
| LRESULT ProcessSingleton::OnCopyData(HWND hwnd, const COPYDATASTRUCT* cds) {
|
|
|