OpenDDS  Snapshot(2023/04/28-20:55)
ZeroCopySeq_T.h
Go to the documentation of this file.
1 /*
2  * Distributed under the OpenDDS License.
3  * See: http://www.opendds.org/license.html
4  */
5 
6 #ifndef OPENDDS_DCPS_ZEROCOPYSEQ_T_H
7 #define OPENDDS_DCPS_ZEROCOPYSEQ_T_H
8 
9 #include <ace/config-macros.h>
10 #ifndef ACE_LACKS_PRAGMA_ONCE
11 # pragma once
12 #endif
13 
14 #include "ZeroCopySeqBase.h"
15 #include "ZeroCopyAllocator_T.h"
16 
17 #include <ace/Vector_T.h>
18 
20 
21 namespace OpenDDS {
22 namespace DCPS {
23 
24 class DataReaderImpl;
25 class ReceivedDataElement;
26 
27 } // namespace DCPS
28 } // namespace OpenDDS
29 
31 
32 
34 
35 //This must stay in namespace "TAO" until the tao_idl compiler is changed
36 namespace TAO {
37 namespace DCPS {
38 
39 /**
40 * Provides [] operators returning sample references
41 * but it is implemented as
42 * an "array" of pointers to the samples so they can be
43 * "loaned" to the application code.
44 *
45 * Design Goals:
46 * - Provide enhanced performance known as "zero-copy" in the DDS spec
47 * - Conform to the C++ CORBA mapping for sequences
48 * - When necessary, certain uncommon sequence operations (resize,
49 * get_buffer, replace) will cause copies. Performance impacts are
50 * noted in comments on the individual methods.
51 */
52 template <class Sample_T, size_t DEF_MAX = DCPS_ZERO_COPY_SEQ_DEFAULT_SIZE>
54 public:
55 
56  typedef Sample_T value_type;
57 
58  /**
59  * Construct a sequence of sample data values that supports
60  * zero-copy reads.
61  *
62  * @param maximum Maximum number of samples to insert into the sequence.
63  * If == 0 then use zero-copy reading.
64  * Defaults to zero hence supporting zero-copy reads/takes.
65  *
66  * @param init_size Initial size of the underlying array of pointers.
67  *
68  * @param alloc The allocator used to allocate the array of pointers
69  * to samples. If zero then use the default allocator.
70  *
71  * This constructor also serves as the "maximum" ctor and default ctor
72  * in the CORBA spec.
73  */
74  explicit ZeroCopyDataSeq(CORBA::ULong maximum = 0,
75  CORBA::ULong init_size = DEF_MAX, ACE_Allocator* alloc = 0);
76 
78  Sample_T* buffer, CORBA::Boolean release = false);
79 
80  ZeroCopyDataSeq(const ZeroCopyDataSeq& frm);
81 
82  ZeroCopyDataSeq& operator=(const ZeroCopyDataSeq& frm);
83 
84  void swap(ZeroCopyDataSeq& frm);
85 
86  ~ZeroCopyDataSeq();
87 
88  CORBA::ULong maximum() const;
89 
90  /** Performance note: increasing the length of a zero-copy sequence past
91  * its current length may cause a copy (the sequence will no longer be
92  * zero-copy enabled).
93  */
94  void length(CORBA::ULong length);
95  CORBA::ULong length() const;
96 
97  const Sample_T& operator[](CORBA::ULong i) const;
98  Sample_T& operator[](CORBA::ULong i);
99 
100  CORBA::Boolean release() const;
101 
102  void replace(CORBA::ULong max, CORBA::ULong length, Sample_T* buffer,
103  CORBA::Boolean release = false);
104 
105  Sample_T* get_buffer(CORBA::Boolean orphan = false);
106  const Sample_T* get_buffer() const;
107 
108  static Sample_T* allocbuf(CORBA::ULong nelems);
109  static void freebuf(Sample_T* buffer);
110 
111  void increment_references();
112 
113  ///Only used by the FooDataReaderImpl and tests
115  public:
117  : seq_(seq) {}
118 
120  return seq_.max_slots();
121  }
122 
124  seq_.internal_set_length(len);
125  }
126 
128  seq_.set_loaner(loaner);
129  }
130 
132  seq_.assign_ptr(ii, item);
133  }
134 
136  return seq_.get_ptr(ii);
137  }
138 
139  void assign_sample(CORBA::ULong ii, const Sample_T& sample) {
140  seq_.assign_sample(ii, sample);
141  }
142 
143  void increment_references() { seq_.increment_references(); }
144 
145  private:
147  };
148  friend class PrivateMemberAccess;
149 
150 private:
151 
152  /**
153  * In some versions of ACE, ACE_Vector doesn't have a working swap()
154  * function, so we have to provide our own.
155  *
156  * This version also provides public access to the allocator_ member,
157  * something the ACE_Vector doesn't do
158  */
160  : public ACE_Vector<OpenDDS::DCPS::ReceivedDataElement*, DEF_MAX> {
161  public:
162  ZeroCopyVector(const size_t init_size = DEF_MAX, ACE_Allocator* alloc = 0);
163 
164  void swap(ZeroCopyVector&);
165 
167  using BASE::allocator_;
168  using BASE::array_;
169  };
170 
171  /**
172  * Current allocated number of sample slots.
173  *
174  * @note The DDS specification's use of maximum=0 to designate
175  * zero-copy read request requires some
176  * way of knowing the internally allocated slots
177  * for sample pointers that is not "maximum".
178  */
179  CORBA::ULong max_slots() const;
180 
181  void internal_set_length(CORBA::ULong len);
182 
183  void set_loaner(OpenDDS::DCPS::DataReaderImpl* loaner);
184 
185  void assign_ptr(CORBA::ULong ii, OpenDDS::DCPS::ReceivedDataElement* item);
186 
188 
189  void assign_sample(CORBA::ULong ii, const Sample_T& sample);
190 
191  bool is_zero_copy() const;
192 
193  void make_single_copy(CORBA::ULong maximum);
194 
195  /// The loaner that loaned its samples.
197 
198  /// the default allocator
201 
203 
204  /// array of pointers if the sequence is supporting zero-copy reads
205  Ptr_Seq_Type ptrs_;
206  static Sample_T default_;
207 
208  //single-copy (aka non-zero-copy) support
211  mutable Sample_T* sc_buffer_;
213 
214 }; // class ZeroCopyDataSeq
215 
216 } // namespace DCPS
217 } // namespace TAO
218 
220 
221 #if defined (__ACE_INLINE__)
222 #include "ZeroCopySeq_T.inl"
223 #endif /* __ACE_INLINE__ */
224 
225 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
226 #include "ZeroCopySeq_T.cpp"
227 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
228 
229 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
230 #pragma message ("ZeroCopySeq_T.cpp template inst")
231 #pragma implementation ("ZeroCopySeq_T.cpp")
232 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
233 
234 #endif /* ZEROCOPYSEQ_H */
void set_loaner(::OpenDDS::DCPS::DataReaderImpl *loaner)
void swap(MessageBlock &lhs, MessageBlock &rhs)
#define TAO_BEGIN_VERSIONED_NAMESPACE_DECL
void release(T x)
Ptr_Seq_Type ptrs_
array of pointers if the sequence is supporting zero-copy reads
ACE_CDR::ULong ULong
ACE_CDR::Boolean Boolean
OpenDDS::DCPS::DataReaderImpl * loaner_
The loaner that loaned its samples.
Implements the DDS::DataReader interface.
void assign_ptr(CORBA::ULong ii, OpenDDS::DCPS::ReceivedDataElement *item)
void assign_sample(CORBA::ULong ii, const Sample_T &sample)
ACE_Vector< OpenDDS::DCPS::ReceivedDataElement *, DEF_MAX > BASE
#define OPENDDS_END_VERSIONED_NAMESPACE_DECL
OpenDDS::DCPS::ReceivedDataElement * get_ptr(CORBA::ULong ii) const
#define TAO_END_VERSIONED_NAMESPACE_DECL
The Internal API and Implementation of OpenDDS.
Definition: AddressCache.h:28
Only used by the FooDataReaderImpl and tests.
OpenDDS::DCPS::FirstTimeFastAllocator< OpenDDS::DCPS::ReceivedDataElement *, DEF_MAX > default_allocator_
the default allocator