Chromium Code Reviews| 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/message_pump/message_pump_mojo.h" | 5 #include "mojo/message_pump/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" |
| 11 #include "base/lazy_instance.h" | |
| 12 #include "base/logging.h" | 11 #include "base/logging.h" |
| 13 #include "base/threading/thread_local.h" | 12 #include "base/threading/thread_local.h" |
| 14 #include "base/time/time.h" | 13 #include "base/time/time.h" |
| 15 #include "mojo/message_pump/message_pump_mojo_handler.h" | 14 #include "mojo/message_pump/message_pump_mojo_handler.h" |
| 16 #include "mojo/message_pump/time_helper.h" | 15 #include "mojo/message_pump/time_helper.h" |
| 17 | 16 |
| 18 namespace mojo { | 17 namespace mojo { |
| 19 namespace common { | 18 namespace common { |
| 20 namespace { | 19 namespace { |
| 21 | 20 |
| 22 base::LazyInstance<base::ThreadLocalPointer<MessagePumpMojo> >::Leaky | 21 base::ThreadLocalPointer<MessagePumpMojo>* CurrentPump() { |
| 23 g_tls_current_pump = LAZY_INSTANCE_INITIALIZER; | 22 static auto* tls = new base::ThreadLocalPointer<MessagePumpMojo>; |
| 23 return tls; | |
| 24 } | |
| 24 | 25 |
| 25 MojoDeadline TimeTicksToMojoDeadline(base::TimeTicks time_ticks, | 26 MojoDeadline TimeTicksToMojoDeadline(base::TimeTicks time_ticks, |
| 26 base::TimeTicks now) { | 27 base::TimeTicks now) { |
| 27 // The is_null() check matches that of HandleWatcher as well as how | 28 // The is_null() check matches that of HandleWatcher as well as how |
| 28 // |delayed_work_time| is used. | 29 // |delayed_work_time| is used. |
| 29 if (time_ticks.is_null()) | 30 if (time_ticks.is_null()) |
| 30 return MOJO_DEADLINE_INDEFINITE; | 31 return MOJO_DEADLINE_INDEFINITE; |
| 31 const int64_t delta = (time_ticks - now).InMicroseconds(); | 32 const int64_t delta = (time_ticks - now).InMicroseconds(); |
| 32 return delta < 0 ? static_cast<MojoDeadline>(0) : | 33 return delta < 0 ? static_cast<MojoDeadline>(0) : |
| 33 static_cast<MojoDeadline>(delta); | 34 static_cast<MojoDeadline>(delta); |
| 34 } | 35 } |
| 35 | 36 |
| 36 } // namespace | 37 } // namespace |
| 37 | 38 |
| 38 // State needed for one iteration of WaitMany. The first handle and flags | 39 // State needed for one iteration of WaitMany. The first handle and flags |
| 39 // corresponds to that of the control pipe. | 40 // corresponds to that of the control pipe. |
| 40 struct MessagePumpMojo::WaitState { | 41 struct MessagePumpMojo::WaitState { |
| 41 std::vector<Handle> handles; | 42 std::vector<Handle> handles; |
| 42 std::vector<MojoHandleSignals> wait_signals; | 43 std::vector<MojoHandleSignals> wait_signals; |
| 43 }; | 44 }; |
| 44 | 45 |
| 45 struct MessagePumpMojo::RunState { | 46 struct MessagePumpMojo::RunState { |
| 46 RunState() : should_quit(false) { | 47 RunState() : should_quit(false) { |
| 47 CreateMessagePipe(NULL, &read_handle, &write_handle); | 48 CreateMessagePipe(nullptr, &read_handle, &write_handle); |
| 48 } | 49 } |
| 49 | 50 |
| 50 base::TimeTicks delayed_work_time; | 51 base::TimeTicks delayed_work_time; |
| 51 | 52 |
| 52 // Used to wake up WaitForWork(). | 53 // Used to wake up WaitForWork(). |
| 53 ScopedMessagePipeHandle read_handle; | 54 ScopedMessagePipeHandle read_handle; |
| 54 ScopedMessagePipeHandle write_handle; | 55 ScopedMessagePipeHandle write_handle; |
| 55 | 56 |
| 56 // Cached structures to avoid the heap allocation cost of std::vector<>. | 57 // Cached structures to avoid the heap allocation cost of std::vector<>. |
| 57 scoped_ptr<WaitState> wait_state; | 58 scoped_ptr<WaitState> wait_state; |
| 58 scoped_ptr<HandleToHandlerList> cloned_handlers; | 59 scoped_ptr<HandleToHandlerList> cloned_handlers; |
| 59 | 60 |
| 60 bool should_quit; | 61 bool should_quit; |
| 61 }; | 62 }; |
| 62 | 63 |
| 63 MessagePumpMojo::MessagePumpMojo() : run_state_(NULL), next_handler_id_(0) { | 64 MessagePumpMojo::MessagePumpMojo() : run_state_(nullptr), next_handler_id_(0) { |
| 64 DCHECK(!current()) | 65 DCHECK(!current()) |
| 65 << "There is already a MessagePumpMojo instance on this thread."; | 66 << "There is already a MessagePumpMojo instance on this thread."; |
| 66 g_tls_current_pump.Pointer()->Set(this); | 67 CurrentPump()->Set(this); |
| 67 } | 68 } |
| 68 | 69 |
| 69 MessagePumpMojo::~MessagePumpMojo() { | 70 MessagePumpMojo::~MessagePumpMojo() { |
| 70 DCHECK_EQ(this, current()); | 71 DCHECK_EQ(this, current()); |
| 71 g_tls_current_pump.Pointer()->Set(NULL); | 72 CurrentPump()->Set(nullptr); |
| 72 } | 73 } |
| 73 | 74 |
| 74 // static | 75 // static |
| 75 scoped_ptr<base::MessagePump> MessagePumpMojo::Create() { | 76 scoped_ptr<base::MessagePump> MessagePumpMojo::Create() { |
| 76 return scoped_ptr<MessagePump>(new MessagePumpMojo()); | 77 return scoped_ptr<MessagePump>(new MessagePumpMojo()); |
| 77 } | 78 } |
| 78 | 79 |
| 79 // static | 80 // static |
| 80 MessagePumpMojo* MessagePumpMojo::current() { | 81 MessagePumpMojo* MessagePumpMojo::current() { |
| 81 return g_tls_current_pump.Pointer()->Get(); | 82 return CurrentPump()->Get(); |
| 82 } | 83 } |
| 83 | 84 |
| 84 void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler, | 85 void MessagePumpMojo::AddHandler(MessagePumpMojoHandler* handler, |
| 85 const Handle& handle, | 86 const Handle& handle, |
| 86 MojoHandleSignals wait_signals, | 87 MojoHandleSignals wait_signals, |
| 87 base::TimeTicks deadline) { | 88 base::TimeTicks deadline) { |
| 88 CHECK(handler); | 89 CHECK(handler); |
| 89 DCHECK(handle.is_valid()); | 90 DCHECK(handle.is_valid()); |
| 90 // Assume it's an error if someone tries to reregister an existing handle. | 91 // Assume it's an error if someone tries to reregister an existing handle. |
| 91 CHECK_EQ(0u, handlers_.count(handle)); | 92 CHECK_EQ(0u, handlers_.count(handle)); |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 107 | 108 |
| 108 void MessagePumpMojo::RemoveObserver(Observer* observer) { | 109 void MessagePumpMojo::RemoveObserver(Observer* observer) { |
| 109 observers_.RemoveObserver(observer); | 110 observers_.RemoveObserver(observer); |
| 110 } | 111 } |
| 111 | 112 |
| 112 void MessagePumpMojo::Run(Delegate* delegate) { | 113 void MessagePumpMojo::Run(Delegate* delegate) { |
| 113 RunState run_state; | 114 RunState run_state; |
| 114 // TODO: better deal with error handling. | 115 // TODO: better deal with error handling. |
| 115 CHECK(run_state.read_handle.is_valid()); | 116 CHECK(run_state.read_handle.is_valid()); |
| 116 CHECK(run_state.write_handle.is_valid()); | 117 CHECK(run_state.write_handle.is_valid()); |
| 117 RunState* old_state = NULL; | 118 RunState* old_state = nullptr; |
|
jamesr
2016/02/10 21:28:38
drive-by s/NULL/nullptr/g since there was a NULL i
| |
| 118 { | 119 { |
| 119 base::AutoLock auto_lock(run_state_lock_); | 120 base::AutoLock auto_lock(run_state_lock_); |
| 120 old_state = run_state_; | 121 old_state = run_state_; |
| 121 run_state_ = &run_state; | 122 run_state_ = &run_state; |
| 122 } | 123 } |
| 123 DoRunLoop(&run_state, delegate); | 124 DoRunLoop(&run_state, delegate); |
| 124 { | 125 { |
| 125 base::AutoLock auto_lock(run_state_lock_); | 126 base::AutoLock auto_lock(run_state_lock_); |
| 126 run_state_ = old_state; | 127 run_state_ = old_state; |
| 127 } | 128 } |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 181 GetWaitState(run_state, run_state_->wait_state.get()); | 182 GetWaitState(run_state, run_state_->wait_state.get()); |
| 182 | 183 |
| 183 const WaitManyResult wait_many_result = | 184 const WaitManyResult wait_many_result = |
| 184 WaitMany(run_state_->wait_state->handles, | 185 WaitMany(run_state_->wait_state->handles, |
| 185 run_state_->wait_state->wait_signals, deadline, nullptr); | 186 run_state_->wait_state->wait_signals, deadline, nullptr); |
| 186 const MojoResult result = wait_many_result.result; | 187 const MojoResult result = wait_many_result.result; |
| 187 bool did_work = true; | 188 bool did_work = true; |
| 188 if (result == MOJO_RESULT_OK) { | 189 if (result == MOJO_RESULT_OK) { |
| 189 if (wait_many_result.index == 0) { | 190 if (wait_many_result.index == 0) { |
| 190 // Control pipe was written to. | 191 // Control pipe was written to. |
| 191 ReadMessageRaw(run_state.read_handle.get(), NULL, NULL, NULL, NULL, | 192 ReadMessageRaw(run_state.read_handle.get(), nullptr, nullptr, nullptr, |
| 192 MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); | 193 nullptr, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); |
| 193 } else { | 194 } else { |
| 194 DCHECK(handlers_.find( | 195 DCHECK(handlers_.find( |
| 195 run_state_->wait_state->handles[wait_many_result.index]) != | 196 run_state_->wait_state->handles[wait_many_result.index]) != |
| 196 handlers_.end()); | 197 handlers_.end()); |
| 197 WillSignalHandler(); | 198 WillSignalHandler(); |
| 198 handlers_[run_state_->wait_state->handles[wait_many_result.index]] | 199 handlers_[run_state_->wait_state->handles[wait_many_result.index]] |
| 199 .handler->OnHandleReady( | 200 .handler->OnHandleReady( |
| 200 run_state_->wait_state->handles[wait_many_result.index]); | 201 run_state_->wait_state->handles[wait_many_result.index]); |
| 201 DidSignalHandler(); | 202 DidSignalHandler(); |
| 202 } | 203 } |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 274 MessagePumpMojoHandler* handler = | 275 MessagePumpMojoHandler* handler = |
| 275 handlers_[wait_state.handles[index]].handler; | 276 handlers_[wait_state.handles[index]].handler; |
| 276 handlers_.erase(wait_state.handles[index]); | 277 handlers_.erase(wait_state.handles[index]); |
| 277 WillSignalHandler(); | 278 WillSignalHandler(); |
| 278 handler->OnHandleError(wait_state.handles[index], result); | 279 handler->OnHandleError(wait_state.handles[index], result); |
| 279 DidSignalHandler(); | 280 DidSignalHandler(); |
| 280 } | 281 } |
| 281 | 282 |
| 282 void MessagePumpMojo::SignalControlPipe(const RunState& run_state) { | 283 void MessagePumpMojo::SignalControlPipe(const RunState& run_state) { |
| 283 const MojoResult result = | 284 const MojoResult result = |
| 284 WriteMessageRaw(run_state.write_handle.get(), NULL, 0, NULL, 0, | 285 WriteMessageRaw(run_state.write_handle.get(), nullptr, 0, nullptr, 0, |
| 285 MOJO_WRITE_MESSAGE_FLAG_NONE); | 286 MOJO_WRITE_MESSAGE_FLAG_NONE); |
| 286 // If we can't write we likely won't wake up the thread and there is a strong | 287 // If we can't write we likely won't wake up the thread and there is a strong |
| 287 // chance we'll deadlock. | 288 // chance we'll deadlock. |
| 288 CHECK_EQ(MOJO_RESULT_OK, result); | 289 CHECK_EQ(MOJO_RESULT_OK, result); |
| 289 } | 290 } |
| 290 | 291 |
| 291 void MessagePumpMojo::GetWaitState( | 292 void MessagePumpMojo::GetWaitState( |
| 292 const RunState& run_state, | 293 const RunState& run_state, |
| 293 MessagePumpMojo::WaitState* wait_state) const { | 294 MessagePumpMojo::WaitState* wait_state) const { |
| 294 const size_t num_handles = handlers_.size() + 1; | 295 const size_t num_handles = handlers_.size() + 1; |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 322 void MessagePumpMojo::WillSignalHandler() { | 323 void MessagePumpMojo::WillSignalHandler() { |
| 323 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); | 324 FOR_EACH_OBSERVER(Observer, observers_, WillSignalHandler()); |
| 324 } | 325 } |
| 325 | 326 |
| 326 void MessagePumpMojo::DidSignalHandler() { | 327 void MessagePumpMojo::DidSignalHandler() { |
| 327 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); | 328 FOR_EACH_OBSERVER(Observer, observers_, DidSignalHandler()); |
| 328 } | 329 } |
| 329 | 330 |
| 330 } // namespace common | 331 } // namespace common |
| 331 } // namespace mojo | 332 } // namespace mojo |
| OLD | NEW |