| 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 |