OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "mojo/common/message_pump_mojo.h" | 5 #include "mojo/common/message_pump_mojo.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <vector> | 8 #include <vector> |
9 | 9 |
10 #include "base/debug/alias.h" | 10 #include "base/debug/alias.h" |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
90 handler_data.wait_signals = wait_signals; | 90 handler_data.wait_signals = wait_signals; |
91 handler_data.deadline = deadline; | 91 handler_data.deadline = deadline; |
92 handler_data.id = next_handler_id_++; | 92 handler_data.id = next_handler_id_++; |
93 handlers_[handle] = handler_data; | 93 handlers_[handle] = handler_data; |
94 } | 94 } |
95 | 95 |
96 void MessagePumpMojo::RemoveHandler(const Handle& handle) { | 96 void MessagePumpMojo::RemoveHandler(const Handle& handle) { |
97 handlers_.erase(handle); | 97 handlers_.erase(handle); |
98 } | 98 } |
99 | 99 |
| 100 void MessagePumpMojo::AddObserver(Observer* observer) { |
| 101 observers_.AddObserver(observer); |
| 102 } |
| 103 |
| 104 void MessagePumpMojo::RemoveObserver(Observer* observer) { |
| 105 observers_.RemoveObserver(observer); |
| 106 } |
| 107 |
100 void MessagePumpMojo::Run(Delegate* delegate) { | 108 void MessagePumpMojo::Run(Delegate* delegate) { |
101 RunState run_state; | 109 RunState run_state; |
102 // TODO: better deal with error handling. | 110 // TODO: better deal with error handling. |
103 CHECK(run_state.read_handle.is_valid()); | 111 CHECK(run_state.read_handle.is_valid()); |
104 CHECK(run_state.write_handle.is_valid()); | 112 CHECK(run_state.write_handle.is_valid()); |
105 RunState* old_state = NULL; | 113 RunState* old_state = NULL; |
106 { | 114 { |
107 base::AutoLock auto_lock(run_state_lock_); | 115 base::AutoLock auto_lock(run_state_lock_); |
108 old_state = run_state_; | 116 old_state = run_state_; |
109 run_state_ = &run_state; | 117 run_state_ = &run_state; |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
168 const MojoResult result = | 176 const MojoResult result = |
169 WaitMany(wait_state.handles, wait_state.wait_signals, deadline); | 177 WaitMany(wait_state.handles, wait_state.wait_signals, deadline); |
170 bool did_work = true; | 178 bool did_work = true; |
171 if (result == 0) { | 179 if (result == 0) { |
172 // Control pipe was written to. | 180 // Control pipe was written to. |
173 ReadMessageRaw(run_state.read_handle.get(), NULL, NULL, NULL, NULL, | 181 ReadMessageRaw(run_state.read_handle.get(), NULL, NULL, NULL, NULL, |
174 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); | 182 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); |
175 } else if (result > 0) { | 183 } else if (result > 0) { |
176 const size_t index = static_cast<size_t>(result); | 184 const size_t index = static_cast<size_t>(result); |
177 DCHECK(handlers_.find(wait_state.handles[index]) != handlers_.end()); | 185 DCHECK(handlers_.find(wait_state.handles[index]) != handlers_.end()); |
| 186 WillSignalHandler(); |
178 handlers_[wait_state.handles[index]].handler->OnHandleReady( | 187 handlers_[wait_state.handles[index]].handler->OnHandleReady( |
179 wait_state.handles[index]); | 188 wait_state.handles[index]); |
| 189 DidSignalHandler(); |
180 } else { | 190 } else { |
181 switch (result) { | 191 switch (result) { |
182 case MOJO_RESULT_CANCELLED: | 192 case MOJO_RESULT_CANCELLED: |
183 case MOJO_RESULT_FAILED_PRECONDITION: | 193 case MOJO_RESULT_FAILED_PRECONDITION: |
184 RemoveFirstInvalidHandle(wait_state); | 194 RemoveFirstInvalidHandle(wait_state); |
185 break; | 195 break; |
186 case MOJO_RESULT_DEADLINE_EXCEEDED: | 196 case MOJO_RESULT_DEADLINE_EXCEEDED: |
187 did_work = false; | 197 did_work = false; |
188 break; | 198 break; |
189 default: | 199 default: |
190 base::debug::Alias(&result); | 200 base::debug::Alias(&result); |
191 // Unexpected result is likely fatal, crash so we can determine cause. | 201 // Unexpected result is likely fatal, crash so we can determine cause. |
192 CHECK(false); | 202 CHECK(false); |
193 } | 203 } |
194 } | 204 } |
195 | 205 |
196 // Notify and remove any handlers whose time has expired. Make a copy in case | 206 // Notify and remove any handlers whose time has expired. Make a copy in case |
197 // someone tries to add/remove new handlers from notification. | 207 // someone tries to add/remove new handlers from notification. |
198 const HandleToHandler cloned_handlers(handlers_); | 208 const HandleToHandler cloned_handlers(handlers_); |
199 const base::TimeTicks now(internal::NowTicks()); | 209 const base::TimeTicks now(internal::NowTicks()); |
200 for (HandleToHandler::const_iterator i = cloned_handlers.begin(); | 210 for (HandleToHandler::const_iterator i = cloned_handlers.begin(); |
201 i != cloned_handlers.end(); ++i) { | 211 i != cloned_handlers.end(); ++i) { |
202 // Since we're iterating over a clone of the handlers, verify the handler is | 212 // Since we're iterating over a clone of the handlers, verify the handler is |
203 // still valid before notifying. | 213 // still valid before notifying. |
204 if (!i->second.deadline.is_null() && i->second.deadline < now && | 214 if (!i->second.deadline.is_null() && i->second.deadline < now && |
205 handlers_.find(i->first) != handlers_.end() && | 215 handlers_.find(i->first) != handlers_.end() && |
206 handlers_[i->first].id == i->second.id) { | 216 handlers_[i->first].id == i->second.id) { |
| 217 WillSignalHandler(); |
207 i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED); | 218 i->second.handler->OnHandleError(i->first, MOJO_RESULT_DEADLINE_EXCEEDED); |
| 219 DidSignalHandler(); |
208 handlers_.erase(i->first); | 220 handlers_.erase(i->first); |
209 did_work = true; | 221 did_work = true; |
210 } | 222 } |
211 } | 223 } |
212 return did_work; | 224 return did_work; |
213 } | 225 } |
214 | 226 |
215 void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { | 227 void MessagePumpMojo::RemoveFirstInvalidHandle(const WaitState& wait_state) { |
216 // TODO(sky): deal with control pipe going bad. | 228 // TODO(sky): deal with control pipe going bad. |
217 for (size_t i = 0; i < wait_state.handles.size(); ++i) { | 229 for (size_t i = 0; i < wait_state.handles.size(); ++i) { |
218 const MojoResult result = | 230 const MojoResult result = |
219 Wait(wait_state.handles[i], wait_state.wait_signals[i], 0); | 231 Wait(wait_state.handles[i], wait_state.wait_signals[i], 0); |
220 if (result == MOJO_RESULT_INVALID_ARGUMENT) { | 232 if (result == MOJO_RESULT_INVALID_ARGUMENT) { |
221 // We should never have an invalid argument. If we do it indicates | 233 // We should never have an invalid argument. If we do it indicates |
222 // RemoveHandler() was not invoked and is likely to cause problems else | 234 // RemoveHandler() was not invoked and is likely to cause problems else |
223 // where in the stack if we ignore it. | 235 // where in the stack if we ignore it. |
224 CHECK(false); | 236 CHECK(false); |
225 } else if (result == MOJO_RESULT_FAILED_PRECONDITION || | 237 } else if (result == MOJO_RESULT_FAILED_PRECONDITION || |
226 result == MOJO_RESULT_CANCELLED) { | 238 result == MOJO_RESULT_CANCELLED) { |
227 CHECK_NE(i, 0u); // Indicates the control pipe went bad. | 239 CHECK_NE(i, 0u); // Indicates the control pipe went bad. |
228 | 240 |
229 // Remove the handle first, this way if OnHandleError() tries to remove | 241 // Remove the handle first, this way if OnHandleError() tries to remove |
230 // the handle our iterator isn't invalidated. | 242 // the handle our iterator isn't invalidated. |
231 CHECK(handlers_.find(wait_state.handles[i]) != handlers_.end()); | 243 CHECK(handlers_.find(wait_state.handles[i]) != handlers_.end()); |
232 MessagePumpMojoHandler* handler = | 244 MessagePumpMojoHandler* handler = |
233 handlers_[wait_state.handles[i]].handler; | 245 handlers_[wait_state.handles[i]].handler; |
234 handlers_.erase(wait_state.handles[i]); | 246 handlers_.erase(wait_state.handles[i]); |
| 247 WillSignalHandler(); |
235 handler->OnHandleError(wait_state.handles[i], result); | 248 handler->OnHandleError(wait_state.handles[i], result); |
| 249 DidSignalHandler(); |
236 return; | 250 return; |
237 } | 251 } |
238 } | 252 } |
239 } | 253 } |
240 | 254 |
241 void MessagePumpMojo::SignalControlPipe(const RunState& run_state) { | 255 void MessagePumpMojo::SignalControlPipe(const RunState& run_state) { |
242 const MojoResult result = | 256 const MojoResult result = |
243 WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0, | 257 WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0, |
244 MOJO_WRITE_MESSAGE_FLAG_NONE); | 258 MOJO_WRITE_MESSAGE_FLAG_NONE); |
245 // If we can't write we likely won't wake up the thread and there is a strong | 259 // If we can't write we likely won't wake up the thread and there is a strong |
(...skipping 21 matching lines...) Expand all Loading... |
267 MojoDeadline deadline = TimeTicksToMojoDeadline(run_state.delayed_work_time, | 281 MojoDeadline deadline = TimeTicksToMojoDeadline(run_state.delayed_work_time, |
268 now); | 282 now); |
269 for (HandleToHandler::const_iterator i = handlers_.begin(); | 283 for (HandleToHandler::const_iterator i = handlers_.begin(); |
270 i != handlers_.end(); ++i) { | 284 i != handlers_.end(); ++i) { |
271 deadline = std::min( | 285 deadline = std::min( |
272 TimeTicksToMojoDeadline(i->second.deadline, now), deadline); | 286 TimeTicksToMojoDeadline(i->second.deadline, now), deadline); |
273 } | 287 } |
274 return deadline; | 288 return deadline; |
275 } | 289 } |
276 | 290 |
| 291 void MessagePumpMojo::WillSignalHandler() { |
| 292 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); |
| 293 } |
| 294 |
| 295 void MessagePumpMojo::DidSignalHandler() { |
| 296 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); |
| 297 } |
| 298 |
277 } // namespace common | 299 } // namespace common |
278 } // namespace mojo | 300 } // namespace mojo |
OLD | NEW |