$treeview $search $mathjax $extrastylesheet
artdaq
v3_04_00
$projectbrief
|
$projectbrief
|
$searchbox |
00001 #define TRACE_NAME "RTIDDS" 00002 00003 #include "artdaq/RTIDDS/RTIDDS.hh" 00004 #include "artdaq/DAQdata/Globals.hh" 00005 00006 #include <boost/tokenizer.hpp> 00007 00008 #include <iostream> 00009 00010 00011 artdaq::RTIDDS::RTIDDS(std::string name, IOType iotype, std::string max_size) : 00012 name_(name) 00013 , iotype_(iotype) 00014 , max_size_(max_size) 00015 { 00016 DDS_ReturnCode_t retcode = DDS_RETCODE_ERROR; 00017 DDS_DomainParticipantQos participant_qos; 00018 00019 retcode = DDSDomainParticipantFactory::get_instance()->get_default_participant_qos(participant_qos); 00020 00021 if (retcode != DDS_RETCODE_OK) 00022 { 00023 TLOG(TLVL_WARNING) << name_ << ": Problem obtaining default participant QoS, retcode was " << retcode ; 00024 } 00025 00026 retcode = DDSPropertyQosPolicyHelper::add_property( 00027 participant_qos.property, "dds.builtin_type.octets.max_size", 00028 max_size_.c_str(), 00029 DDS_BOOLEAN_FALSE); 00030 00031 if (retcode != DDS_RETCODE_OK) 00032 { 00033 TLOG(TLVL_WARNING) << name_ << ": Problem setting dds.builtin_type.octets.max_size, retcode was " << retcode ; 00034 } 00035 00036 participant_.reset(DDSDomainParticipantFactory::get_instance()-> 00037 create_participant( 00038 0, // Domain ID 00039 participant_qos, 00040 nullptr, // Listener 00041 DDS_STATUS_MASK_NONE) 00042 ); 00043 00044 topic_octets_ = participant_->create_topic( 00045 "artdaq fragments", // Topic name 00046 DDSOctetsTypeSupport::get_type_name(), // Type name 00047 DDS_TOPIC_QOS_DEFAULT, // Topic QoS 00048 nullptr, // Listener 00049 DDS_STATUS_MASK_NONE); 00050 00051 if (participant_ == nullptr || topic_octets_ == nullptr) 00052 { 00053 TLOG(TLVL_WARNING) << name_ << ": Problem setting up the RTI-DDS participant and/or topic" ; 00054 } 00055 00056 // JCF, 9/16/15 00057 00058 // Following effort to increase the max DDS buffer size from its 00059 // default of 2048 bytes is cribbed from section 3.2.7 of the Core 00060 // Utilities user manual, "Managing Memory for Built-in Types" 00061 00062 00063 DDS_DataWriterQos writer_qos; 00064 00065 retcode = participant_->get_default_datawriter_qos(writer_qos); 00066 00067 if (retcode != DDS_RETCODE_OK) 00068 { 00069 TLOG(TLVL_WARNING) << name_ << ": Problem obtaining default datawriter QoS, retcode was " << retcode ; 00070 } 00071 00072 retcode = DDSPropertyQosPolicyHelper::add_property( 00073 writer_qos.property, "dds.builtin_type.octets.alloc_size", 00074 max_size_.c_str(), 00075 DDS_BOOLEAN_FALSE); 00076 00077 if (retcode != DDS_RETCODE_OK) 00078 { 00079 TLOG(TLVL_WARNING) << name_ << ": Problem setting dds.builtin_type.octets.alloc_size, retcode was " << retcode ; 00080 } 00081 00082 00083 if (iotype_ == IOType::writer) 00084 { 00085 octets_writer_ = DDSOctetsDataWriter::narrow(participant_->create_datawriter( 00086 topic_octets_, 00087 writer_qos, 00088 nullptr, // Listener 00089 DDS_STATUS_MASK_NONE) 00090 ); 00091 00092 if (octets_writer_ == nullptr) 00093 { 00094 TLOG(TLVL_WARNING) << name_ << ": Problem setting up the RTI-DDS writer objects" ; 00095 } 00096 } 00097 else 00098 { 00099 octets_reader_ = participant_->create_datareader( 00100 topic_octets_, 00101 DDS_DATAREADER_QOS_DEFAULT, // QoS 00102 &octets_listener_, // Listener 00103 DDS_DATA_AVAILABLE_STATUS); 00104 00105 if (octets_reader_ == nullptr) 00106 { 00107 TLOG(TLVL_WARNING) << name_ << ": Problem setting up the RTI-DDS reader objects" ; 00108 } 00109 } 00110 } 00111 00112 void artdaq::RTIDDS::transfer_fragment_reliable_mode_via_DDS_(artdaq::Fragment&& fragment) { transfer_fragment_min_blocking_mode_via_DDS_(fragment); } 00113 00114 void artdaq::RTIDDS::transfer_fragment_min_blocking_mode_via_DDS_(artdaq::Fragment const& fragment) 00115 { 00116 // check if a fragment of this type has already been copied 00117 size_t fragmentType = fragment.type(); 00118 00119 if (octets_writer_ == NULL) { return; } 00120 00121 // JCF, 9/15/15 00122 00123 // Perform the same checks Kurt implemented in the AggregatorCore's 00124 // copyFragmentToSharedMemory_() function 00125 00126 size_t max_fragment_size = boost::lexical_cast<size_t>(max_size_) - 00127 detail::RawFragmentHeader::num_words() * sizeof(RawDataType); 00128 00129 if (fragment.type() != artdaq::Fragment::InvalidFragmentType && 00130 fragment.sizeBytes() < max_fragment_size) 00131 { 00132 if (fragment.type() == artdaq::Fragment::InitFragmentType) 00133 { 00134 usleep(500000); 00135 } 00136 00137 DDS_ReturnCode_t retcode = octets_writer_->write(reinterpret_cast<unsigned char*>(fragment.headerBeginBytes()), 00138 fragment.sizeBytes(), 00139 DDS_HANDLE_NIL); 00140 00141 if (retcode != DDS_RETCODE_OK) 00142 { 00143 TLOG(TLVL_WARNING) << name_ << ": Problem writing octets (bytes), retcode was " << retcode ; 00144 00145 TLOG(TLVL_WARNING) << name_ << ": Fragment failed for DDS! " 00146 << "fragment address and size = " 00147 << static_cast<void*>(fragment.headerBeginBytes()) << " " << static_cast<int>(fragment.sizeBytes()) << " " 00148 << "sequence ID, fragment ID, and type = " 00149 << fragment.sequenceID() << " " 00150 << fragment.fragmentID() << " " 00151 << ((int) fragment.type()) ; 00152 } 00153 } 00154 else 00155 { 00156 TLOG(TLVL_WARNING) << name_ << ": Fragment invalid for DDS! " 00157 << "fragment address and size = " 00158 << static_cast<void*>(fragment.headerBeginBytes()) << " " << static_cast<int>(fragment.sizeBytes()) << " " 00159 << "sequence ID, fragment ID, and type = " 00160 << fragment.sequenceID() << " " 00161 << fragment.fragmentID() << " " 00162 << ((int) fragment.type()) ; 00163 } 00164 } 00165 00166 void artdaq::RTIDDS::OctetsListener::on_data_available(DDSDataReader* reader) 00167 { 00168 DDSOctetsDataReader* octets_reader = NULL; 00169 DDS_SampleInfo info; 00170 DDS_ReturnCode_t retcode; 00171 00172 TLOG(TLVL_DEBUG) << name_ << ": In OctetsListener::on_data_available" ; 00173 00174 00175 octets_reader = DDSOctetsDataReader::narrow(reader); 00176 if (octets_reader == nullptr) 00177 { 00178 TLOG(TLVL_ERROR) << name_ << ": Error: Very unexpected - DDSOctetsDataReader::narrow failed" ; 00179 return; 00180 } 00181 00182 // Loop until there are messages available in the queue 00183 00184 00185 for (;;) 00186 { 00187 retcode = octets_reader->take_next_sample( 00188 dds_octets_, 00189 info); 00190 if (retcode == DDS_RETCODE_NO_DATA) 00191 { 00192 // No more samples 00193 break; 00194 } 00195 else if (retcode != DDS_RETCODE_OK) 00196 { 00197 TLOG(TLVL_WARNING) << "Unable to take data from data reader, error " 00198 << retcode ; 00199 return; 00200 } 00201 if (info.valid_data) 00202 { 00203 // JCF, 9/17/15 00204 00205 // We want to make sure the dds_octets_ doesn't get popped from 00206 // by receiveFragmentFromDDS before we display its contents 00207 00208 std::lock_guard<std::mutex> lock(queue_mutex_); 00209 00210 dds_octets_queue_.push(dds_octets_); 00211 } 00212 } 00213 } 00214 00215 // receiveFragmentFromDDS returns true (and fills fragment passed to 00216 // it) in there's no timeout; if there is, returns false 00217 00218 bool artdaq::RTIDDS::OctetsListener::receiveFragmentFromDDS(artdaq::Fragment& fragment, 00219 const size_t receiveTimeout) 00220 { 00221 int loopCount = 0; 00222 size_t sleepTime = 1000; // microseconds 00223 size_t nloops = receiveTimeout / sleepTime; 00224 00225 while (dds_octets_queue_.empty() && loopCount < nloops) 00226 { 00227 usleep(sleepTime); 00228 ++loopCount; 00229 } 00230 00231 // JCF, 9/17/15 00232 00233 // Make sure the on_data_available() callback function doesn't 00234 // modify dds_octets_queue_ while this section is running 00235 00236 std::lock_guard<std::mutex> lock(queue_mutex_); 00237 00238 if (!dds_octets_queue_.empty()) 00239 { 00240 fragment.resizeBytes(dds_octets_queue_.front().length); 00241 memcpy(fragment.headerAddress(), dds_octets_queue_.front().value, dds_octets_queue_.front().length); 00242 00243 dds_octets_queue_.pop(); 00244 00245 TLOG(TLVL_DEBUG) << name_ 00246 << ": Received fragment from DDS, type =" 00247 << ((int)fragment.type()) << ", sequenceID = " 00248 << fragment.sequenceID() << ", size in bytes = " 00249 << fragment.sizeBytes() 00250 ; 00251 00252 return true; 00253 } 00254 00255 return false; 00256 }