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 |