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 #ifndef MOJO_EDK_SYSTEM_DATA_PIPE_H_ | 5 #ifndef MOJO_EDK_SYSTEM_DATA_PIPE_H_ |
6 #define MOJO_EDK_SYSTEM_DATA_PIPE_H_ | 6 #define MOJO_EDK_SYSTEM_DATA_PIPE_H_ |
7 | 7 |
8 #include <stdint.h> | 8 #include <stdint.h> |
9 | 9 |
10 #include "base/macros.h" | 10 #include "base/macros.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/memory/scoped_ptr.h" | 12 #include "base/memory/scoped_ptr.h" |
13 #include "base/synchronization/lock.h" | 13 #include "base/synchronization/lock.h" |
14 #include "mojo/edk/embedder/platform_handle_vector.h" | 14 #include "mojo/edk/embedder/platform_handle_vector.h" |
15 #include "mojo/edk/system/handle_signals_state.h" | 15 #include "mojo/edk/system/handle_signals_state.h" |
16 #include "mojo/edk/system/memory.h" | 16 #include "mojo/edk/system/memory.h" |
17 #include "mojo/edk/system/system_impl_export.h" | 17 #include "mojo/edk/system/system_impl_export.h" |
18 #include "mojo/public/c/system/data_pipe.h" | 18 #include "mojo/public/c/system/data_pipe.h" |
19 #include "mojo/public/c/system/types.h" | 19 #include "mojo/public/c/system/types.h" |
20 | 20 |
21 namespace mojo { | 21 namespace mojo { |
22 namespace system { | 22 namespace system { |
23 | 23 |
24 class Awakable; | 24 class Awakable; |
25 class AwakableList; | 25 class AwakableList; |
26 class Channel; | 26 class Channel; |
| 27 class DataPipeImpl; |
27 | 28 |
28 // |DataPipe| is a base class for secondary objects implementing data pipes, | 29 // |DataPipe| is a base class for secondary objects implementing data pipes, |
29 // similar to |MessagePipe| (see the explanatory comment in core.cc). It is | 30 // similar to |MessagePipe| (see the explanatory comment in core.cc). It is |
30 // typically owned by the dispatcher(s) corresponding to the local endpoints. | 31 // typically owned by the dispatcher(s) corresponding to the local endpoints. |
31 // Its subclasses implement the three cases: local producer and consumer, local | 32 // Its subclasses implement the three cases: local producer and consumer, local |
32 // producer and remote consumer, and remote producer and local consumer. This | 33 // producer and remote consumer, and remote producer and local consumer. This |
33 // class is thread-safe. | 34 // class is thread-safe. |
34 class MOJO_SYSTEM_IMPL_EXPORT DataPipe | 35 class MOJO_SYSTEM_IMPL_EXPORT DataPipe |
35 : public base::RefCountedThreadSafe<DataPipe> { | 36 : public base::RefCountedThreadSafe<DataPipe> { |
36 public: | 37 public: |
37 // The default options for |MojoCreateDataPipe()|. (Real uses should obtain | 38 // The default options for |MojoCreateDataPipe()|. (Real uses should obtain |
38 // this via |ValidateCreateOptions()| with a null |in_options|; this is | 39 // this via |ValidateCreateOptions()| with a null |in_options|; this is |
39 // exposed directly for testing convenience.) | 40 // exposed directly for testing convenience.) |
40 static MojoCreateDataPipeOptions GetDefaultCreateOptions(); | 41 static MojoCreateDataPipeOptions GetDefaultCreateOptions(); |
41 | 42 |
42 // Validates and/or sets default options for |MojoCreateDataPipeOptions|. If | 43 // Validates and/or sets default options for |MojoCreateDataPipeOptions|. If |
43 // non-null, |in_options| must point to a struct of at least | 44 // non-null, |in_options| must point to a struct of at least |
44 // |in_options->struct_size| bytes. |out_options| must point to a (current) | 45 // |in_options->struct_size| bytes. |out_options| must point to a (current) |
45 // |MojoCreateDataPipeOptions| and will be entirely overwritten on success (it | 46 // |MojoCreateDataPipeOptions| and will be entirely overwritten on success (it |
46 // may be partly overwritten on failure). | 47 // may be partly overwritten on failure). |
47 static MojoResult ValidateCreateOptions( | 48 static MojoResult ValidateCreateOptions( |
48 UserPointer<const MojoCreateDataPipeOptions> in_options, | 49 UserPointer<const MojoCreateDataPipeOptions> in_options, |
49 MojoCreateDataPipeOptions* out_options); | 50 MojoCreateDataPipeOptions* out_options); |
50 | 51 |
| 52 // Creates a local (both producer and consumer) data pipe (using |
| 53 // |LocalDataPipeImpl|. |validated_options| should be the output of |
| 54 // |ValidateOptions()|. In particular: |struct_size| is ignored (so |
| 55 // |validated_options| must be the current version of the struct) and |
| 56 // |capacity_num_bytes| must be nonzero. |
| 57 static DataPipe* CreateLocal( |
| 58 const MojoCreateDataPipeOptions& validated_options); |
| 59 |
51 // These are called by the producer dispatcher to implement its methods of | 60 // These are called by the producer dispatcher to implement its methods of |
52 // corresponding names. | 61 // corresponding names. |
53 void ProducerCancelAllAwakables(); | 62 void ProducerCancelAllAwakables(); |
54 void ProducerClose(); | 63 void ProducerClose(); |
55 MojoResult ProducerWriteData(UserPointer<const void> elements, | 64 MojoResult ProducerWriteData(UserPointer<const void> elements, |
56 UserPointer<uint32_t> num_bytes, | 65 UserPointer<uint32_t> num_bytes, |
57 bool all_or_none); | 66 bool all_or_none); |
58 MojoResult ProducerBeginWriteData(UserPointer<void*> buffer, | 67 MojoResult ProducerBeginWriteData(UserPointer<void*> buffer, |
59 UserPointer<uint32_t> buffer_num_bytes, | 68 UserPointer<uint32_t> buffer_num_bytes, |
60 bool all_or_none); | 69 bool all_or_none); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
101 HandleSignalsState* signals_state); | 110 HandleSignalsState* signals_state); |
102 void ConsumerStartSerialize(Channel* channel, | 111 void ConsumerStartSerialize(Channel* channel, |
103 size_t* max_size, | 112 size_t* max_size, |
104 size_t* max_platform_handles); | 113 size_t* max_platform_handles); |
105 bool ConsumerEndSerialize(Channel* channel, | 114 bool ConsumerEndSerialize(Channel* channel, |
106 void* destination, | 115 void* destination, |
107 size_t* actual_size, | 116 size_t* actual_size, |
108 embedder::PlatformHandleVector* platform_handles); | 117 embedder::PlatformHandleVector* platform_handles); |
109 bool ConsumerIsBusy() const; | 118 bool ConsumerIsBusy() const; |
110 | 119 |
111 protected: | 120 // The following are only to be used by |DataPipeImpl| (and its subclasses): |
112 DataPipe(bool has_local_producer, | |
113 bool has_local_consumer, | |
114 const MojoCreateDataPipeOptions& validated_options); | |
115 | |
116 friend class base::RefCountedThreadSafe<DataPipe>; | |
117 virtual ~DataPipe(); | |
118 | 121 |
119 void ProducerCloseNoLock(); | 122 void ProducerCloseNoLock(); |
120 void ConsumerCloseNoLock(); | 123 void ConsumerCloseNoLock(); |
121 | 124 |
122 virtual void ProducerCloseImplNoLock() = 0; | |
123 // |num_bytes.Get()| will be a nonzero multiple of |element_num_bytes_|. | |
124 virtual MojoResult ProducerWriteDataImplNoLock( | |
125 UserPointer<const void> elements, | |
126 UserPointer<uint32_t> num_bytes, | |
127 uint32_t max_num_bytes_to_write, | |
128 uint32_t min_num_bytes_to_write) = 0; | |
129 virtual MojoResult ProducerBeginWriteDataImplNoLock( | |
130 UserPointer<void*> buffer, | |
131 UserPointer<uint32_t> buffer_num_bytes, | |
132 uint32_t min_num_bytes_to_write) = 0; | |
133 virtual MojoResult ProducerEndWriteDataImplNoLock( | |
134 uint32_t num_bytes_written) = 0; | |
135 // Note: A producer should not be writable during a two-phase write. | |
136 virtual HandleSignalsState ProducerGetHandleSignalsStateImplNoLock() | |
137 const = 0; | |
138 virtual void ProducerStartSerializeImplNoLock( | |
139 Channel* channel, | |
140 size_t* max_size, | |
141 size_t* max_platform_handles) = 0; | |
142 virtual bool ProducerEndSerializeImplNoLock( | |
143 Channel* channel, | |
144 void* destination, | |
145 size_t* actual_size, | |
146 embedder::PlatformHandleVector* platform_handles) = 0; | |
147 | |
148 virtual void ConsumerCloseImplNoLock() = 0; | |
149 // |*num_bytes| will be a nonzero multiple of |element_num_bytes_|. | |
150 virtual MojoResult ConsumerReadDataImplNoLock(UserPointer<void> elements, | |
151 UserPointer<uint32_t> num_bytes, | |
152 uint32_t max_num_bytes_to_read, | |
153 uint32_t min_num_bytes_to_read, | |
154 bool peek) = 0; | |
155 virtual MojoResult ConsumerDiscardDataImplNoLock( | |
156 UserPointer<uint32_t> num_bytes, | |
157 uint32_t max_num_bytes_to_discard, | |
158 uint32_t min_num_bytes_to_discard) = 0; | |
159 // |*num_bytes| will be a nonzero multiple of |element_num_bytes_|. | |
160 virtual MojoResult ConsumerQueryDataImplNoLock( | |
161 UserPointer<uint32_t> num_bytes) = 0; | |
162 virtual MojoResult ConsumerBeginReadDataImplNoLock( | |
163 UserPointer<const void*> buffer, | |
164 UserPointer<uint32_t> buffer_num_bytes, | |
165 uint32_t min_num_bytes_to_read) = 0; | |
166 virtual MojoResult ConsumerEndReadDataImplNoLock(uint32_t num_bytes_read) = 0; | |
167 // Note: A consumer should not be writable during a two-phase read. | |
168 virtual HandleSignalsState ConsumerGetHandleSignalsStateImplNoLock() | |
169 const = 0; | |
170 virtual void ConsumerStartSerializeImplNoLock( | |
171 Channel* channel, | |
172 size_t* max_size, | |
173 size_t* max_platform_handles) = 0; | |
174 virtual bool ConsumerEndSerializeImplNoLock( | |
175 Channel* channel, | |
176 void* destination, | |
177 size_t* actual_size, | |
178 embedder::PlatformHandleVector* platform_handles) = 0; | |
179 | |
180 // Thread-safe and fast (they don't take the lock): | 125 // Thread-safe and fast (they don't take the lock): |
181 bool may_discard() const { return may_discard_; } | 126 bool may_discard() const { return may_discard_; } |
182 size_t element_num_bytes() const { return element_num_bytes_; } | 127 size_t element_num_bytes() const { return element_num_bytes_; } |
183 size_t capacity_num_bytes() const { return capacity_num_bytes_; } | 128 size_t capacity_num_bytes() const { return capacity_num_bytes_; } |
184 | 129 |
185 // Must be called under lock. | 130 // Must be called under lock. |
186 bool producer_open_no_lock() const { | 131 bool producer_open_no_lock() const { |
187 lock_.AssertAcquired(); | 132 lock_.AssertAcquired(); |
188 return producer_open_; | 133 return producer_open_; |
189 } | 134 } |
(...skipping 21 matching lines...) Expand all Loading... |
211 bool producer_in_two_phase_write_no_lock() const { | 156 bool producer_in_two_phase_write_no_lock() const { |
212 lock_.AssertAcquired(); | 157 lock_.AssertAcquired(); |
213 return producer_two_phase_max_num_bytes_written_ > 0; | 158 return producer_two_phase_max_num_bytes_written_ > 0; |
214 } | 159 } |
215 bool consumer_in_two_phase_read_no_lock() const { | 160 bool consumer_in_two_phase_read_no_lock() const { |
216 lock_.AssertAcquired(); | 161 lock_.AssertAcquired(); |
217 return consumer_two_phase_max_num_bytes_read_ > 0; | 162 return consumer_two_phase_max_num_bytes_read_ > 0; |
218 } | 163 } |
219 | 164 |
220 private: | 165 private: |
| 166 friend class base::RefCountedThreadSafe<DataPipe>; |
| 167 |
| 168 // |validated_options| should be the output of |ValidateOptions()|. In |
| 169 // particular: |struct_size| is ignored (so |validated_options| must be the |
| 170 // current version of the struct) and |capacity_num_bytes| must be nonzero. |
| 171 // TODO(vtl): |has_local_producer|/|has_local_consumer| shouldn't really be |
| 172 // arguments here. Instead, they should be determined from the |impl| ... but |
| 173 // the |impl|'s typically figures these out by examining the owner, i.e., the |
| 174 // |DataPipe| object. Probably, this indicates that more stuff should be moved |
| 175 // to |DataPipeImpl|, but for now we'll live with this. |
| 176 DataPipe(bool has_local_producer, |
| 177 bool has_local_consumer, |
| 178 const MojoCreateDataPipeOptions& validated_options, |
| 179 scoped_ptr<DataPipeImpl> impl); |
| 180 virtual ~DataPipe(); |
| 181 |
221 void AwakeProducerAwakablesForStateChangeNoLock( | 182 void AwakeProducerAwakablesForStateChangeNoLock( |
222 const HandleSignalsState& new_producer_state); | 183 const HandleSignalsState& new_producer_state); |
223 void AwakeConsumerAwakablesForStateChangeNoLock( | 184 void AwakeConsumerAwakablesForStateChangeNoLock( |
224 const HandleSignalsState& new_consumer_state); | 185 const HandleSignalsState& new_consumer_state); |
225 | 186 |
226 bool has_local_producer_no_lock() const { | 187 bool has_local_producer_no_lock() const { |
227 lock_.AssertAcquired(); | 188 lock_.AssertAcquired(); |
228 return !!producer_awakable_list_; | 189 return !!producer_awakable_list_; |
229 } | 190 } |
230 bool has_local_consumer_no_lock() const { | 191 bool has_local_consumer_no_lock() const { |
231 lock_.AssertAcquired(); | 192 lock_.AssertAcquired(); |
232 return !!consumer_awakable_list_; | 193 return !!consumer_awakable_list_; |
233 } | 194 } |
234 | 195 |
235 const bool may_discard_; | 196 const bool may_discard_; |
236 const size_t element_num_bytes_; | 197 const size_t element_num_bytes_; |
237 const size_t capacity_num_bytes_; | 198 const size_t capacity_num_bytes_; |
238 | 199 |
239 mutable base::Lock lock_; // Protects the following members. | 200 mutable base::Lock lock_; // Protects the following members. |
240 // *Known* state of producer or consumer. | 201 // *Known* state of producer or consumer. |
241 bool producer_open_; | 202 bool producer_open_; |
242 bool consumer_open_; | 203 bool consumer_open_; |
243 // Non-null only if the producer or consumer, respectively, is local. | 204 // Non-null only if the producer or consumer, respectively, is local. |
244 scoped_ptr<AwakableList> producer_awakable_list_; | 205 scoped_ptr<AwakableList> producer_awakable_list_; |
245 scoped_ptr<AwakableList> consumer_awakable_list_; | 206 scoped_ptr<AwakableList> consumer_awakable_list_; |
246 // These are nonzero if and only if a two-phase write/read is in progress. | 207 // These are nonzero if and only if a two-phase write/read is in progress. |
247 uint32_t producer_two_phase_max_num_bytes_written_; | 208 uint32_t producer_two_phase_max_num_bytes_written_; |
248 uint32_t consumer_two_phase_max_num_bytes_read_; | 209 uint32_t consumer_two_phase_max_num_bytes_read_; |
| 210 scoped_ptr<DataPipeImpl> impl_; |
249 | 211 |
250 DISALLOW_COPY_AND_ASSIGN(DataPipe); | 212 DISALLOW_COPY_AND_ASSIGN(DataPipe); |
251 }; | 213 }; |
252 | 214 |
253 } // namespace system | 215 } // namespace system |
254 } // namespace mojo | 216 } // namespace mojo |
255 | 217 |
256 #endif // MOJO_EDK_SYSTEM_DATA_PIPE_H_ | 218 #endif // MOJO_EDK_SYSTEM_DATA_PIPE_H_ |
OLD | NEW |