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

Generated on 10 Aug 2018 for OpenDDS by  doxygen 1.6.1