00001 // $Id: InitMsgData.cc,v 1.9 2012/04/20 10:48:02 mommsen Exp $ 00003 00004 #include "EventFilter/StorageManager/src/ChainData.h" 00005 00006 #include "IOPool/Streamer/interface/InitMessage.h" 00007 00008 namespace stor 00009 { 00010 00011 namespace detail 00012 { 00013 00014 InitMsgData::InitMsgData(toolbox::mem::Reference* pRef) : 00015 ChainData(I2O_SM_PREAMBLE, Header::INIT), 00016 headerFieldsCached_(false) 00017 { 00018 addFirstFragment(pRef); 00019 parseI2OHeader(); 00020 } 00021 00022 inline size_t InitMsgData::do_i2oFrameSize() const 00023 { 00024 return sizeof(I2O_SM_PREAMBLE_MESSAGE_FRAME); 00025 } 00026 00027 unsigned long InitMsgData::do_headerSize() const 00028 { 00029 if ( !headerOkay() ) 00030 { 00031 return 0; 00032 } 00033 00034 if (! headerFieldsCached_) {cacheHeaderFields();} 00035 return headerSize_; 00036 } 00037 00038 unsigned char* InitMsgData::do_headerLocation() const 00039 { 00040 if ( !headerOkay() ) 00041 { 00042 return 0; 00043 } 00044 00045 if (! headerFieldsCached_) {cacheHeaderFields();} 00046 return headerLocation_; 00047 } 00048 00049 inline unsigned char* 00050 InitMsgData::do_fragmentLocation(unsigned char* dataLoc) const 00051 { 00052 if ( parsable() ) 00053 { 00054 I2O_SM_PREAMBLE_MESSAGE_FRAME *smMsg = 00055 (I2O_SM_PREAMBLE_MESSAGE_FRAME*) dataLoc; 00056 return (unsigned char*) smMsg->dataPtr(); 00057 } 00058 else 00059 { 00060 return dataLoc; 00061 } 00062 } 00063 00064 uint32_t InitMsgData::do_adler32Checksum() const 00065 { 00066 if ( !headerOkay() ) 00067 { 00068 std::stringstream msg; 00069 msg << "An adler32 checksum can not be determined from a "; 00070 msg << "faulty or incomplete INIT message."; 00071 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00072 } 00073 00074 if (! headerFieldsCached_) {cacheHeaderFields();} 00075 return adler32_; 00076 } 00077 00078 std::string InitMsgData::do_outputModuleLabel() const 00079 { 00080 if ( !headerOkay() ) 00081 { 00082 std::stringstream msg; 00083 msg << "An output module label can not be determined from a "; 00084 msg << "faulty or incomplete INIT message."; 00085 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00086 } 00087 00088 if (! headerFieldsCached_) {cacheHeaderFields();} 00089 return outputModuleLabel_; 00090 } 00091 00092 uint32_t InitMsgData::do_outputModuleId() const 00093 { 00094 if ( !headerOkay() ) 00095 { 00096 std::stringstream msg; 00097 msg << "An output module ID can not be determined from a "; 00098 msg << "faulty or incomplete INIT message."; 00099 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00100 } 00101 00102 if (! headerFieldsCached_) {cacheHeaderFields();} 00103 return outputModuleId_; 00104 } 00105 00106 void InitMsgData::do_hltTriggerNames(Strings& nameList) const 00107 { 00108 if ( !headerOkay() ) 00109 { 00110 std::stringstream msg; 00111 msg << "The HLT trigger names can not be determined from a "; 00112 msg << "faulty or incomplete INIT message."; 00113 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00114 } 00115 00116 if (! headerFieldsCached_) {cacheHeaderFields();} 00117 nameList = hltTriggerNames_; 00118 } 00119 00120 void InitMsgData::do_hltTriggerSelections(Strings& nameList) const 00121 { 00122 if ( !headerOkay() ) 00123 { 00124 std::stringstream msg; 00125 msg << "The HLT trigger selections can not be determined from a "; 00126 msg << "faulty or incomplete INIT message."; 00127 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00128 } 00129 00130 if (! headerFieldsCached_) {cacheHeaderFields();} 00131 nameList = hltTriggerSelections_; 00132 } 00133 00134 void InitMsgData::do_l1TriggerNames(Strings& nameList) const 00135 { 00136 if ( !headerOkay() ) 00137 { 00138 std::stringstream msg; 00139 msg << "The L1 trigger names can not be determined from a "; 00140 msg << "faulty or incomplete INIT message."; 00141 XCEPT_RAISE(stor::exception::IncompleteInitMessage, msg.str()); 00142 } 00143 00144 if (! headerFieldsCached_) {cacheHeaderFields();} 00145 nameList = l1TriggerNames_; 00146 } 00147 00148 inline void InitMsgData::parseI2OHeader() 00149 { 00150 if ( parsable() ) 00151 { 00152 I2O_SM_PREAMBLE_MESSAGE_FRAME *smMsg = 00153 (I2O_SM_PREAMBLE_MESSAGE_FRAME*) ref_->getDataLocation(); 00154 fragKey_.code_ = messageCode_; 00155 fragKey_.run_ = 0; 00156 fragKey_.event_ = smMsg->hltTid; 00157 fragKey_.secondaryId_ = smMsg->outModID; 00158 fragKey_.originatorPid_ = smMsg->fuProcID; 00159 fragKey_.originatorGuid_ = smMsg->fuGUID; 00160 rbBufferId_ = smMsg->rbBufferID; 00161 hltLocalId_ = smMsg->hltLocalId; 00162 hltInstance_ = smMsg->hltInstance; 00163 hltTid_ = smMsg->hltTid; 00164 fuProcessId_ = smMsg->fuProcID; 00165 fuGuid_ = smMsg->fuGUID; 00166 nExpectedEPs_ = smMsg->nExpectedEPs; 00167 } 00168 } 00169 00170 void InitMsgData::cacheHeaderFields() const 00171 { 00172 unsigned char* firstFragLoc = dataLocation(0); 00173 unsigned long firstFragSize = dataSize(0); 00174 bool useFirstFrag = false; 00175 00176 // if there is only one fragment, use it 00177 if (fragmentCount_ == 1) 00178 { 00179 useFirstFrag = true; 00180 } 00181 // otherwise, check if the first fragment is large enough to hold 00182 // the full INIT message header (we require some minimal fixed 00183 // size in the hope that we don't parse garbage when we overlay 00184 // the InitMsgView on the buffer) 00185 else if (firstFragSize > (sizeof(InitHeader) + 16384)) 00186 { 00187 InitMsgView view(firstFragLoc); 00188 if (view.headerSize() <= firstFragSize) 00189 { 00190 useFirstFrag = true; 00191 } 00192 } 00193 00194 boost::shared_ptr<InitMsgView> msgView; 00195 if (useFirstFrag) 00196 { 00197 msgView.reset(new InitMsgView(firstFragLoc)); 00198 } 00199 else 00200 { 00201 copyFragmentsIntoBuffer(headerCopy_); 00202 msgView.reset(new InitMsgView(&headerCopy_[0])); 00203 } 00204 00205 headerSize_ = msgView->headerSize(); 00206 headerLocation_ = msgView->startAddress(); 00207 adler32_ = msgView->adler32_chksum(); 00208 outputModuleLabel_ = msgView->outputModuleLabel(); 00209 outputModuleId_ = msgView->outputModuleId(); 00210 msgView->hltTriggerNames(hltTriggerNames_); 00211 msgView->hltTriggerSelections(hltTriggerSelections_); 00212 msgView->l1TriggerNames(l1TriggerNames_); 00213 00214 headerFieldsCached_ = true; 00215 00216 #ifdef STOR_DEBUG_WRONG_ADLER 00217 double r = rand()/static_cast<double>(RAND_MAX); 00218 if (r < 0.01) 00219 { 00220 std::cout << "Simulating corrupt Adler calculation" << std::endl; 00221 headerSize_ += 3; 00222 } 00223 else if (r < 0.02) 00224 { 00225 std::cout << "Simulating corrupt Adler entry" << std::endl; 00226 adler32_ += r*10000; 00227 } 00228 #endif // STOR_DEBUG_WRONG_ADLER 00229 } 00230 00231 } // namespace detail 00232 00233 } // namespace stor 00234 00235