Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(17)

Side by Side Diff: mojo/system/dispatcher.cc

Issue 621153003: Move mojo edk into mojo/edk (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: fix checkdeps Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « mojo/system/dispatcher.h ('k') | mojo/system/dispatcher_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "mojo/system/dispatcher.h"
6
7 #include "base/logging.h"
8 #include "mojo/system/constants.h"
9 #include "mojo/system/message_pipe_dispatcher.h"
10 #include "mojo/system/platform_handle_dispatcher.h"
11 #include "mojo/system/shared_buffer_dispatcher.h"
12
13 namespace mojo {
14 namespace system {
15
16 namespace test {
17
18 // TODO(vtl): Maybe this should be defined in a test-only file instead.
19 DispatcherTransport DispatcherTryStartTransport(Dispatcher* dispatcher) {
20 return Dispatcher::HandleTableAccess::TryStartTransport(dispatcher);
21 }
22
23 } // namespace test
24
25 // Dispatcher ------------------------------------------------------------------
26
27 // static
28 DispatcherTransport Dispatcher::HandleTableAccess::TryStartTransport(
29 Dispatcher* dispatcher) {
30 DCHECK(dispatcher);
31
32 if (!dispatcher->lock_.Try())
33 return DispatcherTransport();
34
35 // We shouldn't race with things that close dispatchers, since closing can
36 // only take place either under |handle_table_lock_| or when the handle is
37 // marked as busy.
38 DCHECK(!dispatcher->is_closed_);
39
40 return DispatcherTransport(dispatcher);
41 }
42
43 // static
44 void Dispatcher::TransportDataAccess::StartSerialize(
45 Dispatcher* dispatcher,
46 Channel* channel,
47 size_t* max_size,
48 size_t* max_platform_handles) {
49 DCHECK(dispatcher);
50 dispatcher->StartSerialize(channel, max_size, max_platform_handles);
51 }
52
53 // static
54 bool Dispatcher::TransportDataAccess::EndSerializeAndClose(
55 Dispatcher* dispatcher,
56 Channel* channel,
57 void* destination,
58 size_t* actual_size,
59 embedder::PlatformHandleVector* platform_handles) {
60 DCHECK(dispatcher);
61 return dispatcher->EndSerializeAndClose(
62 channel, destination, actual_size, platform_handles);
63 }
64
65 // static
66 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize(
67 Channel* channel,
68 int32_t type,
69 const void* source,
70 size_t size,
71 embedder::PlatformHandleVector* platform_handles) {
72 switch (static_cast<int32_t>(type)) {
73 case kTypeUnknown:
74 DVLOG(2) << "Deserializing invalid handle";
75 return scoped_refptr<Dispatcher>();
76 case kTypeMessagePipe:
77 return scoped_refptr<Dispatcher>(
78 MessagePipeDispatcher::Deserialize(channel, source, size));
79 case kTypeDataPipeProducer:
80 case kTypeDataPipeConsumer:
81 // TODO(vtl): Implement.
82 LOG(WARNING) << "Deserialization of dispatcher type " << type
83 << " not supported";
84 return scoped_refptr<Dispatcher>();
85 case kTypeSharedBuffer:
86 return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize(
87 channel, source, size, platform_handles));
88 case kTypePlatformHandle:
89 return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize(
90 channel, source, size, platform_handles));
91 }
92 LOG(WARNING) << "Unknown dispatcher type " << type;
93 return scoped_refptr<Dispatcher>();
94 }
95
96 MojoResult Dispatcher::Close() {
97 base::AutoLock locker(lock_);
98 if (is_closed_)
99 return MOJO_RESULT_INVALID_ARGUMENT;
100
101 CloseNoLock();
102 return MOJO_RESULT_OK;
103 }
104
105 MojoResult Dispatcher::WriteMessage(
106 UserPointer<const void> bytes,
107 uint32_t num_bytes,
108 std::vector<DispatcherTransport>* transports,
109 MojoWriteMessageFlags flags) {
110 DCHECK(!transports || (transports->size() > 0 &&
111 transports->size() < kMaxMessageNumHandles));
112
113 base::AutoLock locker(lock_);
114 if (is_closed_)
115 return MOJO_RESULT_INVALID_ARGUMENT;
116
117 return WriteMessageImplNoLock(bytes, num_bytes, transports, flags);
118 }
119
120 MojoResult Dispatcher::ReadMessage(UserPointer<void> bytes,
121 UserPointer<uint32_t> num_bytes,
122 DispatcherVector* dispatchers,
123 uint32_t* num_dispatchers,
124 MojoReadMessageFlags flags) {
125 DCHECK(!num_dispatchers || *num_dispatchers == 0 ||
126 (dispatchers && dispatchers->empty()));
127
128 base::AutoLock locker(lock_);
129 if (is_closed_)
130 return MOJO_RESULT_INVALID_ARGUMENT;
131
132 return ReadMessageImplNoLock(
133 bytes, num_bytes, dispatchers, num_dispatchers, flags);
134 }
135
136 MojoResult Dispatcher::WriteData(UserPointer<const void> elements,
137 UserPointer<uint32_t> num_bytes,
138 MojoWriteDataFlags flags) {
139 base::AutoLock locker(lock_);
140 if (is_closed_)
141 return MOJO_RESULT_INVALID_ARGUMENT;
142
143 return WriteDataImplNoLock(elements, num_bytes, flags);
144 }
145
146 MojoResult Dispatcher::BeginWriteData(UserPointer<void*> buffer,
147 UserPointer<uint32_t> buffer_num_bytes,
148 MojoWriteDataFlags flags) {
149 base::AutoLock locker(lock_);
150 if (is_closed_)
151 return MOJO_RESULT_INVALID_ARGUMENT;
152
153 return BeginWriteDataImplNoLock(buffer, buffer_num_bytes, flags);
154 }
155
156 MojoResult Dispatcher::EndWriteData(uint32_t num_bytes_written) {
157 base::AutoLock locker(lock_);
158 if (is_closed_)
159 return MOJO_RESULT_INVALID_ARGUMENT;
160
161 return EndWriteDataImplNoLock(num_bytes_written);
162 }
163
164 MojoResult Dispatcher::ReadData(UserPointer<void> elements,
165 UserPointer<uint32_t> num_bytes,
166 MojoReadDataFlags flags) {
167 base::AutoLock locker(lock_);
168 if (is_closed_)
169 return MOJO_RESULT_INVALID_ARGUMENT;
170
171 return ReadDataImplNoLock(elements, num_bytes, flags);
172 }
173
174 MojoResult Dispatcher::BeginReadData(UserPointer<const void*> buffer,
175 UserPointer<uint32_t> buffer_num_bytes,
176 MojoReadDataFlags flags) {
177 base::AutoLock locker(lock_);
178 if (is_closed_)
179 return MOJO_RESULT_INVALID_ARGUMENT;
180
181 return BeginReadDataImplNoLock(buffer, buffer_num_bytes, flags);
182 }
183
184 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) {
185 base::AutoLock locker(lock_);
186 if (is_closed_)
187 return MOJO_RESULT_INVALID_ARGUMENT;
188
189 return EndReadDataImplNoLock(num_bytes_read);
190 }
191
192 MojoResult Dispatcher::DuplicateBufferHandle(
193 UserPointer<const MojoDuplicateBufferHandleOptions> options,
194 scoped_refptr<Dispatcher>* new_dispatcher) {
195 base::AutoLock locker(lock_);
196 if (is_closed_)
197 return MOJO_RESULT_INVALID_ARGUMENT;
198
199 return DuplicateBufferHandleImplNoLock(options, new_dispatcher);
200 }
201
202 MojoResult Dispatcher::MapBuffer(
203 uint64_t offset,
204 uint64_t num_bytes,
205 MojoMapBufferFlags flags,
206 scoped_ptr<embedder::PlatformSharedBufferMapping>* mapping) {
207 base::AutoLock locker(lock_);
208 if (is_closed_)
209 return MOJO_RESULT_INVALID_ARGUMENT;
210
211 return MapBufferImplNoLock(offset, num_bytes, flags, mapping);
212 }
213
214 HandleSignalsState Dispatcher::GetHandleSignalsState() const {
215 base::AutoLock locker(lock_);
216 if (is_closed_)
217 return HandleSignalsState();
218
219 return GetHandleSignalsStateImplNoLock();
220 }
221
222 MojoResult Dispatcher::AddWaiter(Waiter* waiter,
223 MojoHandleSignals signals,
224 uint32_t context,
225 HandleSignalsState* signals_state) {
226 base::AutoLock locker(lock_);
227 if (is_closed_) {
228 if (signals_state)
229 *signals_state = HandleSignalsState();
230 return MOJO_RESULT_INVALID_ARGUMENT;
231 }
232
233 return AddWaiterImplNoLock(waiter, signals, context, signals_state);
234 }
235
236 void Dispatcher::RemoveWaiter(Waiter* waiter,
237 HandleSignalsState* handle_signals_state) {
238 base::AutoLock locker(lock_);
239 if (is_closed_) {
240 if (handle_signals_state)
241 *handle_signals_state = HandleSignalsState();
242 return;
243 }
244 RemoveWaiterImplNoLock(waiter, handle_signals_state);
245 }
246
247 Dispatcher::Dispatcher() : is_closed_(false) {
248 }
249
250 Dispatcher::~Dispatcher() {
251 // Make sure that |Close()| was called.
252 DCHECK(is_closed_);
253 }
254
255 void Dispatcher::CancelAllWaitersNoLock() {
256 lock_.AssertAcquired();
257 DCHECK(is_closed_);
258 // By default, waiting isn't supported. Only dispatchers that can be waited on
259 // will do something nontrivial.
260 }
261
262 void Dispatcher::CloseImplNoLock() {
263 lock_.AssertAcquired();
264 DCHECK(is_closed_);
265 // This may not need to do anything. Dispatchers should override this to do
266 // any actual close-time cleanup necessary.
267 }
268
269 MojoResult Dispatcher::WriteMessageImplNoLock(
270 UserPointer<const void> /*bytes*/,
271 uint32_t /*num_bytes*/,
272 std::vector<DispatcherTransport>* /*transports*/,
273 MojoWriteMessageFlags /*flags*/) {
274 lock_.AssertAcquired();
275 DCHECK(!is_closed_);
276 // By default, not supported. Only needed for message pipe dispatchers.
277 return MOJO_RESULT_INVALID_ARGUMENT;
278 }
279
280 MojoResult Dispatcher::ReadMessageImplNoLock(
281 UserPointer<void> /*bytes*/,
282 UserPointer<uint32_t> /*num_bytes*/,
283 DispatcherVector* /*dispatchers*/,
284 uint32_t* /*num_dispatchers*/,
285 MojoReadMessageFlags /*flags*/) {
286 lock_.AssertAcquired();
287 DCHECK(!is_closed_);
288 // By default, not supported. Only needed for message pipe dispatchers.
289 return MOJO_RESULT_INVALID_ARGUMENT;
290 }
291
292 MojoResult Dispatcher::WriteDataImplNoLock(UserPointer<const void> /*elements*/,
293 UserPointer<uint32_t> /*num_bytes*/,
294 MojoWriteDataFlags /*flags*/) {
295 lock_.AssertAcquired();
296 DCHECK(!is_closed_);
297 // By default, not supported. Only needed for data pipe dispatchers.
298 return MOJO_RESULT_INVALID_ARGUMENT;
299 }
300
301 MojoResult Dispatcher::BeginWriteDataImplNoLock(
302 UserPointer<void*> /*buffer*/,
303 UserPointer<uint32_t> /*buffer_num_bytes*/,
304 MojoWriteDataFlags /*flags*/) {
305 lock_.AssertAcquired();
306 DCHECK(!is_closed_);
307 // By default, not supported. Only needed for data pipe dispatchers.
308 return MOJO_RESULT_INVALID_ARGUMENT;
309 }
310
311 MojoResult Dispatcher::EndWriteDataImplNoLock(uint32_t /*num_bytes_written*/) {
312 lock_.AssertAcquired();
313 DCHECK(!is_closed_);
314 // By default, not supported. Only needed for data pipe dispatchers.
315 return MOJO_RESULT_INVALID_ARGUMENT;
316 }
317
318 MojoResult Dispatcher::ReadDataImplNoLock(UserPointer<void> /*elements*/,
319 UserPointer<uint32_t> /*num_bytes*/,
320 MojoReadDataFlags /*flags*/) {
321 lock_.AssertAcquired();
322 DCHECK(!is_closed_);
323 // By default, not supported. Only needed for data pipe dispatchers.
324 return MOJO_RESULT_INVALID_ARGUMENT;
325 }
326
327 MojoResult Dispatcher::BeginReadDataImplNoLock(
328 UserPointer<const void*> /*buffer*/,
329 UserPointer<uint32_t> /*buffer_num_bytes*/,
330 MojoReadDataFlags /*flags*/) {
331 lock_.AssertAcquired();
332 DCHECK(!is_closed_);
333 // By default, not supported. Only needed for data pipe dispatchers.
334 return MOJO_RESULT_INVALID_ARGUMENT;
335 }
336
337 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) {
338 lock_.AssertAcquired();
339 DCHECK(!is_closed_);
340 // By default, not supported. Only needed for data pipe dispatchers.
341 return MOJO_RESULT_INVALID_ARGUMENT;
342 }
343
344 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock(
345 UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/,
346 scoped_refptr<Dispatcher>* /*new_dispatcher*/) {
347 lock_.AssertAcquired();
348 DCHECK(!is_closed_);
349 // By default, not supported. Only needed for buffer dispatchers.
350 return MOJO_RESULT_INVALID_ARGUMENT;
351 }
352
353 MojoResult Dispatcher::MapBufferImplNoLock(
354 uint64_t /*offset*/,
355 uint64_t /*num_bytes*/,
356 MojoMapBufferFlags /*flags*/,
357 scoped_ptr<embedder::PlatformSharedBufferMapping>* /*mapping*/) {
358 lock_.AssertAcquired();
359 DCHECK(!is_closed_);
360 // By default, not supported. Only needed for buffer dispatchers.
361 return MOJO_RESULT_INVALID_ARGUMENT;
362 }
363
364 HandleSignalsState Dispatcher::GetHandleSignalsStateImplNoLock() const {
365 lock_.AssertAcquired();
366 DCHECK(!is_closed_);
367 // By default, waiting isn't supported. Only dispatchers that can be waited on
368 // will do something nontrivial.
369 return HandleSignalsState();
370 }
371
372 MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/,
373 MojoHandleSignals /*signals*/,
374 uint32_t /*context*/,
375 HandleSignalsState* signals_state) {
376 lock_.AssertAcquired();
377 DCHECK(!is_closed_);
378 // By default, waiting isn't supported. Only dispatchers that can be waited on
379 // will do something nontrivial.
380 if (signals_state)
381 *signals_state = HandleSignalsState();
382 return MOJO_RESULT_FAILED_PRECONDITION;
383 }
384
385 void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/,
386 HandleSignalsState* signals_state) {
387 lock_.AssertAcquired();
388 DCHECK(!is_closed_);
389 // By default, waiting isn't supported. Only dispatchers that can be waited on
390 // will do something nontrivial.
391 if (signals_state)
392 *signals_state = HandleSignalsState();
393 }
394
395 void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/,
396 size_t* max_size,
397 size_t* max_platform_handles) {
398 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
399 DCHECK(!is_closed_);
400 *max_size = 0;
401 *max_platform_handles = 0;
402 }
403
404 bool Dispatcher::EndSerializeAndCloseImplNoLock(
405 Channel* /*channel*/,
406 void* /*destination*/,
407 size_t* /*actual_size*/,
408 embedder::PlatformHandleVector* /*platform_handles*/) {
409 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
410 DCHECK(is_closed_);
411 // By default, serializing isn't supported, so just close.
412 CloseImplNoLock();
413 return false;
414 }
415
416 bool Dispatcher::IsBusyNoLock() const {
417 lock_.AssertAcquired();
418 DCHECK(!is_closed_);
419 // Most dispatchers support only "atomic" operations, so they are never busy
420 // (in this sense).
421 return false;
422 }
423
424 void Dispatcher::CloseNoLock() {
425 lock_.AssertAcquired();
426 DCHECK(!is_closed_);
427
428 is_closed_ = true;
429 CancelAllWaitersNoLock();
430 CloseImplNoLock();
431 }
432
433 scoped_refptr<Dispatcher>
434 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() {
435 lock_.AssertAcquired();
436 DCHECK(!is_closed_);
437
438 is_closed_ = true;
439 CancelAllWaitersNoLock();
440 return CreateEquivalentDispatcherAndCloseImplNoLock();
441 }
442
443 void Dispatcher::StartSerialize(Channel* channel,
444 size_t* max_size,
445 size_t* max_platform_handles) {
446 DCHECK(channel);
447 DCHECK(max_size);
448 DCHECK(max_platform_handles);
449 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
450 DCHECK(!is_closed_);
451 StartSerializeImplNoLock(channel, max_size, max_platform_handles);
452 }
453
454 bool Dispatcher::EndSerializeAndClose(
455 Channel* channel,
456 void* destination,
457 size_t* actual_size,
458 embedder::PlatformHandleVector* platform_handles) {
459 DCHECK(channel);
460 DCHECK(actual_size);
461 DCHECK(HasOneRef()); // Only one ref => no need to take the lock.
462 DCHECK(!is_closed_);
463
464 // Like other |...Close()| methods, we mark ourselves as closed before calling
465 // the impl. But there's no need to cancel waiters: we shouldn't have any (and
466 // shouldn't be in |Core|'s handle table.
467 is_closed_ = true;
468
469 #if !defined(NDEBUG)
470 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking
471 // isn't actually needed, but we need to satisfy assertions (which we don't
472 // want to remove or weaken).
473 base::AutoLock locker(lock_);
474 #endif
475
476 return EndSerializeAndCloseImplNoLock(
477 channel, destination, actual_size, platform_handles);
478 }
479
480 // DispatcherTransport ---------------------------------------------------------
481
482 void DispatcherTransport::End() {
483 DCHECK(dispatcher_);
484 dispatcher_->lock_.Release();
485 dispatcher_ = nullptr;
486 }
487
488 } // namespace system
489 } // namespace mojo
OLDNEW
« no previous file with comments | « mojo/system/dispatcher.h ('k') | mojo/system/dispatcher_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698