Upstream version 11.39.266.0
[platform/framework/web/crosswalk.git] / src / mojo / system / data_pipe.h
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_