ZeroCopySeq_T.h

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_H
00009 #define ZEROCOPYSEQ_H
00010 
00011 #if !defined (ACE_LACKS_PRAGMA_ONCE)
00012 # pragma once
00013 #endif /* ACE_LACKS_PRAGMA_ONCE */
00014 
00015 #include /**/ "ace/pre.h"
00016 
00017 #include "dds/DCPS/ZeroCopySeqBase.h"
00018 #include "dds/DCPS/ZeroCopyAllocator_T.h"
00019 #include <ace/Vector_T.h>
00020 
00021 namespace OpenDDS {
00022 namespace DCPS {
00023 
00024 class DataReaderImpl;
00025 class ReceivedDataElement;
00026 
00027 } // namespace DCPS
00028 } // namespace OpenDDS
00029 
00030 TAO_BEGIN_VERSIONED_NAMESPACE_DECL
00031 
00032 //This must stay in namespace "TAO" until the tao_idl compiler is changed
00033 namespace TAO {
00034 namespace DCPS {
00035 
00036 /**
00037 * Provides [] operators returning sample references
00038 *     but it is implemented as
00039 *     an "array" of pointers to the samples so they can be
00040 *     "loaned" to the application code.
00041 *
00042 * Design Goals:
00043 *  - Provide enhanced performance known as "zero-copy" in the DDS spec
00044 *  - Conform to the C++ CORBA mapping for sequences
00045 *    - When necessary, certain uncommon sequence operations (resize,
00046 *      get_buffer, replace) will cause copies.  Performance impacts are
00047 *      noted in comments on the individual methods.
00048 */
00049 template <class Sample_T, size_t DEF_MAX = DCPS_ZERO_COPY_SEQ_DEFAULT_SIZE>
00050 class ZeroCopyDataSeq {
00051 public:
00052 
00053   typedef Sample_T value_type;
00054 
00055   /**
00056   * Construct a sequence of sample data values that supports
00057   * zero-copy reads.
00058   *
00059   * @param maximum Maximum number of samples to insert into the sequence.
00060   *                If == 0 then use zero-copy reading.
00061   *                Defaults to zero hence supporting zero-copy reads/takes.
00062   *
00063   * @param init_size Initial size of the underlying array of pointers.
00064   *
00065   * @param alloc The allocator used to allocate the array of pointers
00066   *              to samples. If zero then use the default allocator.
00067   *
00068   * This constructor also serves as the "maximum" ctor and default ctor
00069   * in the CORBA spec.
00070   */
00071   explicit ZeroCopyDataSeq(CORBA::ULong maximum = 0,
00072                            CORBA::ULong init_size = DEF_MAX, ACE_Allocator* alloc = 0);
00073 
00074   ZeroCopyDataSeq(CORBA::ULong maximum, CORBA::ULong length,
00075                   Sample_T* buffer, CORBA::Boolean release = false);
00076 
00077   ZeroCopyDataSeq(const ZeroCopyDataSeq& frm);
00078 
00079   ZeroCopyDataSeq& operator=(const ZeroCopyDataSeq& frm);
00080 
00081   void swap(ZeroCopyDataSeq& frm);
00082 
00083   ~ZeroCopyDataSeq();
00084 
00085   CORBA::ULong maximum() const;
00086 
00087   /** Performance note: increasing the length of a zero-copy sequence past
00088    *  its current length may cause a copy (the sequence will no longer be
00089    *  zero-copy enabled).
00090    */
00091   void length(CORBA::ULong length);
00092   CORBA::ULong length() const;
00093 
00094   const Sample_T& operator[](CORBA::ULong i) const;
00095   Sample_T& operator[](CORBA::ULong i);
00096 
00097   CORBA::Boolean release() const;
00098 
00099   void replace(CORBA::ULong max, CORBA::ULong length, Sample_T* buffer,
00100                CORBA::Boolean release = false);
00101 
00102   Sample_T* get_buffer(CORBA::Boolean orphan = false);
00103   const Sample_T* get_buffer() const;
00104 
00105   static Sample_T* allocbuf(CORBA::ULong nelems);
00106   static void freebuf(Sample_T* buffer);
00107 
00108   void increment_references(void);
00109 
00110   ///Only used by the FooDataReaderImpl and tests
00111   class PrivateMemberAccess {
00112   public:
00113     explicit PrivateMemberAccess(ZeroCopyDataSeq& seq)
00114         : seq_(seq) {}
00115 
00116     CORBA::ULong max_slots() const {
00117       return seq_.max_slots();
00118     }
00119 
00120     void internal_set_length(CORBA::ULong len) {
00121       seq_.internal_set_length(len);
00122     }
00123 
00124     void set_loaner(OpenDDS::DCPS::DataReaderImpl* loaner) {
00125       seq_.set_loaner(loaner);
00126     }
00127 
00128     void assign_ptr(CORBA::ULong ii, OpenDDS::DCPS::ReceivedDataElement* item) {
00129       seq_.assign_ptr(ii, item);
00130     }
00131 
00132     OpenDDS::DCPS::ReceivedDataElement* get_ptr(CORBA::ULong ii) const {
00133       return seq_.get_ptr(ii);
00134     }
00135 
00136     void assign_sample(CORBA::ULong ii, const Sample_T& sample) {
00137       seq_.assign_sample(ii, sample);
00138     }
00139 
00140   private:
00141     ZeroCopyDataSeq& seq_;
00142   };
00143   friend class PrivateMemberAccess;
00144 
00145 private:
00146 
00147   /** In some versions of ACE, ACE_Vector doesn't have a working swap()
00148     * function, so we have to provide our own.
00149     */
00150   class ZeroCopyVector
00151         : public ACE_Vector<OpenDDS::DCPS::ReceivedDataElement*, DEF_MAX> {
00152   public:
00153     ZeroCopyVector(const size_t init_size = DEF_MAX, ACE_Allocator* alloc = 0);
00154 
00155     void swap(ZeroCopyVector&);
00156 
00157     typedef ACE_Vector<OpenDDS::DCPS::ReceivedDataElement*, DEF_MAX> BASE;
00158     using BASE::allocator_;
00159     using BASE::array_;
00160   };
00161 
00162   /**
00163   * Current allocated number of sample slots.
00164   *
00165   * @note The DDS specification's use of maximum=0 to designate
00166   *       zero-copy read request requires some
00167   *       way of knowing the internally allocated slots
00168   *       for sample pointers that is not "maximum".
00169   */
00170   CORBA::ULong max_slots() const;
00171 
00172   void internal_set_length(CORBA::ULong len);
00173 
00174   void set_loaner(OpenDDS::DCPS::DataReaderImpl* loaner);
00175 
00176   void assign_ptr(CORBA::ULong ii, OpenDDS::DCPS::ReceivedDataElement* item);
00177 
00178   OpenDDS::DCPS::ReceivedDataElement* get_ptr(CORBA::ULong ii) const;
00179 
00180   void assign_sample(CORBA::ULong ii, const Sample_T& sample);
00181 
00182   bool is_zero_copy() const;
00183 
00184   void make_single_copy(CORBA::ULong maximum);
00185 
00186   /// The datareader that loaned its samples.
00187   OpenDDS::DCPS::DataReaderImpl* loaner_;
00188 
00189   /// the default allocator
00190   OpenDDS::DCPS::FirstTimeFastAllocator<OpenDDS::DCPS::ReceivedDataElement*, DEF_MAX>
00191   default_allocator_;
00192 
00193   typedef ZeroCopyVector Ptr_Seq_Type;
00194 
00195   /// array of pointers if the sequence is supporting zero-copy reads
00196   Ptr_Seq_Type ptrs_;
00197   static Sample_T default_;
00198 
00199   //single-copy (aka non-zero-copy) support
00200   CORBA::ULong sc_maximum_;
00201   CORBA::ULong sc_length_;
00202   mutable Sample_T* sc_buffer_;
00203   mutable CORBA::Boolean sc_release_;
00204 
00205 }; // class ZeroCopyDataSeq
00206 
00207 } // namespace DCPS
00208 } // namespace TAO
00209 
00210 TAO_END_VERSIONED_NAMESPACE_DECL
00211 
00212 #if defined (__ACE_INLINE__)
00213 #include "dds/DCPS/ZeroCopySeq_T.inl"
00214 #endif /* __ACE_INLINE__ */
00215 
00216 #if defined (ACE_TEMPLATES_REQUIRE_SOURCE)
00217 #include "dds/DCPS/ZeroCopySeq_T.cpp"
00218 #endif /* ACE_TEMPLATES_REQUIRE_SOURCE */
00219 
00220 #if defined (ACE_TEMPLATES_REQUIRE_PRAGMA)
00221 #pragma message ("ZeroCopySeq_T.cpp template inst")
00222 #pragma implementation ("ZeroCopySeq_T.cpp")
00223 #endif /* ACE_TEMPLATES_REQUIRE_PRAGMA */
00224 
00225 #include /**/ "ace/post.h"
00226 
00227 #endif /* ZEROCOPYSEQ_H  */

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