// Copyright 2013 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include "mojo/system/dispatcher.h" #include "base/logging.h" #include "mojo/system/constants.h" namespace mojo { namespace system { MojoResult Dispatcher::Close() { base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; is_closed_ = true; CancelAllWaitersNoLock(); return CloseImplNoLock(); } MojoResult Dispatcher::WriteMessage(const void* bytes, uint32_t num_bytes, const std::vector<Dispatcher*>* dispatchers, MojoWriteMessageFlags flags) { DCHECK(!dispatchers || (dispatchers->size() > 0 && dispatchers->size() < kMaxMessageNumHandles)); base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return WriteMessageImplNoLock(bytes, num_bytes, dispatchers, flags); } MojoResult Dispatcher::ReadMessage( void* bytes, uint32_t* num_bytes, std::vector<scoped_refptr<Dispatcher> >* dispatchers, uint32_t* num_dispatchers, MojoReadMessageFlags flags) { DCHECK(!num_dispatchers || *num_dispatchers == 0 || (dispatchers && dispatchers->empty())); base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return ReadMessageImplNoLock(bytes, num_bytes, dispatchers, num_dispatchers, flags); } MojoResult Dispatcher::WriteData(const void* elements, uint32_t* num_elements, MojoWriteDataFlags flags) { base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return WriteDataImplNoLock(elements, num_elements, flags); } MojoResult Dispatcher::BeginWriteData(void** buffer, uint32_t* buffer_num_elements, MojoWriteDataFlags flags) { base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return BeginWriteDataImplNoLock(buffer, buffer_num_elements, flags); } MojoResult Dispatcher::EndWriteData(uint32_t num_elements_written) { base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return EndWriteDataImplNoLock(num_elements_written); } MojoResult Dispatcher::ReadData(void* elements, uint32_t* num_elements, MojoReadDataFlags flags) { base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return ReadDataImplNoLock(elements, num_elements, flags); } MojoResult Dispatcher::BeginReadData(const void** buffer, uint32_t* buffer_num_elements, MojoReadDataFlags flags) { base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return BeginReadDataImplNoLock(buffer, buffer_num_elements, flags); } MojoResult Dispatcher::EndReadData(uint32_t num_elements_read) { base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return EndReadDataImplNoLock(num_elements_read); } MojoResult Dispatcher::AddWaiter(Waiter* waiter, MojoWaitFlags flags, MojoResult wake_result) { DCHECK_GE(wake_result, 0); base::AutoLock locker(lock_); if (is_closed_) return MOJO_RESULT_INVALID_ARGUMENT; return AddWaiterImplNoLock(waiter, flags, wake_result); } void Dispatcher::RemoveWaiter(Waiter* waiter) { base::AutoLock locker(lock_); if (is_closed_) return; RemoveWaiterImplNoLock(waiter); } scoped_refptr<Dispatcher> Dispatcher::CreateEquivalentDispatcherAndCloseNoLock() { lock_.AssertAcquired(); DCHECK(!is_closed_); is_closed_ = true; CancelAllWaitersNoLock(); return CreateEquivalentDispatcherAndCloseImplNoLock(); } Dispatcher::Dispatcher() : is_closed_(false) { } Dispatcher::~Dispatcher() { // Make sure that |Close()| was called. DCHECK(is_closed_); } void Dispatcher::CancelAllWaitersNoLock() { lock_.AssertAcquired(); DCHECK(is_closed_); // By default, waiting isn't supported. Only dispatchers that can be waited on // will do something nontrivial. } MojoResult Dispatcher::CloseImplNoLock() { lock_.AssertAcquired(); DCHECK(is_closed_); // This may not need to do anything. Dispatchers should override this to do // any actual close-time cleanup necessary. return MOJO_RESULT_OK; } MojoResult Dispatcher::WriteMessageImplNoLock( const void* bytes, uint32_t num_bytes, const std::vector<Dispatcher*>* dispatchers, MojoWriteMessageFlags flags) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for message pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::ReadMessageImplNoLock( void* /*bytes*/, uint32_t* /*num_bytes*/, std::vector<scoped_refptr<Dispatcher> >* /*dispatchers*/, uint32_t* /*num_dispatchers*/, MojoReadMessageFlags /*flags*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for message pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::WriteDataImplNoLock(const void* /*elements*/, uint32_t* /*num_elements*/, MojoWriteDataFlags /*flags*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for data pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::BeginWriteDataImplNoLock( void** /*buffer*/, uint32_t* /*buffer_num_elements*/, MojoWriteDataFlags /*flags*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for data pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::EndWriteDataImplNoLock( uint32_t /*num_elements_written*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for data pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::ReadDataImplNoLock(void* /*elements*/, uint32_t* /*num_elements*/, MojoReadDataFlags /*flags*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for data pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::BeginReadDataImplNoLock( const void** /*buffer*/, uint32_t* /*buffer_num_elements*/, MojoReadDataFlags /*flags*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for data pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::EndReadDataImplNoLock(uint32_t /*num_elements_read*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, not supported. Only needed for data pipe dispatchers. return MOJO_RESULT_INVALID_ARGUMENT; } MojoResult Dispatcher::AddWaiterImplNoLock(Waiter* /*waiter*/, MojoWaitFlags /*flags*/, MojoResult /*wake_result*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, waiting isn't supported. Only dispatchers that can be waited on // will do something nontrivial. return MOJO_RESULT_FAILED_PRECONDITION; } void Dispatcher::RemoveWaiterImplNoLock(Waiter* /*waiter*/) { lock_.AssertAcquired(); DCHECK(!is_closed_); // By default, waiting isn't supported. Only dispatchers that can be waited on // will do something nontrivial. } } // namespace system } // namespace mojo