ZeroCopySeq_T.cpp

Go to the documentation of this file.
00001 /*
00002  *
00003  *
00004  * Distributed under the OpenDDS License.
00005  * See: http://www.opendds.org/license.html
00006  */
00007 
00008 #ifndef ZEROCOPYSEQ_T_CPP
00009 #define ZEROCOPYSEQ_T_CPP
00010 
00011 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00012 # pragma once
00013 #endif /* ACE_LACKS_PRAGMA_ONCE */
00014 
00015 #include "dds/DCPS/ZeroCopySeq_T.h"
00016 
00017 #if !defined (__ACE_INLINE__)
00018 #include "dds/DCPS/ZeroCopySeq_T.inl"
00019 #endif /* __//ACE_INLINE__ */
00020 
00021 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00022 
00023 namespace TAO {
00024 namespace DCPS {
00025 
00026 template <class Sample_T, size_t DEF_MAX>
00027 Sample_T ZeroCopyDataSeq<Sample_T, DEF_MAX>::default_;
00028 
00029 template <class Sample_T, size_t DEF_MAX>
00030 ZeroCopyDataSeq<Sample_T, DEF_MAX>::ZeroCopyDataSeq(
00031   const ZeroCopyDataSeq& frm)
00032   : loaner_(frm.loaner_)
00033   , ptrs_(frm.ptrs_.size(),
00034             (frm.ptrs_.allocator_ ==
00035              static_cast<const ACE_Allocator*>(&frm.default_allocator_))
00036             ? &default_allocator_
00037             : const_cast<ACE_Allocator*>(frm.ptrs_.allocator_))
00038     //The constructor of ptrs_ requires a non-const ptr to ACE_Alloc.
00039   , sc_maximum_(frm.sc_maximum_)
00040   , sc_length_(0) //initialized below
00041   , sc_buffer_(frm.sc_maximum_ ? allocbuf(frm.sc_maximum_) : 0)
00042   , sc_release_(frm.sc_maximum_)
00043 {
00044   if (frm.is_zero_copy()) {
00045     ptrs_ = frm.ptrs_;
00046 
00047     //ptrs_ doesn't manage the ref count for its elements
00048     for (size_t ii = 0; ii < frm.ptrs_.size(); ++ii) {
00049       ptrs_[ii]->inc_ref();
00050       ++ptrs_[ii]->zero_copy_cnt_;
00051     }
00052 
00053   } else {
00054     for (CORBA::ULong i = 0; i < frm.sc_length_; ++i) {
00055       sc_buffer_[i] = frm.sc_buffer_[i];
00056       ++sc_length_;
00057     }
00058   }
00059 }
00060 
00061 #if defined (_MSC_VER)
00062 #pragma warning (disable:4996) //std::copy OK here
00063 #endif
00064 template <class Sample_T, size_t DEF_MAX>
00065 void
00066 ZeroCopyDataSeq<Sample_T, DEF_MAX>::length(CORBA::ULong length)
00067 {
00068   using std::fill;
00069   using std::max;
00070   using std::copy;
00071 
00072   if (length == this->length()) {
00073     return;
00074   }
00075 
00076   if (is_zero_copy()) {
00077     if (length < ptrs_.size()) {
00078       if (!loaner_) {
00079         make_single_copy(length);
00080         this->length(length);
00081         return;
00082       }
00083 
00084       for (size_t i(length); i < ptrs_.size(); ++i) {
00085         --ptrs_[i]->zero_copy_cnt_;
00086         loaner_->dec_ref_data_element(ptrs_[i]);
00087       }
00088 
00089       ptrs_.resize(length, 0);
00090       // At this point, there is no longer a loan
00091       this->set_loaner(0);
00092 
00093     } else {
00094       //There's no way we can expand the size (logical) of the zero-copy
00095       //array and have the user do any meaningful operations on the new
00096       //elements.  The fact that they're pointers to ReceivedDataElement
00097       //is hidden from the user.  Thus we need to make the sequence
00098       //single-copy at this point.
00099       make_single_copy(length);
00100       sc_length_ = length;
00101     }
00102 
00103   } else {
00104     if (length < sc_length_) { //shrink
00105       sc_length_ = length;
00106 
00107     } else if (length <= sc_maximum_) { //grow within buffer
00108       fill(&sc_buffer_[sc_length_], &sc_buffer_[length], Sample_T());
00109       sc_length_ = length;
00110 
00111     } else { //grow to larger buffer
00112       ZeroCopyDataSeq<Sample_T, DEF_MAX> grow(max(length, sc_maximum_*2));
00113       copy(sc_buffer_, &sc_buffer_[sc_length_], grow.sc_buffer_);
00114       fill(&grow.sc_buffer_[sc_length_], &grow.sc_buffer_[length],
00115            Sample_T());
00116       swap(grow);
00117     }
00118   }
00119 }
00120 #if defined (_MSC_VER)
00121 #pragma warning (default:4996)
00122 #endif
00123 
00124 template <class Sample_T, size_t DEF_MAX>
00125 Sample_T*
00126 ZeroCopyDataSeq<Sample_T, DEF_MAX>::get_buffer(
00127   CORBA::Boolean orphan /* = false */)
00128 {
00129   //Case 1: I can't give away what's not mine
00130   //  (includes zero-copy since sc_release_ is always false for zero-copy
00131   if (orphan && !sc_release_) return 0;
00132 
00133   // (preparation for cases 2-3)
00134   if (is_zero_copy()) make_single_copy(max_slots());
00135 
00136   if (!sc_buffer_) {
00137     sc_buffer_ = allocbuf(sc_maximum_);
00138 
00139     if (!orphan) sc_release_ = true;
00140   }
00141 
00142   //Case 2: Keeping the buffer but letting client use it too
00143   if (!orphan) return sc_buffer_;
00144 
00145   //Case 3: Orphaning the buffer to the client, leaves "this" in the
00146   //  default-constructed state (which in our case is ZC-enabled)
00147   ZeroCopyDataSeq<Sample_T, DEF_MAX> yours;
00148   swap(yours);
00149   yours.sc_release_ = false; //don't freebuf in dtor
00150   return yours.sc_buffer_;
00151 }
00152 
00153 #if defined (_MSC_VER)
00154 #pragma warning (default:4996)
00155 #endif
00156 
00157 template <class Sample_T, size_t DEF_MAX>
00158 void
00159 ZeroCopyDataSeq<Sample_T, DEF_MAX>::increment_references(void){
00160   if (is_zero_copy()) {
00161     for (size_t ii = 0; ii < ptrs_.size(); ++ii) {
00162       ptrs_[ii]->inc_ref();
00163     }
00164   }
00165 }
00166 
00167 } // namespace DCPS
00168 } // namespace OpenDDS
00169 
00170 TAO_END_VERSIONED_NAMESPACE_DECL
00171 
00172 #endif /* ZEROCOPYSEQ_H  */

Generated on Fri Feb 12 20:05:29 2016 for OpenDDS by  doxygen 1.4.7