Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1042)

Side by Side Diff: chrome/common/service_process_util_win.cc

Issue 7736002: Make the mac service process handling code clean itself up properly as far as launchd is concerned. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: add launchd test Created 9 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « chrome/common/service_process_util_unittest.cc ('k') | chrome/service/service_process.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/common/service_process_util.h" 5 #include "chrome/common/service_process_util.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/path_service.h" 11 #include "base/path_service.h"
12 #include "base/string16.h" 12 #include "base/string16.h"
13 #include "base/task.h" 13 #include "base/task.h"
14 #include "base/utf_string_conversions.h" 14 #include "base/utf_string_conversions.h"
15 #include "base/win/object_watcher.h" 15 #include "base/win/object_watcher.h"
16 #include "base/win/scoped_handle.h" 16 #include "base/win/scoped_handle.h"
17 #include "base/win/win_util.h" 17 #include "base/win/win_util.h"
18 #include "chrome/common/chrome_paths.h" 18 #include "chrome/common/chrome_paths.h"
19 #include "chrome/common/chrome_switches.h" 19 #include "chrome/common/chrome_switches.h"
20 20
21 namespace { 21 namespace {
22 22
23 const char* kTerminateEventSuffix = "_service_terminate_evt";
24
23 string16 GetServiceProcessReadyEventName() { 25 string16 GetServiceProcessReadyEventName() {
24 return UTF8ToWide( 26 return UTF8ToWide(
25 GetServiceProcessScopedVersionedName("_service_ready")); 27 GetServiceProcessScopedVersionedName("_service_ready"));
26 } 28 }
27 29
28 string16 GetServiceProcessShutdownEventName() { 30 string16 GetServiceProcessTerminateEventName() {
29 return UTF8ToWide( 31 return UTF8ToWide(
30 GetServiceProcessScopedVersionedName("_service_shutdown_evt")); 32 GetServiceProcessScopedVersionedName(kTerminateEventSuffix));
31 } 33 }
32 34
33 std::string GetServiceProcessAutoRunKey() { 35 std::string GetServiceProcessAutoRunKey() {
34 return GetServiceProcessScopedName("_service_run"); 36 return GetServiceProcessScopedName("_service_run");
35 } 37 }
36 38
37 // Returns the name of the autotun reg value that we used to use for older 39 // Returns the name of the autotun reg value that we used to use for older
38 // versions of Chrome. 40 // versions of Chrome.
39 std::string GetObsoleteServiceProcessAutoRunKey() { 41 std::string GetObsoleteServiceProcessAutoRunKey() {
40 FilePath user_data_dir; 42 FilePath user_data_dir;
41 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); 43 PathService::Get(chrome::DIR_USER_DATA, &user_data_dir);
42 std::string scoped_name = WideToUTF8(user_data_dir.value()); 44 std::string scoped_name = WideToUTF8(user_data_dir.value());
43 std::replace(scoped_name.begin(), scoped_name.end(), '\\', '!'); 45 std::replace(scoped_name.begin(), scoped_name.end(), '\\', '!');
44 std::replace(scoped_name.begin(), scoped_name.end(), '/', '!'); 46 std::replace(scoped_name.begin(), scoped_name.end(), '/', '!');
45 scoped_name.append("_service_run"); 47 scoped_name.append("_service_run");
46 return scoped_name; 48 return scoped_name;
47 } 49 }
48 50
49 class ServiceProcessShutdownMonitor 51 class ServiceProcessTerminateMonitor
50 : public base::win::ObjectWatcher::Delegate { 52 : public base::win::ObjectWatcher::Delegate {
51 public: 53 public:
52 explicit ServiceProcessShutdownMonitor(Task* shutdown_task) 54 explicit ServiceProcessTerminateMonitor(Task* terminate_task)
53 : shutdown_task_(shutdown_task) { 55 : terminate_task_(terminate_task) {
54 } 56 }
55 void Start() { 57 void Start() {
56 string16 event_name = GetServiceProcessShutdownEventName(); 58 string16 event_name = GetServiceProcessTerminateEventName();
57 CHECK(event_name.length() <= MAX_PATH); 59 CHECK(event_name.length() <= MAX_PATH);
58 shutdown_event_.Set(CreateEvent(NULL, TRUE, FALSE, event_name.c_str())); 60 terminate_event_.Set(CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
59 watcher_.StartWatching(shutdown_event_.Get(), this); 61 watcher_.StartWatching(terminate_event_.Get(), this);
60 } 62 }
61 63
62 // base::ObjectWatcher::Delegate implementation. 64 // base::ObjectWatcher::Delegate implementation.
63 virtual void OnObjectSignaled(HANDLE object) { 65 virtual void OnObjectSignaled(HANDLE object) {
64 shutdown_task_->Run(); 66 terminate_task_->Run();
65 shutdown_task_.reset(); 67 terminate_task_.reset();
66 } 68 }
67 69
68 private: 70 private:
69 base::win::ScopedHandle shutdown_event_; 71 base::win::ScopedHandle terminate_event_;
70 base::win::ObjectWatcher watcher_; 72 base::win::ObjectWatcher watcher_;
71 scoped_ptr<Task> shutdown_task_; 73 scoped_ptr<Task> terminate_task_;
72 }; 74 };
73 75
74 } // namespace 76 } // namespace
75 77
76 // Gets the name of the service process IPC channel. 78 // Gets the name of the service process IPC channel.
77 IPC::ChannelHandle GetServiceProcessChannel() { 79 IPC::ChannelHandle GetServiceProcessChannel() {
78 return GetServiceProcessScopedVersionedName("_service_ipc"); 80 return GetServiceProcessScopedVersionedName("_service_ipc");
79 } 81 }
80 82
81 bool ForceServiceProcessShutdown(const std::string& version, 83 bool ForceServiceProcessShutdown(const std::string& version,
82 base::ProcessId process_id) { 84 base::ProcessId process_id) {
83 base::win::ScopedHandle shutdown_event; 85 base::win::ScopedHandle terminate_event;
84 std::string versioned_name = version; 86 std::string versioned_name = version;
85 versioned_name.append("_service_shutdown_evt"); 87 versioned_name.append(kTerminateEventSuffix);
86 string16 event_name = 88 string16 event_name =
87 UTF8ToWide(GetServiceProcessScopedName(versioned_name)); 89 UTF8ToWide(GetServiceProcessScopedName(versioned_name));
88 shutdown_event.Set(OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name.c_str())); 90 terminate_event.Set(OpenEvent(EVENT_MODIFY_STATE, FALSE, event_name.c_str()));
89 if (!shutdown_event.IsValid()) 91 if (!terminate_event.IsValid())
90 return false; 92 return false;
91 SetEvent(shutdown_event.Get()); 93 SetEvent(terminate_event.Get());
92 return true; 94 return true;
93 } 95 }
94 96
95 bool CheckServiceProcessReady() { 97 bool CheckServiceProcessReady() {
96 string16 event_name = GetServiceProcessReadyEventName(); 98 string16 event_name = GetServiceProcessReadyEventName();
97 base::win::ScopedHandle event( 99 base::win::ScopedHandle event(
98 OpenEvent(SYNCHRONIZE | READ_CONTROL, false, event_name.c_str())); 100 OpenEvent(SYNCHRONIZE | READ_CONTROL, false, event_name.c_str()));
99 if (!event.IsValid()) 101 if (!event.IsValid())
100 return false; 102 return false;
101 // Check if the event is signaled. 103 // Check if the event is signaled.
102 return WaitForSingleObject(event, 0) == WAIT_OBJECT_0; 104 return WaitForSingleObject(event, 0) == WAIT_OBJECT_0;
103 } 105 }
104 106
105 struct ServiceProcessState::StateData { 107 struct ServiceProcessState::StateData {
106 // An event that is signaled when a service process is ready. 108 // An event that is signaled when a service process is ready.
107 base::win::ScopedHandle ready_event; 109 base::win::ScopedHandle ready_event;
108 scoped_ptr<ServiceProcessShutdownMonitor> shutdown_monitor; 110 scoped_ptr<ServiceProcessTerminateMonitor> terminate_monitor;
109 }; 111 };
110 112
111 void ServiceProcessState::CreateState() { 113 void ServiceProcessState::CreateState() {
112 CHECK(!state_); 114 CHECK(!state_);
113 state_ = new StateData; 115 state_ = new StateData;
114 } 116 }
115 117
116 bool ServiceProcessState::TakeSingletonLock() { 118 bool ServiceProcessState::TakeSingletonLock() {
117 DCHECK(state_); 119 DCHECK(state_);
118 string16 event_name = GetServiceProcessReadyEventName(); 120 string16 event_name = GetServiceProcessReadyEventName();
119 CHECK(event_name.length() <= MAX_PATH); 121 CHECK(event_name.length() <= MAX_PATH);
120 base::win::ScopedHandle service_process_ready_event; 122 base::win::ScopedHandle service_process_ready_event;
121 service_process_ready_event.Set( 123 service_process_ready_event.Set(
122 CreateEvent(NULL, TRUE, FALSE, event_name.c_str())); 124 CreateEvent(NULL, TRUE, FALSE, event_name.c_str()));
123 DWORD error = GetLastError(); 125 DWORD error = GetLastError();
124 if ((error == ERROR_ALREADY_EXISTS) || (error == ERROR_ACCESS_DENIED)) 126 if ((error == ERROR_ALREADY_EXISTS) || (error == ERROR_ACCESS_DENIED))
125 return false; 127 return false;
126 DCHECK(service_process_ready_event.IsValid()); 128 DCHECK(service_process_ready_event.IsValid());
127 state_->ready_event.Set(service_process_ready_event.Take()); 129 state_->ready_event.Set(service_process_ready_event.Take());
128 return true; 130 return true;
129 } 131 }
130 132
131 bool ServiceProcessState::SignalReady( 133 bool ServiceProcessState::SignalReady(
132 base::MessageLoopProxy* message_loop_proxy, Task* shutdown_task) { 134 base::MessageLoopProxy* message_loop_proxy, Task* terminate_task) {
133 DCHECK(state_); 135 DCHECK(state_);
134 DCHECK(state_->ready_event.IsValid()); 136 DCHECK(state_->ready_event.IsValid());
135 scoped_ptr<Task> scoped_shutdown_task(shutdown_task); 137 scoped_ptr<Task> scoped_terminate_task(terminate_task);
136 if (!SetEvent(state_->ready_event.Get())) { 138 if (!SetEvent(state_->ready_event.Get())) {
137 return false; 139 return false;
138 } 140 }
139 if (shutdown_task) { 141 if (terminate_task) {
140 state_->shutdown_monitor.reset( 142 state_->terminate_monitor.reset(
141 new ServiceProcessShutdownMonitor(scoped_shutdown_task.release())); 143 new ServiceProcessTerminateMonitor(scoped_terminate_task.release()));
142 state_->shutdown_monitor->Start(); 144 state_->terminate_monitor->Start();
143 } 145 }
144 return true; 146 return true;
145 } 147 }
146 148
147 bool ServiceProcessState::AddToAutoRun() { 149 bool ServiceProcessState::AddToAutoRun() {
148 DCHECK(autorun_command_line_.get()); 150 DCHECK(autorun_command_line_.get());
149 // Remove the old autorun value first because we changed the naming scheme 151 // Remove the old autorun value first because we changed the naming scheme
150 // for the autorun value name. 152 // for the autorun value name.
151 base::win::RemoveCommandFromAutoRun( 153 base::win::RemoveCommandFromAutoRun(
152 HKEY_CURRENT_USER, UTF8ToWide(GetObsoleteServiceProcessAutoRunKey())); 154 HKEY_CURRENT_USER, UTF8ToWide(GetObsoleteServiceProcessAutoRunKey()));
153 return base::win::AddCommandToAutoRun( 155 return base::win::AddCommandToAutoRun(
154 HKEY_CURRENT_USER, 156 HKEY_CURRENT_USER,
155 UTF8ToWide(GetServiceProcessAutoRunKey()), 157 UTF8ToWide(GetServiceProcessAutoRunKey()),
156 autorun_command_line_->GetCommandLineString()); 158 autorun_command_line_->GetCommandLineString());
157 } 159 }
158 160
159 bool ServiceProcessState::RemoveFromAutoRun() { 161 bool ServiceProcessState::RemoveFromAutoRun() {
160 // Remove the old autorun value first because we changed the naming scheme 162 // Remove the old autorun value first because we changed the naming scheme
161 // for the autorun value name. 163 // for the autorun value name.
162 base::win::RemoveCommandFromAutoRun( 164 base::win::RemoveCommandFromAutoRun(
163 HKEY_CURRENT_USER, UTF8ToWide(GetObsoleteServiceProcessAutoRunKey())); 165 HKEY_CURRENT_USER, UTF8ToWide(GetObsoleteServiceProcessAutoRunKey()));
164 return base::win::RemoveCommandFromAutoRun( 166 return base::win::RemoveCommandFromAutoRun(
165 HKEY_CURRENT_USER, UTF8ToWide(GetServiceProcessAutoRunKey())); 167 HKEY_CURRENT_USER, UTF8ToWide(GetServiceProcessAutoRunKey()));
166 } 168 }
167 169
168 void ServiceProcessState::TearDownState() { 170 void ServiceProcessState::TearDownState() {
169 delete state_; 171 delete state_;
170 state_ = NULL; 172 state_ = NULL;
171 } 173 }
OLDNEW
« no previous file with comments | « chrome/common/service_process_util_unittest.cc ('k') | chrome/service/service_process.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698