| 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 |