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 |