Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "chrome/installer/setup/setup_singleton.h" | |
| 6 | |
| 7 #include <Windows.h> | |
| 8 | |
| 9 #include <algorithm> | |
| 10 | |
| 11 #include "base/files/file_path.h" | |
| 12 #include "base/logging.h" | |
| 13 #include "base/strings/string16.h" | |
| 14 #include "base/time/time.h" | |
| 15 #include "chrome/installer/util/installer_state.h" | |
| 16 | |
| 17 namespace installer { | |
| 18 | |
| 19 namespace { | |
| 20 | |
| 21 base::string16 ReplaceBackslashes(const base::string16& path) { | |
| 22 base::string16 path_without_backslashes(path); | |
| 23 std::replace(path_without_backslashes.begin(), path_without_backslashes.end(), | |
| 24 L'\\', L'/'); | |
| 25 return path_without_backslashes; | |
| 26 } | |
| 27 | |
| 28 } // namespace | |
| 29 | |
| 30 SetupSingleton::SetupSingleton(const InstallerState& installer_state) | |
|
grt (UTC plus 2)
2016/08/31 12:03:47
perhaps this should take InstallerState and Instal
fdoray
2016/08/31 19:14:21
Done.
| |
| 31 : SetupSingleton(installer_state.target_path(), | |
| 32 installer_state.system_install()) {} | |
| 33 | |
| 34 SetupSingleton::SetupSingleton(const base::FilePath& install_dir, | |
| 35 bool system_install) { | |
| 36 // Create mutexes and event. | |
| 37 const base::string16 name_prefix = system_install ? L"Global\\" : L"Local\\"; | |
|
grt (UTC plus 2)
2016/08/31 12:03:47
while i'm not sure if/how a user could be logged o
fdoray
2016/08/31 19:14:21
Done.
| |
| 38 const base::string16 install_dir_without_backslashes( | |
| 39 ReplaceBackslashes(install_dir.value())); | |
| 40 | |
| 41 const base::string16 setup_mutex_name = | |
| 42 name_prefix + L"ChromeSetupMutex_" + install_dir_without_backslashes; | |
| 43 setup_mutex_.Set(::CreateMutex(nullptr, FALSE, setup_mutex_name.c_str())); | |
|
grt (UTC plus 2)
2016/08/31 12:03:47
a mutex's name is limited to MAX_PATH chars. to av
fdoray
2016/08/31 19:14:21
Done.
| |
| 44 DCHECK(setup_mutex_.IsValid()); | |
| 45 | |
| 46 const base::string16 exit_event_name = | |
|
grt (UTC plus 2)
2016/08/31 12:03:47
is the exit event only used for testing? if so, co
fdoray
2016/08/31 19:14:21
No. The cleanup process will call Wait() between a
| |
| 47 name_prefix + L"ChromeSetupExitEvent_" + install_dir_without_backslashes; | |
| 48 exit_event_.reset(new base::WaitableEvent(base::win::ScopedHandle( | |
| 49 ::CreateEvent(nullptr, TRUE, FALSE, exit_event_name.c_str())))); | |
| 50 | |
| 51 // The exit mutex must be acquired before signaling |exit_event_| and released | |
| 52 // after acquiring |setup_mutex_|. It ensures that a single SetupSingleton | |
| 53 // signals the exit event and waits for |setup_mutex_| to be released at a | |
| 54 // time. | |
| 55 const base::string16 exit_event_mutex_name = name_prefix + | |
| 56 L"ChromeSetupExitEventMutex_" + | |
| 57 install_dir_without_backslashes; | |
| 58 base::win::ScopedHandle exit_event_mutex( | |
| 59 ::CreateMutex(nullptr, FALSE, exit_event_mutex_name.c_str())); | |
| 60 DCHECK(exit_event_mutex.IsValid()); | |
| 61 | |
| 62 // Ask existing SetupSingletons to release |setup_mutex_| as soon as possible. | |
| 63 const DWORD wait_exit_event_mutex_return_value = | |
| 64 ::WaitForSingleObject(exit_event_mutex.Get(), INFINITE); | |
| 65 DCHECK(wait_exit_event_mutex_return_value == WAIT_ABANDONED || | |
| 66 wait_exit_event_mutex_return_value == WAIT_OBJECT_0); | |
| 67 exit_event_->Signal(); | |
| 68 | |
| 69 // Acquire |setup_mutex_|. | |
| 70 const DWORD wait_setup_mutex_return_value = | |
| 71 ::WaitForSingleObject(setup_mutex_.Get(), INFINITE); | |
|
fdoray
2016/08/30 20:07:53
This could block forever if a process hangs while
grt (UTC plus 2)
2016/08/31 12:03:47
That's not so good.
fdoray
2016/08/31 19:14:21
setup.exe now returns SETUP_SINGLETON_ACQUISITION_
| |
| 72 DCHECK(wait_setup_mutex_return_value == WAIT_ABANDONED || | |
| 73 wait_setup_mutex_return_value == WAIT_OBJECT_0); | |
| 74 exit_event_->Reset(); | |
| 75 const BOOL release_mutex_return_value = | |
| 76 ::ReleaseMutex(exit_event_mutex.Get()); | |
| 77 DCHECK(release_mutex_return_value); | |
| 78 } | |
| 79 | |
| 80 SetupSingleton::~SetupSingleton() { | |
| 81 ::ReleaseMutex(setup_mutex_.Get()); | |
|
grt (UTC plus 2)
2016/08/31 12:03:47
how about using base::ScopedGeneric for auto-relea
fdoray
2016/08/31 19:14:21
Having a class that takes care of acquiring + auto
| |
| 82 } | |
| 83 | |
| 84 bool SetupSingleton::Wait(const base::TimeDelta& max_time) { | |
| 85 const bool exit_event_signaled = exit_event_->TimedWait(max_time); | |
| 86 return exit_event_signaled; | |
| 87 } | |
| 88 | |
| 89 } // namespace installer | |
| OLD | NEW |