OpenDDS  Snapshot(2023/04/28-20:55)
ZeroCopySeq_T.cpp
Go to the documentation of this file.
1 /*
2  *
3  *
4  * Distributed under the OpenDDS License.
5  * See: http://www.opendds.org/license.html
6  */
7 
8 #ifndef OPENDDS_DCPS_ZEROCOPYSEQ_T_CPP
9 #define OPENDDS_DCPS_ZEROCOPYSEQ_T_CPP
10 
11 #if !defined (ACE_LACKS_PRAGMA_ONCE)
12 # pragma once
13 #endif /* ACE_LACKS_PRAGMA_ONCE */
14 
15 #include "ZeroCopySeq_T.h"
16 
17 #if !defined (__ACE_INLINE__)
18 #include "ZeroCopySeq_T.inl"
19 #endif /* __//ACE_INLINE__ */
20 
22 
23 namespace TAO {
24 namespace DCPS {
25 
26 template <class Sample_T, size_t DEF_MAX>
28 
29 template <class Sample_T, size_t DEF_MAX>
31  const ZeroCopyDataSeq& frm)
32  : loaner_(frm.loaner_)
33  , ptrs_(frm.ptrs_.size(),
34  (frm.ptrs_.allocator_ ==
35  static_cast<const ACE_Allocator*>(&frm.default_allocator_))
36  ? &default_allocator_
37  : const_cast<ACE_Allocator*>(frm.ptrs_.allocator_))
38  //The constructor of ptrs_ requires a non-const ptr to ACE_Alloc.
39  , sc_maximum_(frm.sc_maximum_)
40  , sc_length_(0) //initialized below
41  , sc_buffer_(frm.sc_maximum_ ? allocbuf(frm.sc_maximum_) : 0)
42  , sc_release_(frm.sc_maximum_)
43 {
44  if (frm.is_zero_copy()) {
45  ptrs_ = frm.ptrs_;
46 
47  //ptrs_ doesn't manage the ref count for its elements
48  for (size_t ii = 0; ii < frm.ptrs_.size(); ++ii) {
49  ptrs_[ii]->inc_ref();
50  ++ptrs_[ii]->zero_copy_cnt_;
51  }
52 
53  } else {
54  for (CORBA::ULong i = 0; i < frm.sc_length_; ++i) {
55  sc_buffer_[i] = frm.sc_buffer_[i];
56  ++sc_length_;
57  }
58  }
59 }
60 
61 #if defined (_MSC_VER)
62 #pragma warning (disable:4996) //std::copy OK here
63 #endif
64 template <class Sample_T, size_t DEF_MAX>
65 void
67 {
68  using std::fill;
69  using std::max;
70  using std::copy;
71 
72  if (length == this->length()) {
73  return;
74  }
75 
76  if (is_zero_copy()) {
77  if (length < ptrs_.size()) {
78  if (!loaner_) {
79  make_single_copy(length);
80  this->length(length);
81  return;
82  }
83 
84  for (size_t i(length); i < ptrs_.size(); ++i) {
85  --ptrs_[i]->zero_copy_cnt_;
86  ptrs_[i]->dec_ref();
87  }
88 
89  ptrs_.resize(length, 0);
90  // At this point, there is no longer a loan
91  this->set_loaner(0);
92 
93  } else {
94  //There's no way we can expand the size (logical) of the zero-copy
95  //array and have the user do any meaningful operations on the new
96  //elements. The fact that they're pointers to ReceivedDataElement
97  //is hidden from the user. Thus we need to make the sequence
98  //single-copy at this point.
99  make_single_copy(length);
100  sc_length_ = length;
101  }
102 
103  } else {
104  if (length < sc_length_) { //shrink
105  sc_length_ = length;
106 
107  } else if (length <= sc_maximum_) { //grow within buffer
108  fill(&sc_buffer_[sc_length_], &sc_buffer_[length], Sample_T());
109  sc_length_ = length;
110 
111  } else { //grow to larger buffer
113  grow.sc_length_ = length;
115  fill(&grow.sc_buffer_[sc_length_], &grow.sc_buffer_[length],
116  Sample_T());
117  swap(grow);
118  }
119  }
120 }
121 #if defined (_MSC_VER)
122 #pragma warning (default:4996)
123 #endif
124 
125 template <class Sample_T, size_t DEF_MAX>
126 Sample_T*
128  CORBA::Boolean orphan /* = false */)
129 {
130  //Case 1: I can't give away what's not mine
131  // (includes zero-copy since sc_release_ is always false for zero-copy
132  if (orphan && !sc_release_) return 0;
133 
134  // (preparation for cases 2-3)
136 
137  if (!sc_buffer_) {
139 
140  if (!orphan) sc_release_ = true;
141  }
142 
143  //Case 2: Keeping the buffer but letting client use it too
144  if (!orphan) return sc_buffer_;
145 
146  //Case 3: Orphaning the buffer to the client, leaves "this" in the
147  // default-constructed state (which in our case is ZC-enabled)
149  swap(yours);
150  yours.sc_release_ = false; //don't freebuf in dtor
151  return yours.sc_buffer_;
152 }
153 
154 #if defined (_MSC_VER)
155 #pragma warning (default:4996)
156 #endif
157 
158 template <class Sample_T, size_t DEF_MAX>
160 {
161  if (is_zero_copy()) {
162  for (size_t ii = 0; ii < ptrs_.size(); ++ii) {
163  ptrs_[ii]->inc_ref();
164  }
165  }
166 }
167 
168 } // namespace DCPS
169 } // namespace OpenDDS
170 
172 
173 #endif /* OPENDDS_DCPS_ZEROCOPYSEQ_CPP */
#define TAO_BEGIN_VERSIONED_NAMESPACE_DECL
size_t size(void) const
CORBA::ULong length() const
CORBA::ULong max_slots() const
Ptr_Seq_Type ptrs_
array of pointers if the sequence is supporting zero-copy reads
ACE_CDR::ULong ULong
ACE_CDR::Boolean Boolean
void swap(ZeroCopyDataSeq &frm)
OpenDDS::DCPS::DataReaderImpl * loaner_
The loaner that loaned its samples.
void make_single_copy(CORBA::ULong maximum)
static Sample_T * allocbuf(CORBA::ULong nelems)
Seq::size_type grow(Seq &seq)
Definition: Util.h:151
const Sample_T * get_buffer() const
ZeroCopyDataSeq(CORBA::ULong maximum=0, CORBA::ULong init_size=DEF_MAX, ACE_Allocator *alloc=0)
DDS::ReturnCode_t copy(DDS::DynamicData_ptr dest, DDS::DynamicData_ptr src)
#define TAO_END_VERSIONED_NAMESPACE_DECL
void resize(const size_t new_size, const T &t)
void set_loaner(OpenDDS::DCPS::DataReaderImpl *loaner)