Home | History | Annotate | Download | only in system
      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
      3 // found in the LICENSE file.
      4 
      5 #ifndef MOJO_SYSTEM_DATA_PIPE_H_
      6 #define MOJO_SYSTEM_DATA_PIPE_H_
      7 
      8 #include <stdint.h>
      9 
     10 #include "base/macros.h"
     11 #include "base/memory/ref_counted.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/synchronization/lock.h"
     14 #include "mojo/public/c/system/data_pipe.h"
     15 #include "mojo/public/c/system/types.h"
     16 #include "mojo/system/handle_signals_state.h"
     17 #include "mojo/system/memory.h"
     18 #include "mojo/system/system_impl_export.h"
     19 
     20 namespace mojo {
     21 namespace system {
     22 
     23 class Waiter;
     24 class WaiterList;
     25 
     26 // |DataPipe| is a base class for secondary objects implementing data pipes,
     27 // similar to |MessagePipe| (see the explanatory comment in core.cc). It is
     28 // typically owned by the dispatcher(s) corresponding to the local endpoints.
     29 // Its subclasses implement the three cases: local producer and consumer, local
     30 // producer and remote consumer, and remote producer and local consumer. This
     31 // class is thread-safe.
     32 class MOJO_SYSTEM_IMPL_EXPORT DataPipe
     33     : public base::RefCountedThreadSafe<DataPipe> {
     34  public:
     35   // The default options for |MojoCreateDataPipe()|. (Real uses should obtain
     36   // this via |ValidateCreateOptions()| with a null |in_options|; this is
     37   // exposed directly for testing convenience.)
     38   static const MojoCreateDataPipeOptions kDefaultCreateOptions;
     39 
     40   // Validates and/or sets default options for |MojoCreateDataPipeOptions|. If
     41   // non-null, |in_options| must point to a struct of at least
     42   // |in_options->struct_size| bytes. |out_options| must point to a (current)
     43   // |MojoCreateDataPipeOptions| and will be entirely overwritten on success (it
     44   // may be partly overwritten on failure).
     45   static MojoResult ValidateCreateOptions(
     46       UserPointer<const MojoCreateDataPipeOptions> in_options,
     47       MojoCreateDataPipeOptions* out_options);
     48 
     49   // These are called by the producer dispatcher to implement its methods of
     50   // corresponding names.
     51   void ProducerCancelAllWaiters();
     52   void ProducerClose();
     53   MojoResult ProducerWriteData(UserPointer<const void> elements,
     54                                UserPointer<uint32_t> num_bytes,
     55                                bool all_or_none);
     56   MojoResult ProducerBeginWriteData(UserPointer<void*> buffer,
     57                                     UserPointer<uint32_t> buffer_num_bytes,
     58                                     bool all_or_none);
     59   MojoResult ProducerEndWriteData(uint32_t num_bytes_written);
     60   HandleSignalsState ProducerGetHandleSignalsState();
     61   MojoResult ProducerAddWaiter(Waiter* waiter,
     62                                MojoHandleSignals signals,
     63                                uint32_t context,
     64                                HandleSignalsState* signals_state);
     65   void ProducerRemoveWaiter(Waiter* waiter, HandleSignalsState* signals_state);
     66   bool ProducerIsBusy() const;
     67 
     68   // These are called by the consumer dispatcher to implement its methods of
     69   // corresponding names.
     70   void ConsumerCancelAllWaiters();
     71   void ConsumerClose();
     72   // This does not validate its arguments, except to check that |*num_bytes| is
     73   // a multiple of |element_num_bytes_|.
     74   MojoResult ConsumerReadData(UserPointer<void> elements,
     75                               UserPointer<uint32_t> num_bytes,
     76                               bool all_or_none);
     77   MojoResult ConsumerDiscardData(UserPointer<uint32_t> num_bytes,
     78                                  bool all_or_none);
     79   MojoResult ConsumerQueryData(UserPointer<uint32_t> num_bytes);
     80   MojoResult ConsumerBeginReadData(UserPointer<const void*> buffer,
     81                                    UserPointer<uint32_t> buffer_num_bytes,
     82                                    bool all_or_none);
     83   MojoResult ConsumerEndReadData(uint32_t num_bytes_read);
     84   HandleSignalsState ConsumerGetHandleSignalsState();
     85   MojoResult ConsumerAddWaiter(Waiter* waiter,
     86                                MojoHandleSignals signals,
     87                                uint32_t context,
     88                                HandleSignalsState* signals_state);
     89   void ConsumerRemoveWaiter(Waiter* waiter, HandleSignalsState* signals_state);
     90   bool ConsumerIsBusy() const;
     91 
     92  protected:
     93   DataPipe(bool has_local_producer,
     94            bool has_local_consumer,
     95            const MojoCreateDataPipeOptions& validated_options);
     96 
     97   friend class base::RefCountedThreadSafe<DataPipe>;
     98   virtual ~DataPipe();
     99 
    100   virtual void ProducerCloseImplNoLock() = 0;
    101   // |num_bytes.Get()| will be a nonzero multiple of |element_num_bytes_|.
    102   virtual MojoResult ProducerWriteDataImplNoLock(
    103       UserPointer<const void> elements,
    104       UserPointer<uint32_t> num_bytes,
    105       uint32_t max_num_bytes_to_write,
    106       uint32_t min_num_bytes_to_write) = 0;
    107   virtual MojoResult ProducerBeginWriteDataImplNoLock(
    108       UserPointer<void*> buffer,
    109       UserPointer<uint32_t> buffer_num_bytes,
    110       uint32_t min_num_bytes_to_write) = 0;
    111   virtual MojoResult ProducerEndWriteDataImplNoLock(
    112       uint32_t num_bytes_written) = 0;
    113   // Note: A producer should not be writable during a two-phase write.
    114   virtual HandleSignalsState ProducerGetHandleSignalsStateImplNoLock()
    115       const = 0;
    116 
    117   virtual void ConsumerCloseImplNoLock() = 0;
    118   // |*num_bytes| will be a nonzero multiple of |element_num_bytes_|.
    119   virtual MojoResult ConsumerReadDataImplNoLock(
    120       UserPointer<void> elements,
    121       UserPointer<uint32_t> num_bytes,
    122       uint32_t max_num_bytes_to_read,
    123       uint32_t min_num_bytes_to_read) = 0;
    124   virtual MojoResult ConsumerDiscardDataImplNoLock(
    125       UserPointer<uint32_t> num_bytes,
    126       uint32_t max_num_bytes_to_discard,
    127       uint32_t min_num_bytes_to_discard) = 0;
    128   // |*num_bytes| will be a nonzero multiple of |element_num_bytes_|.
    129   virtual MojoResult ConsumerQueryDataImplNoLock(
    130       UserPointer<uint32_t> num_bytes) = 0;
    131   virtual MojoResult ConsumerBeginReadDataImplNoLock(
    132       UserPointer<const void*> buffer,
    133       UserPointer<uint32_t> buffer_num_bytes,
    134       uint32_t min_num_bytes_to_read) = 0;
    135   virtual MojoResult ConsumerEndReadDataImplNoLock(uint32_t num_bytes_read) = 0;
    136   // Note: A consumer should not be writable during a two-phase read.
    137   virtual HandleSignalsState ConsumerGetHandleSignalsStateImplNoLock()
    138       const = 0;
    139 
    140   // Thread-safe and fast (they don't take the lock):
    141   bool may_discard() const { return may_discard_; }
    142   size_t element_num_bytes() const { return element_num_bytes_; }
    143   size_t capacity_num_bytes() const { return capacity_num_bytes_; }
    144 
    145   // Must be called under lock.
    146   bool producer_open_no_lock() const {
    147     lock_.AssertAcquired();
    148     return producer_open_;
    149   }
    150   bool consumer_open_no_lock() const {
    151     lock_.AssertAcquired();
    152     return consumer_open_;
    153   }
    154   uint32_t producer_two_phase_max_num_bytes_written_no_lock() const {
    155     lock_.AssertAcquired();
    156     return producer_two_phase_max_num_bytes_written_;
    157   }
    158   uint32_t consumer_two_phase_max_num_bytes_read_no_lock() const {
    159     lock_.AssertAcquired();
    160     return consumer_two_phase_max_num_bytes_read_;
    161   }
    162   void set_producer_two_phase_max_num_bytes_written_no_lock(
    163       uint32_t num_bytes) {
    164     lock_.AssertAcquired();
    165     producer_two_phase_max_num_bytes_written_ = num_bytes;
    166   }
    167   void set_consumer_two_phase_max_num_bytes_read_no_lock(uint32_t num_bytes) {
    168     lock_.AssertAcquired();
    169     consumer_two_phase_max_num_bytes_read_ = num_bytes;
    170   }
    171   bool producer_in_two_phase_write_no_lock() const {
    172     lock_.AssertAcquired();
    173     return producer_two_phase_max_num_bytes_written_ > 0;
    174   }
    175   bool consumer_in_two_phase_read_no_lock() const {
    176     lock_.AssertAcquired();
    177     return consumer_two_phase_max_num_bytes_read_ > 0;
    178   }
    179 
    180  private:
    181   void AwakeProducerWaitersForStateChangeNoLock(
    182       const HandleSignalsState& new_producer_state);
    183   void AwakeConsumerWaitersForStateChangeNoLock(
    184       const HandleSignalsState& new_consumer_state);
    185 
    186   bool has_local_producer_no_lock() const {
    187     lock_.AssertAcquired();
    188     return !!producer_waiter_list_;
    189   }
    190   bool has_local_consumer_no_lock() const {
    191     lock_.AssertAcquired();
    192     return !!consumer_waiter_list_;
    193   }
    194 
    195   const bool may_discard_;
    196   const size_t element_num_bytes_;
    197   const size_t capacity_num_bytes_;
    198 
    199   mutable base::Lock lock_;  // Protects the following members.
    200   // *Known* state of producer or consumer.
    201   bool producer_open_;
    202   bool consumer_open_;
    203   // Non-null only if the producer or consumer, respectively, is local.
    204   scoped_ptr<WaiterList> producer_waiter_list_;
    205   scoped_ptr<WaiterList> consumer_waiter_list_;
    206   // These are nonzero if and only if a two-phase write/read is in progress.
    207   uint32_t producer_two_phase_max_num_bytes_written_;
    208   uint32_t consumer_two_phase_max_num_bytes_read_;
    209 
    210   DISALLOW_COPY_AND_ASSIGN(DataPipe);
    211 };
    212 
    213 }  // namespace system
    214 }  // namespace mojo
    215 
    216 #endif  // MOJO_SYSTEM_DATA_PIPE_H_
    217