// 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. #ifndef MOJO_SYSTEM_DATA_PIPE_H_ #define MOJO_SYSTEM_DATA_PIPE_H_ #include "base/basictypes.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/synchronization/lock.h" #include "mojo/public/system/core.h" #include "mojo/system/system_impl_export.h" namespace mojo { namespace system { class Waiter; class WaiterList; // |DataPipe| is a base class for secondary objects implementing data pipes, // similar to |MessagePipe| (see the explanatory comment in core_impl.cc). It is // typically owned by the dispatcher(s) corresponding to the local endpoints. // Its subclasses implement the three cases: local producer and consumer, local // producer and remote consumer, and remote producer and local consumer. This // class is thread-safe. class MOJO_SYSTEM_IMPL_EXPORT DataPipe : public base::RefCountedThreadSafe<DataPipe> { public: // These are called by the producer dispatcher to implement its methods of // corresponding names. void ProducerCancelAllWaiters(); void ProducerClose(); // This does not validate its arguments. MojoResult ProducerWriteData(const void* elements, uint32_t* num_elements, MojoWriteDataFlags flags); // This does not validate its arguments. MojoResult ProducerBeginWriteData(void** buffer, uint32_t* buffer_num_elements, MojoWriteDataFlags flags); MojoResult ProducerEndWriteData(uint32_t num_elements_written); MojoResult ProducerAddWaiter(Waiter* waiter, MojoWaitFlags flags, MojoResult wake_result); void ProducerRemoveWaiter(Waiter* waiter); // These are called by the consumer dispatcher to implement its methods of // corresponding names. void ConsumerCancelAllWaiters(); void ConsumerClose(); // This does not validate its arguments. MojoResult ConsumerReadData(void* elements, uint32_t* num_elements, MojoReadDataFlags flags); // This does not validate its arguments. MojoResult ConsumerBeginReadData(const void** buffer, uint32_t* buffer_num_elements, MojoReadDataFlags flags); MojoResult ConsumerEndReadData(uint32_t num_elements_read); MojoResult ConsumerAddWaiter(Waiter* waiter, MojoWaitFlags flags, MojoResult wake_result); void ConsumerRemoveWaiter(Waiter* waiter); // Thread-safe and fast (they don't take the lock): bool may_discard() const { return may_discard_; } size_t element_size() const { return element_size_; } size_t capacity_num_elements() const { return capacity_num_elements_; } protected: DataPipe(bool has_local_producer, bool has_local_consumer); friend class base::RefCountedThreadSafe<DataPipe>; virtual ~DataPipe(); // Not thread-safe; must be called before any other methods are called. This // object is only usable on success. MojoResult Init(bool may_discard, size_t element_size, size_t capacity_num_elements); void AwakeProducerWaitersForStateChangeNoLock(); void AwakeConsumerWaitersForStateChangeNoLock(); virtual void ProducerCloseImplNoLock() = 0; virtual MojoResult ProducerBeginWriteDataImplNoLock( void** buffer, uint32_t* buffer_num_elements, MojoWriteDataFlags flags) = 0; virtual MojoResult ProducerEndWriteDataImplNoLock( uint32_t num_elements_written) = 0; virtual MojoWaitFlags ProducerSatisfiedFlagsNoLock() = 0; virtual MojoWaitFlags ProducerSatisfiableFlagsNoLock() = 0; virtual void ConsumerCloseImplNoLock() = 0; virtual MojoResult ConsumerDiscardDataNoLock(uint32_t* num_elements, bool all_or_none) = 0; virtual MojoResult ConsumerQueryDataNoLock(uint32_t* num_elements) = 0; virtual MojoResult ConsumerBeginReadDataImplNoLock( const void** buffer, uint32_t* buffer_num_elements, MojoReadDataFlags flags) = 0; virtual MojoResult ConsumerEndReadDataImplNoLock( uint32_t num_elements_read) = 0; virtual MojoWaitFlags ConsumerSatisfiedFlagsNoLock() = 0; virtual MojoWaitFlags ConsumerSatisfiableFlagsNoLock() = 0; private: bool has_local_producer_no_lock() const { return !!producer_waiter_list_.get(); } bool has_local_consumer_no_lock() const { return !!consumer_waiter_list_.get(); } // Set by |Init()| and never changed afterwards: bool may_discard_; size_t element_size_; size_t capacity_num_elements_; base::Lock lock_; // Protects the following members. scoped_ptr<WaiterList> producer_waiter_list_; scoped_ptr<WaiterList> consumer_waiter_list_; bool producer_in_two_phase_write_; bool consumer_in_two_phase_read_; DISALLOW_COPY_AND_ASSIGN(DataPipe); }; } // namespace system } // namespace mojo #endif // MOJO_SYSTEM_DATA_PIPE_H_