OLD | NEW |
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_posix.h" | 5 #include "chrome/common/service_process_util_posix.h" |
6 | 6 |
7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" |
8 #include "base/eintr_wrapper.h" | 9 #include "base/eintr_wrapper.h" |
9 #include "base/message_loop_proxy.h" | 10 #include "base/message_loop_proxy.h" |
10 #include "base/synchronization/waitable_event.h" | 11 #include "base/synchronization/waitable_event.h" |
11 | 12 |
12 namespace { | 13 namespace { |
13 int g_signal_socket = -1; | 14 int g_signal_socket = -1; |
14 } | 15 } |
15 | 16 |
16 ServiceProcessTerminateMonitor::ServiceProcessTerminateMonitor( | 17 ServiceProcessTerminateMonitor::ServiceProcessTerminateMonitor( |
17 Task* terminate_task) | 18 const base::Closure& terminate_task) |
18 : terminate_task_(terminate_task) { | 19 : terminate_task_(terminate_task) { |
19 } | 20 } |
20 | 21 |
21 ServiceProcessTerminateMonitor::~ServiceProcessTerminateMonitor() { | 22 ServiceProcessTerminateMonitor::~ServiceProcessTerminateMonitor() { |
22 } | 23 } |
23 | 24 |
24 void ServiceProcessTerminateMonitor::OnFileCanReadWithoutBlocking(int fd) { | 25 void ServiceProcessTerminateMonitor::OnFileCanReadWithoutBlocking(int fd) { |
25 if (terminate_task_.get()) { | 26 if (!terminate_task_.is_null()) { |
26 int buffer; | 27 int buffer; |
27 int length = read(fd, &buffer, sizeof(buffer)); | 28 int length = read(fd, &buffer, sizeof(buffer)); |
28 if ((length == sizeof(buffer)) && (buffer == kTerminateMessage)) { | 29 if ((length == sizeof(buffer)) && (buffer == kTerminateMessage)) { |
29 terminate_task_->Run(); | 30 terminate_task_.Run(); |
30 terminate_task_.reset(); | 31 terminate_task_.Reset(); |
31 } else if (length > 0) { | 32 } else if (length > 0) { |
32 DLOG(ERROR) << "Unexpected read: " << buffer; | 33 DLOG(ERROR) << "Unexpected read: " << buffer; |
33 } else if (length == 0) { | 34 } else if (length == 0) { |
34 DLOG(ERROR) << "Unexpected fd close"; | 35 DLOG(ERROR) << "Unexpected fd close"; |
35 } else if (length < 0) { | 36 } else if (length < 0) { |
36 DPLOG(ERROR) << "read"; | 37 DPLOG(ERROR) << "read"; |
37 } | 38 } |
38 } | 39 } |
39 } | 40 } |
40 | 41 |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
129 state_ = new StateData; | 130 state_ = new StateData; |
130 | 131 |
131 // Explicitly adding a reference here (and removing it in TearDownState) | 132 // Explicitly adding a reference here (and removing it in TearDownState) |
132 // because StateData is refcounted on Mac and Linux so that methods can | 133 // because StateData is refcounted on Mac and Linux so that methods can |
133 // be called on other threads. | 134 // be called on other threads. |
134 // It is not refcounted on Windows at this time. | 135 // It is not refcounted on Windows at this time. |
135 state_->AddRef(); | 136 state_->AddRef(); |
136 } | 137 } |
137 | 138 |
138 bool ServiceProcessState::SignalReady( | 139 bool ServiceProcessState::SignalReady( |
139 base::MessageLoopProxy* message_loop_proxy, Task* terminate_task) { | 140 base::MessageLoopProxy* message_loop_proxy, |
| 141 const base::Closure& terminate_task) { |
140 DCHECK(state_); | 142 DCHECK(state_); |
141 | 143 |
142 scoped_ptr<Task> scoped_terminate_task(terminate_task); | |
143 #if defined(OS_POSIX) && !defined(OS_MACOSX) | 144 #if defined(OS_POSIX) && !defined(OS_MACOSX) |
144 state_->running_lock_.reset(TakeServiceRunningLock(true)); | 145 state_->running_lock_.reset(TakeServiceRunningLock(true)); |
145 if (state_->running_lock_.get() == NULL) { | 146 if (state_->running_lock_.get() == NULL) { |
146 return false; | 147 return false; |
147 } | 148 } |
148 #endif | 149 #endif |
149 state_->terminate_monitor_.reset( | 150 state_->terminate_monitor_.reset( |
150 new ServiceProcessTerminateMonitor(scoped_terminate_task.release())); | 151 new ServiceProcessTerminateMonitor(terminate_task)); |
151 if (pipe(state_->sockets_) < 0) { | 152 if (pipe(state_->sockets_) < 0) { |
152 DPLOG(ERROR) << "pipe"; | 153 DPLOG(ERROR) << "pipe"; |
153 return false; | 154 return false; |
154 } | 155 } |
155 base::WaitableEvent signal_ready(true, false); | 156 base::WaitableEvent signal_ready(true, false); |
156 bool success = false; | 157 bool success = false; |
157 | 158 |
158 message_loop_proxy->PostTask(FROM_HERE, | 159 message_loop_proxy->PostTask(FROM_HERE, |
159 NewRunnableMethod(state_, &ServiceProcessState::StateData::SignalReady, | 160 base::Bind(&ServiceProcessState::StateData::SignalReady, |
160 &signal_ready, | 161 state_, |
161 &success)); | 162 &signal_ready, |
| 163 &success)); |
162 signal_ready.Wait(); | 164 signal_ready.Wait(); |
163 return success; | 165 return success; |
164 } | 166 } |
165 | 167 |
166 void ServiceProcessState::TearDownState() { | 168 void ServiceProcessState::TearDownState() { |
167 if (state_) { | 169 if (state_) { |
168 state_->Release(); | 170 state_->Release(); |
169 state_ = NULL; | 171 state_ = NULL; |
170 } | 172 } |
171 } | 173 } |
OLD | NEW |