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/eintr_wrapper.h" | 8 #include "base/eintr_wrapper.h" |
9 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
10 | 10 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
52 PLOG(ERROR) << "write"; | 52 PLOG(ERROR) << "write"; |
53 } | 53 } |
54 } | 54 } |
55 | 55 |
56 ServiceProcessState::StateData::StateData() : set_action_(false) { | 56 ServiceProcessState::StateData::StateData() : set_action_(false) { |
57 memset(sockets_, -1, sizeof(sockets_)); | 57 memset(sockets_, -1, sizeof(sockets_)); |
58 memset(&old_action_, 0, sizeof(old_action_)); | 58 memset(&old_action_, 0, sizeof(old_action_)); |
59 } | 59 } |
60 | 60 |
61 void ServiceProcessState::StateData::SignalReady() { | 61 void ServiceProcessState::StateData::SignalReady() { |
| 62 CHECK_EQ(g_signal_socket, -1); |
62 CHECK(MessageLoopForIO::current()->WatchFileDescriptor( | 63 CHECK(MessageLoopForIO::current()->WatchFileDescriptor( |
63 sockets_[0], true, MessageLoopForIO::WATCH_READ, | 64 sockets_[0], true, MessageLoopForIO::WATCH_READ, |
64 &watcher_, shut_down_monitor_.get())); | 65 &watcher_, shut_down_monitor_.get())); |
65 g_signal_socket = sockets_[1]; | 66 g_signal_socket = sockets_[1]; |
66 | 67 |
67 // Set up signal handler for SIGTERM. | 68 // Set up signal handler for SIGTERM. |
68 struct sigaction action; | 69 struct sigaction action; |
69 action.sa_sigaction = SigTermHandler; | 70 action.sa_sigaction = SigTermHandler; |
70 sigemptyset(&action.sa_mask); | 71 sigemptyset(&action.sa_mask); |
71 action.sa_flags = SA_SIGINFO; | 72 action.sa_flags = SA_SIGINFO; |
(...skipping 25 matching lines...) Expand all Loading... |
97 if (sockets_[1] != -1) { | 98 if (sockets_[1] != -1) { |
98 if (HANDLE_EINTR(close(sockets_[1]))) { | 99 if (HANDLE_EINTR(close(sockets_[1]))) { |
99 PLOG(ERROR) << "close"; | 100 PLOG(ERROR) << "close"; |
100 } | 101 } |
101 } | 102 } |
102 if (set_action_) { | 103 if (set_action_) { |
103 if (sigaction(SIGTERM, &old_action_, NULL) < 0) { | 104 if (sigaction(SIGTERM, &old_action_, NULL) < 0) { |
104 PLOG(ERROR) << "sigaction"; | 105 PLOG(ERROR) << "sigaction"; |
105 } | 106 } |
106 } | 107 } |
| 108 g_signal_socket = -1; |
107 } | 109 } |
108 | 110 |
109 void ServiceProcessState::CreateState() { | 111 void ServiceProcessState::CreateState() { |
110 CHECK(!state_); | 112 CHECK(!state_); |
111 state_ = new StateData; | 113 state_ = new StateData; |
112 | 114 |
113 // Explicitly adding a reference here (and removing it in TearDownState) | 115 // Explicitly adding a reference here (and removing it in TearDownState) |
114 // because StateData is refcounted on Mac and Linux so that methods can | 116 // because StateData is refcounted on Mac and Linux so that methods can |
115 // be called on other threads. | 117 // be called on other threads. |
116 // It is not refcounted on Windows at this time. | 118 // It is not refcounted on Windows at this time. |
117 state_->AddRef(); | 119 state_->AddRef(); |
118 } | 120 } |
119 | 121 |
120 bool ServiceProcessState::SignalReady( | 122 bool ServiceProcessState::SignalReady( |
121 base::MessageLoopProxy* message_loop_proxy, Task* shutdown_task) { | 123 base::MessageLoopProxy* message_loop_proxy, Task* shutdown_task) { |
122 CHECK(state_); | 124 CHECK(state_); |
123 CHECK_EQ(g_signal_socket, -1); | |
124 | 125 |
125 scoped_ptr<Task> scoped_shutdown_task(shutdown_task); | 126 scoped_ptr<Task> scoped_shutdown_task(shutdown_task); |
126 #if defined(OS_LINUX) | 127 #if defined(OS_LINUX) |
127 state_->running_lock_.reset(TakeServiceRunningLock(true)); | 128 state_->running_lock_.reset(TakeServiceRunningLock(true)); |
128 if (state_->running_lock_.get() == NULL) { | 129 if (state_->running_lock_.get() == NULL) { |
129 return false; | 130 return false; |
130 } | 131 } |
131 #endif // OS_LINUX | 132 #endif // OS_LINUX |
132 state_->shut_down_monitor_.reset( | 133 state_->shut_down_monitor_.reset( |
133 new ServiceProcessShutdownMonitor(scoped_shutdown_task.release())); | 134 new ServiceProcessShutdownMonitor(scoped_shutdown_task.release())); |
134 if (pipe(state_->sockets_) < 0) { | 135 if (pipe(state_->sockets_) < 0) { |
135 PLOG(ERROR) << "pipe"; | 136 PLOG(ERROR) << "pipe"; |
136 return false; | 137 return false; |
137 } | 138 } |
138 message_loop_proxy->PostTask(FROM_HERE, | 139 message_loop_proxy->PostTask(FROM_HERE, |
139 NewRunnableMethod(state_, &ServiceProcessState::StateData::SignalReady)); | 140 NewRunnableMethod(state_, &ServiceProcessState::StateData::SignalReady)); |
140 return true; | 141 return true; |
141 } | 142 } |
142 | 143 |
143 void ServiceProcessState::TearDownState() { | 144 void ServiceProcessState::TearDownState() { |
144 g_signal_socket = -1; | |
145 if (state_) { | 145 if (state_) { |
146 state_->Release(); | 146 state_->Release(); |
147 state_ = NULL; | 147 state_ = NULL; |
148 } | 148 } |
149 } | 149 } |
OLD | NEW |