| 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/system/dispatcher.h" | 5 #include "mojo/system/dispatcher.h" |
| 6 | 6 |
| 7 #include "base/logging.h" | 7 #include "base/logging.h" |
| 8 #include "mojo/system/constants.h" | 8 #include "mojo/system/constants.h" |
| 9 #include "mojo/system/message_pipe_dispatcher.h" | 9 #include "mojo/system/message_pipe_dispatcher.h" |
| 10 | 10 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 33 | 33 |
| 34 // We shouldn't race with things that close dispatchers, since closing can | 34 // We shouldn't race with things that close dispatchers, since closing can |
| 35 // only take place either under |handle_table_lock_| or when the handle is | 35 // only take place either under |handle_table_lock_| or when the handle is |
| 36 // marked as busy. | 36 // marked as busy. |
| 37 DCHECK(!dispatcher->is_closed_); | 37 DCHECK(!dispatcher->is_closed_); |
| 38 | 38 |
| 39 return DispatcherTransport(dispatcher); | 39 return DispatcherTransport(dispatcher); |
| 40 } | 40 } |
| 41 | 41 |
| 42 // static | 42 // static |
| 43 size_t Dispatcher::MessageInTransitAccess::GetMaximumSerializedSize( | 43 void Dispatcher::MessageInTransitAccess::StartSerialize( |
| 44 const Dispatcher* dispatcher, | 44 Dispatcher* dispatcher, |
| 45 const Channel* channel) { | 45 Channel* channel, |
| 46 size_t* max_size, |
| 47 size_t* max_platform_handles) { |
| 46 DCHECK(dispatcher); | 48 DCHECK(dispatcher); |
| 47 return dispatcher->GetMaximumSerializedSize(channel); | 49 dispatcher->StartSerialize(channel, max_size, max_platform_handles); |
| 48 } | 50 } |
| 49 | 51 |
| 50 // static | 52 // static |
| 51 bool Dispatcher::MessageInTransitAccess::SerializeAndClose( | 53 bool Dispatcher::MessageInTransitAccess::EndSerializeAndClose( |
| 52 Dispatcher* dispatcher, | 54 Dispatcher* dispatcher, |
| 53 Channel* channel, | 55 Channel* channel, |
| 54 void* destination, | 56 void* destination, |
| 55 size_t* actual_size) { | 57 size_t* actual_size, |
| 58 std::vector<embedder::PlatformHandle>* platform_handles) { |
| 56 DCHECK(dispatcher); | 59 DCHECK(dispatcher); |
| 57 return dispatcher->SerializeAndClose(channel, destination, actual_size); | 60 return dispatcher->EndSerializeAndClose(channel, destination, actual_size, |
| 61 platform_handles); |
| 58 } | 62 } |
| 59 | 63 |
| 60 // static | 64 // static |
| 61 scoped_refptr<Dispatcher> Dispatcher::MessageInTransitAccess::Deserialize( | 65 scoped_refptr<Dispatcher> Dispatcher::MessageInTransitAccess::Deserialize( |
| 62 Channel* channel, | 66 Channel* channel, |
| 63 int32_t type, | 67 int32_t type, |
| 64 const void* source, | 68 const void* source, |
| 65 size_t size) { | 69 size_t size) { |
| 66 switch (static_cast<int32_t>(type)) { | 70 switch (static_cast<int32_t>(type)) { |
| 67 case kTypeUnknown: | 71 case kTypeUnknown: |
| (...skipping 276 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 344 return MOJO_RESULT_FAILED_PRECONDITION; | 348 return MOJO_RESULT_FAILED_PRECONDITION; |
| 345 } | 349 } |
| 346 | 350 |
| 347 void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/) { | 351 void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/) { |
| 348 lock_.AssertAcquired(); | 352 lock_.AssertAcquired(); |
| 349 DCHECK(!is_closed_); | 353 DCHECK(!is_closed_); |
| 350 // By default, waiting isn't supported. Only dispatchers that can be waited on | 354 // By default, waiting isn't supported. Only dispatchers that can be waited on |
| 351 // will do something nontrivial. | 355 // will do something nontrivial. |
| 352 } | 356 } |
| 353 | 357 |
| 354 size_t Dispatcher::GetMaximumSerializedSizeImplNoLock( | 358 void Dispatcher::StartSerializeImplNoLock(Channel* /*channel*/, |
| 355 const Channel* /*channel*/) const { | 359 size_t* max_size, |
| 360 size_t* max_platform_handles) { |
| 356 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 361 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
| 357 DCHECK(!is_closed_); | 362 DCHECK(!is_closed_); |
| 358 // By default, serializing isn't supported. | 363 *max_size = 0; |
| 359 return 0; | 364 *max_platform_handles = 0; |
| 360 } | 365 } |
| 361 | 366 |
| 362 bool Dispatcher::SerializeAndCloseImplNoLock(Channel* /*channel*/, | 367 bool Dispatcher::EndSerializeAndCloseImplNoLock( |
| 363 void* /*destination*/, | 368 Channel* /*channel*/, |
| 364 size_t* /*actual_size*/) { | 369 void* /*destination*/, |
| 370 size_t* /*actual_size*/, |
| 371 std::vector<embedder::PlatformHandle>* /*platform_handles*/) { |
| 365 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 372 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
| 366 DCHECK(is_closed_); | 373 DCHECK(is_closed_); |
| 367 // By default, serializing isn't supported, so just close. | 374 // By default, serializing isn't supported, so just close. |
| 368 CloseImplNoLock(); | 375 CloseImplNoLock(); |
| 369 return 0; | 376 return false; |
| 370 } | 377 } |
| 371 | 378 |
| 372 bool Dispatcher::IsBusyNoLock() const { | 379 bool Dispatcher::IsBusyNoLock() const { |
| 373 lock_.AssertAcquired(); | 380 lock_.AssertAcquired(); |
| 374 DCHECK(!is_closed_); | 381 DCHECK(!is_closed_); |
| 375 // Most dispatchers support only "atomic" operations, so they are never busy | 382 // Most dispatchers support only "atomic" operations, so they are never busy |
| 376 // (in this sense). | 383 // (in this sense). |
| 377 return false; | 384 return false; |
| 378 } | 385 } |
| 379 | 386 |
| 380 void Dispatcher::CloseNoLock() { | 387 void Dispatcher::CloseNoLock() { |
| 381 lock_.AssertAcquired(); | 388 lock_.AssertAcquired(); |
| 382 DCHECK(!is_closed_); | 389 DCHECK(!is_closed_); |
| 383 | 390 |
| 384 is_closed_ = true; | 391 is_closed_ = true; |
| 385 CancelAllWaitersNoLock(); | 392 CancelAllWaitersNoLock(); |
| 386 CloseImplNoLock(); | 393 CloseImplNoLock(); |
| 387 } | 394 } |
| 388 | 395 |
| 389 scoped_refptr<Dispatcher> | 396 scoped_refptr<Dispatcher> |
| 390 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { | 397 Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { |
| 391 lock_.AssertAcquired(); | 398 lock_.AssertAcquired(); |
| 392 DCHECK(!is_closed_); | 399 DCHECK(!is_closed_); |
| 393 | 400 |
| 394 is_closed_ = true; | 401 is_closed_ = true; |
| 395 CancelAllWaitersNoLock(); | 402 CancelAllWaitersNoLock(); |
| 396 return CreateEquivalentDispatcherAndCloseImplNoLock(); | 403 return CreateEquivalentDispatcherAndCloseImplNoLock(); |
| 397 } | 404 } |
| 398 | 405 |
| 399 size_t Dispatcher::GetMaximumSerializedSize(const Channel* channel) const { | 406 void Dispatcher::StartSerialize(Channel* channel, |
| 407 size_t* max_size, |
| 408 size_t* max_platform_handles) { |
| 400 DCHECK(channel); | 409 DCHECK(channel); |
| 410 DCHECK(max_size); |
| 411 DCHECK(max_platform_handles); |
| 401 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 412 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
| 402 DCHECK(!is_closed_); | 413 DCHECK(!is_closed_); |
| 403 return GetMaximumSerializedSizeImplNoLock(channel); | 414 StartSerializeImplNoLock(channel, max_size, max_platform_handles); |
| 404 } | 415 } |
| 405 | 416 |
| 406 bool Dispatcher::SerializeAndClose(Channel* channel, | 417 bool Dispatcher::EndSerializeAndClose( |
| 407 void* destination, | 418 Channel* channel, |
| 408 size_t* actual_size) { | 419 void* destination, |
| 409 DCHECK(destination); | 420 size_t* actual_size, |
| 421 std::vector<embedder::PlatformHandle>* platform_handles) { |
| 410 DCHECK(channel); | 422 DCHECK(channel); |
| 411 DCHECK(actual_size); | 423 DCHECK(actual_size); |
| 412 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. | 424 DCHECK(HasOneRef()); // Only one ref => no need to take the lock. |
| 413 DCHECK(!is_closed_); | 425 DCHECK(!is_closed_); |
| 414 | 426 |
| 415 // We have to call |GetMaximumSerializedSizeImplNoLock()| first, because we | |
| 416 // leave it to |SerializeAndCloseImplNoLock()| to close the thing. | |
| 417 #if DCHECK_IS_ON | |
| 418 size_t max_size = GetMaximumSerializedSizeImplNoLock(channel); | |
| 419 #else | |
| 420 size_t max_size = static_cast<size_t>(-1); | |
| 421 #endif | |
| 422 | |
| 423 // Like other |...Close()| methods, we mark ourselves as closed before calling | 427 // Like other |...Close()| methods, we mark ourselves as closed before calling |
| 424 // the impl. | 428 // the impl. |
| 425 is_closed_ = true; | 429 is_closed_ = true; |
| 426 // No need to cancel waiters: we shouldn't have any (and shouldn't be in | 430 // No need to cancel waiters: we shouldn't have any (and shouldn't be in |
| 427 // |Core|'s handle table. | 431 // |Core|'s handle table. |
| 428 | 432 |
| 429 if (!SerializeAndCloseImplNoLock(channel, destination, actual_size)) | 433 #if !defined(NDEBUG) |
| 430 return false; | 434 // See the comment above |EndSerializeAndCloseImplNoLock()|. In brief: Locking |
| 435 // isn't actually needed, but we need to satisfy assertions (which we don't |
| 436 // want to remove or weaken). |
| 437 base::AutoLock locker(lock_); |
| 438 #endif |
| 431 | 439 |
| 432 DCHECK_LE(*actual_size, max_size); | 440 return EndSerializeAndCloseImplNoLock(channel, destination, actual_size, |
| 433 return true; | 441 platform_handles); |
| 434 } | 442 } |
| 435 | 443 |
| 436 // DispatcherTransport --------------------------------------------------------- | 444 // DispatcherTransport --------------------------------------------------------- |
| 437 | 445 |
| 438 void DispatcherTransport::End() { | 446 void DispatcherTransport::End() { |
| 439 DCHECK(dispatcher_); | 447 DCHECK(dispatcher_); |
| 440 dispatcher_->lock_.Release(); | 448 dispatcher_->lock_.Release(); |
| 441 dispatcher_ = NULL; | 449 dispatcher_ = NULL; |
| 442 } | 450 } |
| 443 | 451 |
| 444 } // namespace system | 452 } // namespace system |
| 445 } // namespace mojo | 453 } // namespace mojo |
| OLD | NEW |