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/edk/system/dispatcher.h" | 5 #include "mojo/edk/system/dispatcher.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "mojo/edk/system/configuration.h" | 8 #include "mojo/edk/system/configuration.h" |
9 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" | 9 #include "mojo/edk/system/data_pipe_consumer_dispatcher.h" |
10 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" | 10 #include "mojo/edk/system/data_pipe_producer_dispatcher.h" |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
60 Channel* channel, | 60 Channel* channel, |
61 void* destination, | 61 void* destination, |
62 size_t* actual_size, | 62 size_t* actual_size, |
63 embedder::PlatformHandleVector* platform_handles) { | 63 embedder::PlatformHandleVector* platform_handles) { |
64 DCHECK(dispatcher); | 64 DCHECK(dispatcher); |
65 return dispatcher->EndSerializeAndClose(channel, destination, actual_size, | 65 return dispatcher->EndSerializeAndClose(channel, destination, actual_size, |
66 platform_handles); | 66 platform_handles); |
67 } | 67 } |
68 | 68 |
69 // static | 69 // static |
70 scoped_refptr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize( | 70 RefPtr<Dispatcher> Dispatcher::TransportDataAccess::Deserialize( |
71 Channel* channel, | 71 Channel* channel, |
72 int32_t type, | 72 int32_t type, |
73 const void* source, | 73 const void* source, |
74 size_t size, | 74 size_t size, |
75 embedder::PlatformHandleVector* platform_handles) { | 75 embedder::PlatformHandleVector* platform_handles) { |
76 switch (static_cast<Dispatcher::Type>(type)) { | 76 switch (static_cast<Dispatcher::Type>(type)) { |
77 case Type::UNKNOWN: | 77 case Type::UNKNOWN: |
78 DVLOG(2) << "Deserializing invalid handle"; | 78 DVLOG(2) << "Deserializing invalid handle"; |
79 return nullptr; | 79 return nullptr; |
80 case Type::MESSAGE_PIPE: | 80 case Type::MESSAGE_PIPE: |
81 return scoped_refptr<Dispatcher>( | 81 return MessagePipeDispatcher::Deserialize(channel, source, size); |
82 MessagePipeDispatcher::Deserialize(channel, source, size)); | |
83 case Type::DATA_PIPE_PRODUCER: | 82 case Type::DATA_PIPE_PRODUCER: |
84 return scoped_refptr<Dispatcher>( | 83 return DataPipeProducerDispatcher::Deserialize(channel, source, size); |
85 DataPipeProducerDispatcher::Deserialize(channel, source, size)); | |
86 case Type::DATA_PIPE_CONSUMER: | 84 case Type::DATA_PIPE_CONSUMER: |
87 return scoped_refptr<Dispatcher>( | 85 return DataPipeConsumerDispatcher::Deserialize(channel, source, size); |
88 DataPipeConsumerDispatcher::Deserialize(channel, source, size)); | |
89 case Type::SHARED_BUFFER: | 86 case Type::SHARED_BUFFER: |
90 return scoped_refptr<Dispatcher>(SharedBufferDispatcher::Deserialize( | 87 return SharedBufferDispatcher::Deserialize(channel, source, size, |
91 channel, source, size, platform_handles)); | 88 platform_handles); |
92 case Type::PLATFORM_HANDLE: | 89 case Type::PLATFORM_HANDLE: |
93 return scoped_refptr<Dispatcher>(PlatformHandleDispatcher::Deserialize( | 90 return PlatformHandleDispatcher::Deserialize(channel, source, size, |
94 channel, source, size, platform_handles)); | 91 platform_handles); |
95 } | 92 } |
96 LOG(WARNING) << "Unknown dispatcher type " << type; | 93 LOG(WARNING) << "Unknown dispatcher type " << type; |
97 return nullptr; | 94 return nullptr; |
98 } | 95 } |
99 | 96 |
100 MojoResult Dispatcher::Close() { | 97 MojoResult Dispatcher::Close() { |
101 MutexLocker locker(&mutex_); | 98 MutexLocker locker(&mutex_); |
102 if (is_closed_) | 99 if (is_closed_) |
103 return MOJO_RESULT_INVALID_ARGUMENT; | 100 return MOJO_RESULT_INVALID_ARGUMENT; |
104 | 101 |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { | 186 MojoResult Dispatcher::EndReadData(uint32_t num_bytes_read) { |
190 MutexLocker locker(&mutex_); | 187 MutexLocker locker(&mutex_); |
191 if (is_closed_) | 188 if (is_closed_) |
192 return MOJO_RESULT_INVALID_ARGUMENT; | 189 return MOJO_RESULT_INVALID_ARGUMENT; |
193 | 190 |
194 return EndReadDataImplNoLock(num_bytes_read); | 191 return EndReadDataImplNoLock(num_bytes_read); |
195 } | 192 } |
196 | 193 |
197 MojoResult Dispatcher::DuplicateBufferHandle( | 194 MojoResult Dispatcher::DuplicateBufferHandle( |
198 UserPointer<const MojoDuplicateBufferHandleOptions> options, | 195 UserPointer<const MojoDuplicateBufferHandleOptions> options, |
199 scoped_refptr<Dispatcher>* new_dispatcher) { | 196 RefPtr<Dispatcher>* new_dispatcher) { |
200 MutexLocker locker(&mutex_); | 197 MutexLocker locker(&mutex_); |
201 if (is_closed_) | 198 if (is_closed_) |
202 return MOJO_RESULT_INVALID_ARGUMENT; | 199 return MOJO_RESULT_INVALID_ARGUMENT; |
203 | 200 |
204 return DuplicateBufferHandleImplNoLock(options, new_dispatcher); | 201 return DuplicateBufferHandleImplNoLock(options, new_dispatcher); |
205 } | 202 } |
206 | 203 |
207 MojoResult Dispatcher::MapBuffer( | 204 MojoResult Dispatcher::MapBuffer( |
208 uint64_t offset, | 205 uint64_t offset, |
209 uint64_t num_bytes, | 206 uint64_t num_bytes, |
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
342 | 339 |
343 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { | 340 MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_bytes_read*/) { |
344 mutex_.AssertHeld(); | 341 mutex_.AssertHeld(); |
345 DCHECK(!is_closed_); | 342 DCHECK(!is_closed_); |
346 // By default, not supported. Only needed for data pipe dispatchers. | 343 // By default, not supported. Only needed for data pipe dispatchers. |
347 return MOJO_RESULT_INVALID_ARGUMENT; | 344 return MOJO_RESULT_INVALID_ARGUMENT; |
348 } | 345 } |
349 | 346 |
350 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock( | 347 MojoResult Dispatcher::DuplicateBufferHandleImplNoLock( |
351 UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/, | 348 UserPointer<const MojoDuplicateBufferHandleOptions> /*options*/, |
352 scoped_refptr<Dispatcher>* /*new_dispatcher*/) { | 349 RefPtr<Dispatcher>* /*new_dispatcher*/) { |
353 mutex_.AssertHeld(); | 350 mutex_.AssertHeld(); |
354 DCHECK(!is_closed_); | 351 DCHECK(!is_closed_); |
355 // By default, not supported. Only needed for buffer dispatchers. | 352 // By default, not supported. Only needed for buffer dispatchers. |
356 return MOJO_RESULT_INVALID_ARGUMENT; | 353 return MOJO_RESULT_INVALID_ARGUMENT; |
357 } | 354 } |
358 | 355 |
359 MojoResult Dispatcher::MapBufferImplNoLock( | 356 MojoResult Dispatcher::MapBufferImplNoLock( |
360 uint64_t /*offset*/, | 357 uint64_t /*offset*/, |
361 uint64_t /*num_bytes*/, | 358 uint64_t /*num_bytes*/, |
362 MojoMapBufferFlags /*flags*/, | 359 MojoMapBufferFlags /*flags*/, |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
395 DCHECK(!is_closed_); | 392 DCHECK(!is_closed_); |
396 // By default, waiting isn't supported. Only dispatchers that can be waited on | 393 // By default, waiting isn't supported. Only dispatchers that can be waited on |
397 // will do something nontrivial. | 394 // will do something nontrivial. |
398 if (signals_state) | 395 if (signals_state) |
399 *signals_state = HandleSignalsState(); | 396 *signals_state = HandleSignalsState(); |
400 } | 397 } |
401 | 398 |
402 void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/, | 399 void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/, |
403 size_t* max_size, | 400 size_t* max_size, |
404 size_t* max_platform_handles) { | 401 size_t* max_platform_handles) { |
405 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 402 AssertHasOneRef(); // Only one ref => no need to take the lock. |
406 DCHECK(!is_closed_); | 403 DCHECK(!is_closed_); |
407 *max_size = 0; | 404 *max_size = 0; |
408 *max_platform_handles = 0; | 405 *max_platform_handles = 0; |
409 } | 406 } |
410 | 407 |
411 bool Dispatcher::EndSerializeAndCloseImplNoLock( | 408 bool Dispatcher::EndSerializeAndCloseImplNoLock( |
412 Channel* /*channel*/, | 409 Channel* /*channel*/, |
413 void* /*destination*/, | 410 void* /*destination*/, |
414 size_t* /*actual_size*/, | 411 size_t* /*actual_size*/, |
415 embedder::PlatformHandleVector* /*platform_handles*/) { | 412 embedder::PlatformHandleVector* /*platform_handles*/) { |
416 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 413 AssertHasOneRef(); // Only one ref => no need to take the lock. |
417 DCHECK(is_closed_); | 414 DCHECK(is_closed_); |
418 // By default, serializing isn't supported, so just close. | 415 // By default, serializing isn't supported, so just close. |
419 CloseImplNoLock(); | 416 CloseImplNoLock(); |
420 return false; | 417 return false; |
421 } | 418 } |
422 | 419 |
423 bool Dispatcher::IsBusyNoLock() const { | 420 bool Dispatcher::IsBusyNoLock() const { |
424 mutex_.AssertHeld(); | 421 mutex_.AssertHeld(); |
425 DCHECK(!is_closed_); | 422 DCHECK(!is_closed_); |
426 // Most dispatchers support only "atomic" operations, so they are never busy | 423 // Most dispatchers support only "atomic" operations, so they are never busy |
427 // (in this sense). | 424 // (in this sense). |
428 return false; | 425 return false; |
429 } | 426 } |
430 | 427 |
431 void Dispatcher::CloseNoLock() { | 428 void Dispatcher::CloseNoLock() { |
432 mutex_.AssertHeld(); | 429 mutex_.AssertHeld(); |
433 DCHECK(!is_closed_); | 430 DCHECK(!is_closed_); |
434 | 431 |
435 is_closed_ = true; | 432 is_closed_ = true; |
436 CancelAllAwakablesNoLock(); | 433 CancelAllAwakablesNoLock(); |
437 CloseImplNoLock(); | 434 CloseImplNoLock(); |
438 } | 435 } |
439 | 436 |
440 scoped_refptr<Dispatcher> | 437 RefPtr<Dispatcher> Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { |
441 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { | |
442 mutex_.AssertHeld(); | 438 mutex_.AssertHeld(); |
443 DCHECK(!is_closed_); | 439 DCHECK(!is_closed_); |
444 | 440 |
445 is_closed_ = true; | 441 is_closed_ = true; |
446 CancelAllAwakablesNoLock(); | 442 CancelAllAwakablesNoLock(); |
447 return CreateEquivalentDispatcherAndCloseImplNoLock(); | 443 return CreateEquivalentDispatcherAndCloseImplNoLock(); |
448 } | 444 } |
449 | 445 |
450 void Dispatcher::StartSerialize(Channel* channel, | 446 void Dispatcher::StartSerialize(Channel* channel, |
451 size_t* max_size, | 447 size_t* max_size, |
452 size_t* max_platform_handles) { | 448 size_t* max_platform_handles) { |
453 DCHECK(channel); | 449 DCHECK(channel); |
454 DCHECK(max_size); | 450 DCHECK(max_size); |
455 DCHECK(max_platform_handles); | 451 DCHECK(max_platform_handles); |
456 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 452 AssertHasOneRef(); // Only one ref => no need to take the lock. |
457 DCHECK(!is_closed_); | 453 DCHECK(!is_closed_); |
458 StartSerializeImplNoLock(channel, max_size, max_platform_handles); | 454 StartSerializeImplNoLock(channel, max_size, max_platform_handles); |
459 } | 455 } |
460 | 456 |
461 bool Dispatcher::EndSerializeAndClose( | 457 bool Dispatcher::EndSerializeAndClose( |
462 Channel* channel, | 458 Channel* channel, |
463 void* destination, | 459 void* destination, |
464 size_t* actual_size, | 460 size_t* actual_size, |
465 embedder::PlatformHandleVector* platform_handles) { | 461 embedder::PlatformHandleVector* platform_handles) { |
466 DCHECK(channel); | 462 DCHECK(channel); |
467 DCHECK(actual_size); | 463 DCHECK(actual_size); |
468 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 464 AssertHasOneRef(); // Only one ref => no need to take the lock. |
469 DCHECK(!is_closed_); | 465 DCHECK(!is_closed_); |
470 | 466 |
471 // Like other |...Close()| methods, we mark ourselves as closed before calling | 467 // Like other |...Close()| methods, we mark ourselves as closed before calling |
472 // the impl. But there's no need to cancel waiters: we shouldn't have any (and | 468 // the impl. But there's no need to cancel waiters: we shouldn't have any (and |
473 // shouldn't be in |Core|'s handle table. | 469 // shouldn't be in |Core|'s handle table. |
474 is_closed_ = true; | 470 is_closed_ = true; |
475 | 471 |
476 #if !defined(NDEBUG) | 472 #if !defined(NDEBUG) |
477 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking | 473 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking |
478 // isn't actually needed, but we need to satisfy assertions (which we don't | 474 // isn't actually needed, but we need to satisfy assertions (which we don't |
479 // want to remove or weaken). | 475 // want to remove or weaken). |
480 MutexLocker locker(&mutex_); | 476 MutexLocker locker(&mutex_); |
481 #endif | 477 #endif |
482 | 478 |
483 return EndSerializeAndCloseImplNoLock(channel, destination, actual_size, | 479 return EndSerializeAndCloseImplNoLock(channel, destination, actual_size, |
484 platform_handles); | 480 platform_handles); |
485 } | 481 } |
486 | 482 |
487 // DispatcherTransport --------------------------------------------------------- | 483 // DispatcherTransport --------------------------------------------------------- |
488 | 484 |
489 void DispatcherTransport::End() { | 485 void DispatcherTransport::End() { |
490 DCHECK(dispatcher_); | 486 DCHECK(dispatcher_); |
491 dispatcher_->mutex_.Unlock(); | 487 dispatcher_->mutex_.Unlock(); |
492 dispatcher_ = nullptr; | 488 dispatcher_ = nullptr; |
493 } | 489 } |
494 | 490 |
495 } // namespace system | 491 } // namespace system |
496 } // namespace mojo | 492 } // namespace mojo |
OLD | NEW |