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/handle_watcher.h" | 5 #include "mojo/common/handle_watcher.h" |
6 | 6 |
7 #include <map> | 7 #include <map> |
8 | 8 |
9 #include "base/atomic_sequence_num.h" | 9 #include "base/atomic_sequence_num.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
(...skipping 28 matching lines...) Expand all Loading... |
39 | 39 |
40 base::TimeTicks MojoDeadlineToTimeTicks(MojoDeadline deadline) { | 40 base::TimeTicks MojoDeadlineToTimeTicks(MojoDeadline deadline) { |
41 return deadline == MOJO_DEADLINE_INDEFINITE ? base::TimeTicks() : | 41 return deadline == MOJO_DEADLINE_INDEFINITE ? base::TimeTicks() : |
42 internal::NowTicks() + base::TimeDelta::FromMicroseconds(deadline); | 42 internal::NowTicks() + base::TimeDelta::FromMicroseconds(deadline); |
43 } | 43 } |
44 | 44 |
45 // Tracks the data for a single call to Start(). | 45 // Tracks the data for a single call to Start(). |
46 struct WatchData { | 46 struct WatchData { |
47 WatchData() | 47 WatchData() |
48 : id(0), | 48 : id(0), |
49 wait_flags(MOJO_WAIT_FLAG_NONE), | 49 handle_signals(MOJO_WAIT_FLAG_NONE), |
50 message_loop(NULL) {} | 50 message_loop(NULL) {} |
51 | 51 |
52 WatcherID id; | 52 WatcherID id; |
53 Handle handle; | 53 Handle handle; |
54 MojoWaitFlags wait_flags; | 54 MojoHandleSignals handle_signals; |
55 base::TimeTicks deadline; | 55 base::TimeTicks deadline; |
56 base::Callback<void(MojoResult)> callback; | 56 base::Callback<void(MojoResult)> callback; |
57 scoped_refptr<base::MessageLoopProxy> message_loop; | 57 scoped_refptr<base::MessageLoopProxy> message_loop; |
58 }; | 58 }; |
59 | 59 |
60 // WatcherBackend -------------------------------------------------------------- | 60 // WatcherBackend -------------------------------------------------------------- |
61 | 61 |
62 // WatcherBackend is responsible for managing the requests and interacting with | 62 // WatcherBackend is responsible for managing the requests and interacting with |
63 // MessagePumpMojo. All access (outside of creation/destruction) is done on the | 63 // MessagePumpMojo. All access (outside of creation/destruction) is done on the |
64 // thread WatcherThreadManager creates. | 64 // thread WatcherThreadManager creates. |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
96 WatcherBackend::~WatcherBackend() { | 96 WatcherBackend::~WatcherBackend() { |
97 } | 97 } |
98 | 98 |
99 void WatcherBackend::StartWatching(const WatchData& data) { | 99 void WatcherBackend::StartWatching(const WatchData& data) { |
100 RemoveAndNotify(data.handle, MOJO_RESULT_CANCELLED); | 100 RemoveAndNotify(data.handle, MOJO_RESULT_CANCELLED); |
101 | 101 |
102 DCHECK_EQ(0u, handle_to_data_.count(data.handle)); | 102 DCHECK_EQ(0u, handle_to_data_.count(data.handle)); |
103 | 103 |
104 handle_to_data_[data.handle] = data; | 104 handle_to_data_[data.handle] = data; |
105 message_pump_mojo->AddHandler(this, data.handle, | 105 message_pump_mojo->AddHandler(this, data.handle, |
106 data.wait_flags, | 106 data.handle_signals, |
107 data.deadline); | 107 data.deadline); |
108 } | 108 } |
109 | 109 |
110 void WatcherBackend::StopWatching(WatcherID watcher_id) { | 110 void WatcherBackend::StopWatching(WatcherID watcher_id) { |
111 // Because of the thread hop it is entirely possible to get here and not | 111 // Because of the thread hop it is entirely possible to get here and not |
112 // have a valid handle registered for |watcher_id|. | 112 // have a valid handle registered for |watcher_id|. |
113 Handle handle; | 113 Handle handle; |
114 if (!GetMojoHandleByWatcherID(watcher_id, &handle)) | 114 if (!GetMojoHandleByWatcherID(watcher_id, &handle)) |
115 return; | 115 return; |
116 | 116 |
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 ~WatcherThreadManager(); | 158 ~WatcherThreadManager(); |
159 | 159 |
160 // Returns the shared instance. | 160 // Returns the shared instance. |
161 static WatcherThreadManager* GetInstance(); | 161 static WatcherThreadManager* GetInstance(); |
162 | 162 |
163 // Starts watching the requested handle. Returns a unique ID that is used to | 163 // Starts watching the requested handle. Returns a unique ID that is used to |
164 // stop watching the handle. When the handle is ready |callback| is notified | 164 // stop watching the handle. When the handle is ready |callback| is notified |
165 // on the thread StartWatching() was invoked on. | 165 // on the thread StartWatching() was invoked on. |
166 // This may be invoked on any thread. | 166 // This may be invoked on any thread. |
167 WatcherID StartWatching(const Handle& handle, | 167 WatcherID StartWatching(const Handle& handle, |
168 MojoWaitFlags wait_flags, | 168 MojoHandleSignals handle_signals, |
169 base::TimeTicks deadline, | 169 base::TimeTicks deadline, |
170 const base::Callback<void(MojoResult)>& callback); | 170 const base::Callback<void(MojoResult)>& callback); |
171 | 171 |
172 // Stops watching a handle. | 172 // Stops watching a handle. |
173 // This may be invoked on any thread. | 173 // This may be invoked on any thread. |
174 void StopWatching(WatcherID watcher_id); | 174 void StopWatching(WatcherID watcher_id); |
175 | 175 |
176 private: | 176 private: |
177 friend struct DefaultSingletonTraits<WatcherThreadManager>; | 177 friend struct DefaultSingletonTraits<WatcherThreadManager>; |
178 WatcherThreadManager(); | 178 WatcherThreadManager(); |
(...skipping 10 matching lines...) Expand all Loading... |
189 WatcherThreadManager::~WatcherThreadManager() { | 189 WatcherThreadManager::~WatcherThreadManager() { |
190 thread_.Stop(); | 190 thread_.Stop(); |
191 } | 191 } |
192 | 192 |
193 WatcherThreadManager* WatcherThreadManager::GetInstance() { | 193 WatcherThreadManager* WatcherThreadManager::GetInstance() { |
194 return Singleton<WatcherThreadManager>::get(); | 194 return Singleton<WatcherThreadManager>::get(); |
195 } | 195 } |
196 | 196 |
197 WatcherID WatcherThreadManager::StartWatching( | 197 WatcherID WatcherThreadManager::StartWatching( |
198 const Handle& handle, | 198 const Handle& handle, |
199 MojoWaitFlags wait_flags, | 199 MojoHandleSignals handle_signals, |
200 base::TimeTicks deadline, | 200 base::TimeTicks deadline, |
201 const base::Callback<void(MojoResult)>& callback) { | 201 const base::Callback<void(MojoResult)>& callback) { |
202 WatchData data; | 202 WatchData data; |
203 data.id = watcher_id_generator_.GetNext(); | 203 data.id = watcher_id_generator_.GetNext(); |
204 data.handle = handle; | 204 data.handle = handle; |
205 data.callback = callback; | 205 data.callback = callback; |
206 data.wait_flags = wait_flags; | 206 data.handle_signals = handle_signals; |
207 data.deadline = deadline; | 207 data.deadline = deadline; |
208 data.message_loop = base::MessageLoopProxy::current(); | 208 data.message_loop = base::MessageLoopProxy::current(); |
209 DCHECK_NE(static_cast<base::MessageLoopProxy*>(NULL), | 209 DCHECK_NE(static_cast<base::MessageLoopProxy*>(NULL), |
210 data.message_loop.get()); | 210 data.message_loop.get()); |
211 // We outlive |thread_|, so it's safe to use Unretained() here. | 211 // We outlive |thread_|, so it's safe to use Unretained() here. |
212 thread_.message_loop()->PostTask( | 212 thread_.message_loop()->PostTask( |
213 FROM_HERE, | 213 FROM_HERE, |
214 base::Bind(&WatcherBackend::StartWatching, | 214 base::Bind(&WatcherBackend::StartWatching, |
215 base::Unretained(&backend_), | 215 base::Unretained(&backend_), |
216 data)); | 216 data)); |
(...skipping 20 matching lines...) Expand all Loading... |
237 | 237 |
238 // HandleWatcher::State -------------------------------------------------------- | 238 // HandleWatcher::State -------------------------------------------------------- |
239 | 239 |
240 // Represents the state of the HandleWatcher. Owns the user's callback and | 240 // Represents the state of the HandleWatcher. Owns the user's callback and |
241 // monitors the current thread's MessageLoop to know when to force the callback | 241 // monitors the current thread's MessageLoop to know when to force the callback |
242 // to run (with an error) even though the pipe hasn't been signaled yet. | 242 // to run (with an error) even though the pipe hasn't been signaled yet. |
243 class HandleWatcher::State : public base::MessageLoop::DestructionObserver { | 243 class HandleWatcher::State : public base::MessageLoop::DestructionObserver { |
244 public: | 244 public: |
245 State(HandleWatcher* watcher, | 245 State(HandleWatcher* watcher, |
246 const Handle& handle, | 246 const Handle& handle, |
247 MojoWaitFlags wait_flags, | 247 MojoHandleSignals handle_signals, |
248 MojoDeadline deadline, | 248 MojoDeadline deadline, |
249 const base::Callback<void(MojoResult)>& callback) | 249 const base::Callback<void(MojoResult)>& callback) |
250 : watcher_(watcher), | 250 : watcher_(watcher), |
251 callback_(callback), | 251 callback_(callback), |
252 weak_factory_(this) { | 252 weak_factory_(this) { |
253 base::MessageLoop::current()->AddDestructionObserver(this); | 253 base::MessageLoop::current()->AddDestructionObserver(this); |
254 | 254 |
255 watcher_id_ = WatcherThreadManager::GetInstance()->StartWatching( | 255 watcher_id_ = WatcherThreadManager::GetInstance()->StartWatching( |
256 handle, | 256 handle, |
257 wait_flags, | 257 handle_signals, |
258 MojoDeadlineToTimeTicks(deadline), | 258 MojoDeadlineToTimeTicks(deadline), |
259 base::Bind(&State::OnHandleReady, weak_factory_.GetWeakPtr())); | 259 base::Bind(&State::OnHandleReady, weak_factory_.GetWeakPtr())); |
260 } | 260 } |
261 | 261 |
262 virtual ~State() { | 262 virtual ~State() { |
263 base::MessageLoop::current()->RemoveDestructionObserver(this); | 263 base::MessageLoop::current()->RemoveDestructionObserver(this); |
264 | 264 |
265 WatcherThreadManager::GetInstance()->StopWatching(watcher_id_); | 265 WatcherThreadManager::GetInstance()->StopWatching(watcher_id_); |
266 } | 266 } |
267 | 267 |
(...skipping 20 matching lines...) Expand all Loading... |
288 | 288 |
289 // HandleWatcher --------------------------------------------------------------- | 289 // HandleWatcher --------------------------------------------------------------- |
290 | 290 |
291 HandleWatcher::HandleWatcher() { | 291 HandleWatcher::HandleWatcher() { |
292 } | 292 } |
293 | 293 |
294 HandleWatcher::~HandleWatcher() { | 294 HandleWatcher::~HandleWatcher() { |
295 } | 295 } |
296 | 296 |
297 void HandleWatcher::Start(const Handle& handle, | 297 void HandleWatcher::Start(const Handle& handle, |
298 MojoWaitFlags wait_flags, | 298 MojoHandleSignals handle_signals, |
299 MojoDeadline deadline, | 299 MojoDeadline deadline, |
300 const base::Callback<void(MojoResult)>& callback) { | 300 const base::Callback<void(MojoResult)>& callback) { |
301 DCHECK(handle.is_valid()); | 301 DCHECK(handle.is_valid()); |
302 DCHECK_NE(MOJO_WAIT_FLAG_NONE, wait_flags); | 302 DCHECK_NE(MOJO_WAIT_FLAG_NONE, handle_signals); |
303 | 303 |
304 state_.reset(new State(this, handle, wait_flags, deadline, callback)); | 304 state_.reset(new State(this, handle, handle_signals, deadline, callback)); |
305 } | 305 } |
306 | 306 |
307 void HandleWatcher::Stop() { | 307 void HandleWatcher::Stop() { |
308 state_.reset(); | 308 state_.reset(); |
309 } | 309 } |
310 | 310 |
311 } // namespace common | 311 } // namespace common |
312 } // namespace mojo | 312 } // namespace mojo |
OLD | NEW |