CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/IORawData/DaqSource/plugins/DaqSource.cc

Go to the documentation of this file.
00001 
00008 #include "DaqSource.h"
00009 
00010 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00011 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00012 #include "EventFilter/FEDInterface/interface/GlobalEventNumber.h"
00013 
00014 #include "IORawData/DaqSource/interface/DaqBaseReader.h"
00015 #include "IORawData/DaqSource/interface/DaqReaderPluginFactory.h"
00016 
00017 #include "DataFormats/Provenance/interface/Timestamp.h" 
00018 #include "FWCore/Framework/interface/LuminosityBlockPrincipal.h"
00019 #include "FWCore/Framework/interface/EventPrincipal.h"
00020 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00021 #include "DataFormats/Provenance/interface/EventAuxiliary.h"
00022 #include "DataFormats/Provenance/interface/LuminosityBlockAuxiliary.h"
00023 #include "DataFormats/Provenance/interface/RunAuxiliary.h"
00024 #include "DataFormats/Provenance/interface/EventID.h"
00025 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00026 
00027 #include <string>
00028 #include <iostream>
00029 #include <time.h>
00030 #include <sys/time.h>
00031 #include <sys/types.h>
00032 
00033 #include "xgi/Method.h"
00034 #include "xgi/Utils.h"
00035 
00036 #include "cgicc/Cgicc.h"
00037 #include "cgicc/FormEntry.h"
00038 #include "cgicc/HTMLClasses.h"
00039 
00040 #include "boost/tokenizer.hpp"
00041 
00042 
00044 // construction/destruction
00046 
00047 
00048 
00049 namespace edm {
00050  namespace daqsource{
00051   static unsigned int gtpEvmId_ =  FEDNumbering::MINTriggerGTPFEDID;
00052   static unsigned int gtpeId_ =  FEDNumbering::MINTriggerEGTPFEDID;
00053  }
00054 
00055   //______________________________________________________________________________
00056   DaqSource::DaqSource(const ParameterSet& pset, 
00057                      const InputSourceDescription& desc) 
00058     : InputSource(pset,desc)
00059     , evf::ModuleWeb("DaqSource")
00060     , reader_(0)
00061     , lumiSegmentSizeInEvents_(pset.getUntrackedParameter<unsigned int>("evtsPerLS",0))
00062     , useEventCounter_(pset.getUntrackedParameter<bool>("useEventCounter",false))
00063     , eventCounter_(0)
00064     , keepUsingPsidFromTrigger_(pset.getUntrackedParameter<bool>("keepUsingPsidFromTrigger",false))
00065     , fakeLSid_(lumiSegmentSizeInEvents_ != 0)
00066     , runNumber_(RunID::firstValidRun().run())
00067     , luminosityBlockNumber_(LuminosityBlockID::firstValidLuminosityBlock().luminosityBlock())
00068     , daqProvenanceHelper_(TypeID(typeid(FEDRawDataCollection)))
00069     , noMoreEvents_(false)
00070     , newRun_(true)
00071     , newLumi_(true)
00072     , eventCached_(false)
00073     , alignLsToLast_(false)
00074     , is_(0)
00075     , mis_(0)
00076     , thisEventLSid(0)
00077     , goToStopping(false)
00078     , immediateStop(false)
00079     , forkInfo_(nullptr)
00080     , runFork_(false)
00081     , beginRunTiming_(false)
00082   {
00083     count = 0;
00084     pthread_mutex_init(&mutex_,0);
00085     pthread_mutex_init(&signal_lock_,0);
00086     pthread_cond_init(&cond_,0);
00087 
00088 
00089     setTimestamp(Timestamp::beginOfTime());
00090     
00091     // Instantiate the requested data source
00092     std::string reader = pset.getUntrackedParameter<std::string>("readerPluginName");
00093     
00094     try{
00095       reader_=
00096         DaqReaderPluginFactory::get()->create(reader,
00097                                             pset.getUntrackedParameter<ParameterSet>("readerPset"));
00098       reader_->setRunNumber(runNumber_);
00099     }
00100     catch(edm::Exception &e) {
00101       if(e.category() == "Configuration" && reader_ == 0) {
00102         reader_ = DaqReaderPluginFactoryU::get()->create(reader);
00103         if(reader_ == 0) throw;
00104         else reader_->setRunNumber(runNumber_);
00105       }
00106       else {
00107         throw;
00108       }
00109     }
00110 
00111    // Initialize metadata, and save the process history ID for use every event.
00112    phid_ = daqProvenanceHelper_.daqInit(productRegistryUpdate());
00113 
00114   }
00115   
00116   //______________________________________________________________________________
00117   DaqSource::~DaqSource() {
00118     delete reader_;
00119   }
00120   
00121   void DaqSource::publishForkInfo(evf::moduleweb::ForkInfoObj * forkInfoObj) {
00122     forkInfo_ = forkInfoObj;
00123     runFork_=true;
00124     immediateStop=false;
00125     noMoreEvents_=false;
00126   }
00127   
00129   // implementation of member functions
00131 
00132 
00133   //______________________________________________________________________________
00134   int DaqSource::doMyBeginRun() {
00135 
00136     if (forkInfo_) {
00137       while (!immediateStop) {
00138         //queue new run to Framework (causes EP beginRun to be executed)
00139         if (newRun_) {
00140           beginRunTiming_=true;
00141           gettimeofday(&tvStat_, NULL);
00142           return 2;
00143         }
00144         //measure time in fwk beginRun
00145         if (beginRunTiming_) {
00146           timeval tsTmp;
00147           gettimeofday(&tsTmp,NULL);
00148           long tusecs = (tsTmp.tv_sec-tvStat_.tv_sec)*1000000 + tsTmp.tv_usec - tvStat_.tv_usec;
00149           double tsecs = ((double)(tusecs/10000))/100.;
00150           std::cout << "DaqSource: FWK beginRun elapsed time: " << tsecs << " seconds in master EP"<< std::endl;
00151           edm::LogInfo("DaqSource") << "FWK beginRun elapsed time: " << tsecs << " seconds in master EP";
00152           beginRunTiming_=false;
00153           usleep(10000);//short sleep before fork
00154         }
00155         //first or new run init
00156         if (forkInfo_->forkParams.isMaster==-1) {
00157           forkInfo_->lock();//keeping it locked during init!
00158           forkInfo_->forkHandler(forkInfo_->fuAddr); //fork all slaves
00159         }
00160         if (forkInfo_->forkParams.isMaster==-1) {
00161           forkInfo_->unlock();
00162           std::cout << "ERROR (DaqSource): not notified to be either in  master or slave process after fork" << std::endl;
00163           return -2;
00164         }
00165 
00166         //slave process after fork: exit all this
00167         if (forkInfo_->forkParams.isMaster==0) {
00168           forkInfo_->unlock();
00169           return 1;
00170         }
00171 
00172         //master process after fork:
00173         if (forkInfo_->forkParams.isMaster==1) {
00174             forkInfo_->unlock();
00175             int slotToRestart=-1;
00176             sem_wait(forkInfo_->control_sem_);
00177             forkInfo_->lock();
00178 
00179             //got unblocked due to next run
00180             if (forkInfo_->forkParams.isMaster==-1) {
00181                     forkInfo_->unlock();
00182                     continue; // check here for newRun_?
00183             }
00184             //check if asked to stop
00185             immediateStop=forkInfo_->stopCondition;
00186             if (immediateStop) {
00187               break;
00188             }
00189             
00190             //check if asked to restart
00191             slotToRestart = forkInfo_->forkParams.slotId;
00192 
00193           if (slotToRestart==-1 && forkInfo_->forkParams.restart==0) {
00194             //this will deal with spurious semaphore signals when slave is killed
00195             forkInfo_->unlock();
00196             continue;
00197           }
00198           //restart single slave
00199           forkInfo_->forkHandler(forkInfo_->fuAddr);
00200         }
00201       }
00202       //loop exit
00203       forkInfo_->unlock();
00204       return 0;
00205     }
00206     return -1; //no forkInfo_
00207   }
00208 
00209 
00210   //______________________________________________________________________________
00211   InputSource::ItemType 
00212   DaqSource::getNextItemType() {
00213     //    std::cout << getpid() << " enter getNextItemType " << std::endl;
00214     if (runFork_) {
00215       runFork_=false;
00216       int queueNext = doMyBeginRun();
00217       //check if new run (requires returning IsRun once)
00218       if (queueNext == 2) runFork_=true;
00219     }
00220 
00221     //get initial time before beginRun (used with old forking)
00222     if (!forkInfo_ && newRun_) {
00223       beginRunTiming_=true;
00224       gettimeofday(&tvStat_, NULL);
00225     }
00226 
00227     if (immediateStop) return IsStop;
00228 
00229     // --------------
00230     if(goToStopping){noMoreEvents_ = true; goToStopping=false;}
00231     if (noMoreEvents_) {
00232       pthread_mutex_lock(&mutex_);
00233       pthread_cond_signal(&cond_);
00234       pthread_mutex_unlock(&mutex_);
00235       return IsStop;
00236     }
00237     if (newRun_) {
00238       return IsRun;
00239     }
00240 
00241     //calculate and print the beginRun the timing
00242     if (beginRunTiming_) {
00243       timeval tsTmp;
00244       gettimeofday(&tsTmp,NULL);
00245       long tusecs = (tsTmp.tv_sec-tvStat_.tv_sec)*1000000 + tsTmp.tv_usec - tvStat_.tv_usec;
00246       double tsecs = ((double)(tusecs/10000))/100.;
00247       std::cout << "DaqSource (slave pid "<< getpid() << " ): FWK beginRun elapsed time: " 
00248                 << tsecs << " seconds "<< std::endl;
00249       edm::LogInfo("DaqSource") << "DaqSource (slave pid "<< getpid() << " ): FWK beginRun elapsed time: " 
00250                 << tsecs << " seconds ";
00251       beginRunTiming_=false;
00252     }
00253 
00254     if (newLumi_ && luminosityBlockAuxiliary()) {
00255       //      std::cout << "newLumi & lumiblock valid " << std::endl;
00256       return IsLumi;
00257     }
00258     if (alignLsToLast_) { //here we are recovering from a gap in Ls number so an event may already be cached but 
00259       // we hold onto it until we have issued all the necessary endLumi/beginLumi
00260       //       std::cout << getpid() << "alignLsToLast was set and ls number is " 
00261       //                << luminosityBlockNumber_ << " before signaling" << std::endl;
00262       signalWaitingThreadAndBlock();
00263       luminosityBlockNumber_++;
00264       //       std::cout << getpid() << "alignLsToLast signaled and incremented " 
00265       //                << luminosityBlockNumber_ << " eventcached " 
00266       //                << eventCached_ << std::endl;
00267       newLumi_ = true;
00268       lumiSectionIndex_->value_ = luminosityBlockNumber_;
00269       resetLuminosityBlockAuxiliary();
00270       if(luminosityBlockNumber_ == thisEventLSid+1) 
00271       {
00272         alignLsToLast_ = false;
00273       }
00274       if (!luminosityBlockAuxiliary() || luminosityBlockAuxiliary()->luminosityBlock() != luminosityBlockNumber_) {
00275         setLuminosityBlockAuxiliary(new LuminosityBlockAuxiliary(
00276               runNumber_, luminosityBlockNumber_, timestamp(), Timestamp::invalidTimestamp()));
00277         luminosityBlockAuxiliary()->setProcessHistoryID(phid_);
00278 
00279         //      std::cout << "nextItemType: dealt with new lumi block principal, retval is " << retval << std::endl;
00280       }
00281       return IsLumi;
00282     }
00283     if (eventCached_) {
00284       //      std::cout << "read event already cached " << std::endl;
00285       return IsEvent;
00286     }
00287     if(reader_ == 0) {
00288       throw edm::Exception(errors::LogicError)
00289           << "DaqSource is used without a reader. Check your configuration !";
00290     }
00291     EventID eventId;
00292     TimeValue_t time = 0LL;
00293     timeval stv;
00294     gettimeofday(&stv,0);
00295     time = stv.tv_sec;
00296     time = (time << 32) + stv.tv_usec;
00297     Timestamp tstamp(time);
00298 
00299     int bunchCrossing = EventAuxiliary::invalidBunchXing;
00300     int orbitNumber   = EventAuxiliary::invalidBunchXing;
00301     
00302     // pass a 0 pointer to fillRawData()!
00303     FEDRawDataCollection* fedCollection(0);
00304 
00305     edm::EventAuxiliary::ExperimentType evttype = EventAuxiliary::Undefined;
00306   
00307     // let reader_ fill the fedCollection 
00308     int retval = reader_->fillRawData(eventId, tstamp, fedCollection);
00309     if(retval==0) {
00310       // fillRawData() failed, clean up the fedCollection in case it was allocated!
00311       if (0 != fedCollection) delete fedCollection;
00312       noMoreEvents_ = true;
00313       pthread_mutex_lock(&mutex_);
00314       pthread_cond_signal(&cond_);
00315       pthread_mutex_unlock(&mutex_);
00316       return IsStop;
00317     }
00318     else if(retval<0)
00319       {
00320  
00321         unsigned int nextLsFromSignal = (-1)*retval+1;
00322 //      std::cout << getpid() << "::got end-of-lumi for " << (-1)*retval
00323 //                << " was " << luminosityBlockNumber_ << std::endl;
00324         if(luminosityBlockNumber_ == (nextLsFromSignal-1) )
00325           {
00326             lastLumiUsingEol_->value_ = nextLsFromSignal;
00327             if(lsToBeRecovered_->value_){
00328 //            std::cout << getpid() << "eol::recover ls::for " << (-1)*retval << std::endl;
00329               signalWaitingThreadAndBlock();
00330               luminosityBlockNumber_++;
00331               newLumi_ = true;
00332               lumiSectionIndex_->value_ = luminosityBlockNumber_;
00333               resetLuminosityBlockAuxiliary();
00334               thisEventLSid = nextLsFromSignal - 1;
00335               if(luminosityBlockNumber_ != thisEventLSid+1) 
00336                 alignLsToLast_ = true;
00337               //              std::cout << getpid() << "eol::::alignLsToLast_ " << alignLsToLast_ << std::endl;
00338             }
00339             else{
00340               //              std::cout << getpid() << "eol::realign ls::for " << (-1)*retval << std::endl;
00341               luminosityBlockNumber_ = nextLsFromSignal;
00342               newLumi_ = true;
00343               lumiSectionIndex_->value_ = luminosityBlockNumber_;
00344               resetLuminosityBlockAuxiliary();
00345             }
00346           }
00347         else if(nextLsFromSignal >(luminosityBlockNumber_+100) ) {
00348           edm::LogError("DaqSource") << "Got EOL event with value " << retval 
00349                                      << " nextLS would be " << nextLsFromSignal 
00350                                      << " while we expected " << luminosityBlockNumber_+1 << " - disregarding... "; 
00351         }
00352         //      else
00353         //        std::cout << getpid() << "::skipping end-of-lumi for " << (-1)*retval << std::endl;
00354       }
00355     else
00356       {
00357         if (eventId.event() == 0) {
00358           throw edm::Exception(errors::LogicError)
00359             << "The reader used with DaqSource has returned an invalid (zero) event number!\n"
00360             << "Event numbers must begin at 1, not 0.";
00361         }
00362         EventSourceSentry(*this);
00363         setTimestamp(tstamp);
00364     
00365         unsigned char *gtpFedAddr = fedCollection->FEDData(daqsource::gtpEvmId_).size()!=0 ? fedCollection->FEDData(daqsource::gtpEvmId_).data() : 0;
00366         uint32_t gtpsize = 0;
00367         if(gtpFedAddr !=0) gtpsize = fedCollection->FEDData(daqsource::gtpEvmId_).size();
00368         unsigned char *gtpeFedAddr = fedCollection->FEDData(daqsource::gtpeId_).size()!=0 ? fedCollection->FEDData(daqsource::gtpeId_).data() : 0; 
00369 
00370         unsigned int nextFakeLs = 0;
00371         eventCounter_++;
00372         if (fakeLSid_)
00373             evttype =  edm::EventAuxiliary::PhysicsTrigger; 
00374         if(fakeLSid_ && luminosityBlockNumber_ != 
00375            (nextFakeLs = useEventCounter_ ? ((eventCounter_-1)/lumiSegmentSizeInEvents_ + 1) :
00376             ((eventId.event() - 1)/lumiSegmentSizeInEvents_ + 1))) {
00377           lastLumiPrescaleIndex_->value_ = prescaleSetIndex_->value_;
00378           prescaleSetIndex_->value_ = 0; // since we do not know better but we want to be able to run
00379          
00380           if(luminosityBlockNumber_ == nextFakeLs-1)
00381             signalWaitingThreadAndBlock();
00382           luminosityBlockNumber_ = nextFakeLs;
00383           thisEventLSid = nextFakeLs-1;
00384           newLumi_ = true;
00385           lumiSectionIndex_->value_ = luminosityBlockNumber_;
00386           resetLuminosityBlockAuxiliary();
00387           if(keepUsingPsidFromTrigger_ && 
00388              gtpFedAddr!=0 && evf::evtn::evm_board_sense(gtpFedAddr,gtpsize)){
00389             prescaleSetIndex_->value_  = (evf::evtn::getfdlpsc(gtpFedAddr) & 0xffff);
00390           }       
00391         }
00392         else if(!fakeLSid_){ 
00393 
00394           if(gtpFedAddr!=0 && evf::evtn::evm_board_sense(gtpFedAddr,gtpsize)){
00395             lastLumiPrescaleIndex_->value_ = prescaleSetIndex_->value_;
00396             thisEventLSid = evf::evtn::getlbn(gtpFedAddr);
00397             prescaleSetIndex_->value_  = (evf::evtn::getfdlpsc(gtpFedAddr) & 0xffff);
00398             evttype =  edm::EventAuxiliary::ExperimentType(evf::evtn::getevtyp(gtpFedAddr));
00399             if(luminosityBlockNumber_ != (thisEventLSid + 1)){
00400               // we got here in a running process and some Ls might have been skipped so set the flag, 
00401               // increase by one, check and if appropriate set the flag then continue
00402               if(lsToBeRecovered_->value_){
00403                 //              std::cout << getpid() << "eve::recover ls::for " << thisEventLSid << std::endl;
00404                 signalWaitingThreadAndBlock();
00405                 luminosityBlockNumber_++;
00406                 newLumi_ = true;
00407                 lumiSectionIndex_->value_ = luminosityBlockNumber_;
00408                 resetLuminosityBlockAuxiliary();
00409                 if(luminosityBlockNumber_ != thisEventLSid+1) alignLsToLast_ = true;
00410                 //              std::cout << getpid() << "eve::::alignLsToLast_ " << alignLsToLast_ << std::endl;
00411               }
00412               else{ // we got here because the process was restarted. just realign the ls id and proceed with this event
00413                 //              std::cout << getpid() << "eve::realign ls::for " << thisEventLSid << std::endl;
00414                 luminosityBlockNumber_ = thisEventLSid + 1;
00415                 newLumi_ = true;
00416                 lumiSectionIndex_->value_ = luminosityBlockNumber_;
00417                 resetLuminosityBlockAuxiliary();
00418                 lsToBeRecovered_->value_ = true;
00419               }
00420             }
00421           }
00422           else if(gtpeFedAddr!=0 && evf::evtn::gtpe_board_sense(gtpeFedAddr)){
00423             lastLumiPrescaleIndex_->value_ = prescaleSetIndex_->value_;
00424             thisEventLSid = evf::evtn::gtpe_getlbn(gtpeFedAddr);
00425             prescaleSetIndex_->value_ = 0; //waiting to get a PS index from gtpe
00426             evttype =  edm::EventAuxiliary::PhysicsTrigger; 
00427             if(luminosityBlockNumber_ != (thisEventLSid + 1)){
00428               if(luminosityBlockNumber_ == thisEventLSid)
00429                 signalWaitingThreadAndBlock();
00430               luminosityBlockNumber_ = thisEventLSid + 1;
00431               newLumi_ = true;
00432               lumiSectionIndex_->value_ = luminosityBlockNumber_;
00433               resetLuminosityBlockAuxiliary();
00434             }
00435           }
00436         }
00437         if(gtpFedAddr!=0 && evf::evtn::evm_board_sense(gtpFedAddr,gtpsize)){
00438           bunchCrossing =  int(evf::evtn::getfdlbx(gtpFedAddr));
00439           orbitNumber =  int(evf::evtn::getorbit(gtpFedAddr));
00440           TimeValue_t time = evf::evtn::getgpshigh(gtpFedAddr);
00441           time = (time << 32) + evf::evtn::getgpslow(gtpFedAddr);
00442           Timestamp tstamp(time);
00443           setTimestamp(tstamp);      
00444         }
00445         else if(gtpeFedAddr!=0 && evf::evtn::gtpe_board_sense(gtpeFedAddr)){
00446           bunchCrossing =  int(evf::evtn::gtpe_getbx(gtpeFedAddr));
00447           orbitNumber =  int(evf::evtn::gtpe_getorbit(gtpeFedAddr));
00448         }
00449       }    
00450           
00451     //    std::cout << "lumiblockaux = " << luminosityBlockAuxiliary() << std::endl;
00452     // If there is no luminosity block principal, make one.
00453     if (!luminosityBlockAuxiliary() || luminosityBlockAuxiliary()->luminosityBlock() != luminosityBlockNumber_) {
00454       newLumi_ = true;
00455       setLuminosityBlockAuxiliary(new LuminosityBlockAuxiliary(
00456         runNumber_, luminosityBlockNumber_, timestamp(), Timestamp::invalidTimestamp()));
00457       luminosityBlockAuxiliary()->setProcessHistoryID(phid_);
00458 
00459       //      std::cout << "nextItemType: dealt with new lumi block principal, retval is " << retval << std::endl;
00460     }
00461     //    std::cout << "here retval = " << retval << std::endl;
00462     if(retval<0){
00463       //      std::cout << getpid() << " returning from getnextitem because retval < 0 - IsLumi "
00464       //                << IsLumi << std::endl;
00465       if(newLumi_) return IsLumi; else return getNextItemType();
00466     }
00467 
00468     // make a brand new event principal
00469     eventId = EventID(runNumber_,thisEventLSid+1, eventId.event());
00470     EventAuxiliary eventAux(eventId, processGUID(),
00471                             timestamp(),
00472                             true,
00473                             evttype,
00474                             bunchCrossing,
00475                             EventAuxiliary::invalidStoreNumber,
00476                             orbitNumber);
00477     eventAux.setProcessHistoryID(phid_);
00478     eventPrincipalCache()->fillEventPrincipal(eventAux, boost::shared_ptr<LuminosityBlockPrincipal>());
00479     eventCached_ = true;
00480     
00481     // have fedCollection managed by a std::auto_ptr<>
00482     std::auto_ptr<FEDRawDataCollection> bare_product(fedCollection);
00483 
00484     WrapperOwningHolder edp(new Wrapper<FEDRawDataCollection>(bare_product), Wrapper<FEDRawDataCollection>::getInterface());
00485     eventPrincipalCache()->put(daqProvenanceHelper_.constBranchDescription_, edp, daqProvenanceHelper_.dummyProvenance_);
00486 
00487 /*
00488     Event e(*eventPrincipalCache(), md_);
00489     // put the fed collection into the transient event store
00490     e.put(bare_product);
00491     // The commit is needed to complete the "put" transaction.
00492     e.commit_();
00493 */
00494     if (newLumi_) {
00495       return IsLumi;
00496     }
00497     return IsEvent;
00498   }
00499 
00500   void
00501   DaqSource::setRun(RunNumber_t r) {
00502     assert(!eventCached_);
00503     reset();
00504     newRun_ = newLumi_ = true;
00505     runNumber_ = r;
00506     if (reader_) reader_->setRunNumber(runNumber_);
00507     noMoreEvents_ = false;
00508     resetLuminosityBlockAuxiliary();
00509   }
00510 
00511   boost::shared_ptr<RunAuxiliary>
00512   DaqSource::readRunAuxiliary_() {
00513     assert(newRun_);
00514     assert(!noMoreEvents_);
00515     newRun_ = false;
00516     boost::shared_ptr<RunAuxiliary> ra(new RunAuxiliary(runNumber_, timestamp(), Timestamp::invalidTimestamp()));
00517     ra->setProcessHistoryID(phid_);
00518     return ra;
00519   }
00520 
00521   boost::shared_ptr<LuminosityBlockAuxiliary>
00522   DaqSource::readLuminosityBlockAuxiliary_() {
00523     assert(!newRun_);
00524     assert(newLumi_);
00525     assert(!noMoreEvents_);
00526     assert(luminosityBlockAuxiliary());
00527     //assert(eventCached_); //the event may or may not be cached - rely on 
00528     // the call to getNextItemType to detect that.
00529     newLumi_ = false;
00530     return luminosityBlockAuxiliary();
00531   }
00532 
00533   EventPrincipal*
00534   DaqSource::readEvent_() {
00535     //    std::cout << "assert not newRun " << std::endl;
00536     assert(!newRun_);
00537     //    std::cout << "assert not newLumi " << std::endl;
00538     assert(!newLumi_);
00539     //    std::cout << "assert not noMoreEvents " << std::endl;
00540     assert(!noMoreEvents_);
00541     //    std::cout << "assert eventCached " << std::endl;
00542     assert(eventCached_);
00543     //    std::cout << "asserts done " << std::endl;
00544     eventCached_ = false;
00545     eventPrincipalCache()->setLuminosityBlockPrincipal(luminosityBlockPrincipal());
00546     return eventPrincipalCache();
00547   }
00548 
00549   void
00550   DaqSource::setLumi(LuminosityBlockNumber_t) {
00551       throw edm::Exception(errors::LogicError,"DaqSource::setLumi(LuminosityBlockNumber_t lumiNumber)")
00552         << "The luminosity block number cannot be set externally for DaqSource.\n"
00553         << "Contact a Framework developer.\n";
00554   }
00555 
00556   EventPrincipal*
00557   DaqSource::readIt(EventID const&) {
00558       throw edm::Exception(errors::LogicError,"DaqSource::readIt(EventID const& eventID)")
00559         << "Random access read cannot be used for DaqSource.\n"
00560         << "Contact a Framework developer.\n";
00561   }
00562 
00563   void
00564   DaqSource::skip(int) {
00565       throw edm::Exception(errors::LogicError,"DaqSource::skip(int offset)")
00566         << "Random access skip cannot be used for DaqSource\n"
00567         << "Contact a Framework developer.\n";
00568   }
00569 
00570   void DaqSource::publish(xdata::InfoSpace *is)
00571   {
00572     is_ = is;
00573     lumiSectionIndex_      = (xdata::UnsignedInteger32*)is_->find("lumiSectionIndex");
00574     prescaleSetIndex_      = (xdata::UnsignedInteger32*)is_->find("prescaleSetIndex");
00575     lastLumiPrescaleIndex_ = (xdata::UnsignedInteger32*)is_->find("lastLumiPrescaleIndex");
00576     lastLumiUsingEol_ = (xdata::UnsignedInteger32*)is_->find("lastLumiUsingEol");
00577     lsTimedOut_            = (xdata::Boolean*)is_->find("lsTimedOut");
00578     lsToBeRecovered_       = (xdata::Boolean*)is_->find("lsToBeRecovered");
00579   }
00580   void DaqSource::publishToXmas(xdata::InfoSpace *is)
00581   {
00582     mis_ = is;
00583   }
00584 
00585   void DaqSource::openBackDoor(unsigned int timeout_sec, bool *running)
00586   {
00587     count++;
00588     if(count==2) throw;
00589     pthread_mutex_lock(&mutex_);
00590     if (running) *running=true;
00591     pthread_mutex_unlock(&signal_lock_);
00592     timespec ts;
00593 #if _POSIX_TIMERS > 0
00594     clock_gettime(CLOCK_REALTIME, &ts);
00595 #else
00596     struct timeval tv; 
00597     gettimeofday(&tv, NULL);
00598     ts.tv_sec = tv.tv_sec + 0;
00599     ts.tv_nsec = 0;
00600 #endif
00601     ts.tv_sec += timeout_sec;
00602 
00603     int rc = pthread_cond_timedwait(&cond_, &mutex_, &ts);
00604     if(rc == ETIMEDOUT) lsTimedOut_->value_ = true; 
00605   }
00606   
00607   void DaqSource::closeBackDoor()
00608   {
00609     count--;
00610     pthread_cond_signal(&cond_);
00611     pthread_mutex_unlock(&mutex_);
00612     pthread_mutex_lock(&signal_lock_);
00613     lsTimedOut_->value_ = false; 
00614   }
00615 
00616   void DaqSource::signalWaitingThreadAndBlock()
00617   {
00618     pthread_mutex_lock(&signal_lock_);
00619     pthread_mutex_lock(&mutex_);
00620     pthread_mutex_unlock(&signal_lock_);
00621     //    std::cout << getpid() << " DS::signal from evloop " << std::endl;
00622     pthread_cond_signal(&cond_);
00623     //    std::cout << getpid() << " DS::go to wait for scalers wl " << std::endl;
00624     pthread_cond_wait(&cond_, &mutex_);
00625     pthread_mutex_unlock(&mutex_);
00626     ::usleep(1000);//allow other thread to lock
00627   }  
00628 
00629   void DaqSource::defaultWebPage(xgi::Input *in, xgi::Output *out)
00630   {
00631       std::string path;
00632       std::string urn;
00633       std::string mname;
00634       std::string query;
00635       std::string original_referrer_;
00636       try 
00637         {
00638           cgicc::Cgicc cgi(in);
00639           if ( xgi::Utils::hasFormElement(cgi,"gotostopping") )
00640             {
00641               goToStopping=true;
00642             }
00643           if ( xgi::Utils::hasFormElement(cgi,"module") )
00644             mname = xgi::Utils::getFormElement(cgi, "module")->getValue();
00645           cgicc::CgiEnvironment cgie(in);
00646           if(original_referrer_ == "")
00647             original_referrer_ = cgie.getReferrer();
00648           path = cgie.getPathInfo();
00649           query = cgie.getQueryString();
00650         }
00651       catch (const std::exception & e) 
00652         {
00653           // don't care if it did not work
00654         }
00655 
00656       using std::endl;
00657       *out << "<html>"                                                   << endl;
00658       *out << "<head>"                                                   << endl;
00659 
00660 
00661       *out << "<STYLE type=\"text/css\"> #T1 {border-width: 2px; border: solid blue; text-align: center} </STYLE> "                                      << endl; 
00662       *out << "<link type=\"text/css\" rel=\"stylesheet\"";
00663       *out << " href=\"/" <<  urn
00664            << "/styles.css\"/>"                   << endl;
00665 
00666       *out << "<title>" << moduleName_
00667            << " MAIN</title>"                                            << endl;
00668 
00669       *out << "</head>"                                                  << endl;
00670       *out << "<body onload=\"loadXMLDoc()\">"                           << endl;
00671       *out << "<table border=\"0\" width=\"100%\">"                      << endl;
00672       *out << "<tr>"                                                     << endl;
00673       *out << "  <td align=\"left\">"                                    << endl;
00674       *out << "    <img"                                                 << endl;
00675       *out << "     align=\"middle\""                                    << endl;
00676       *out << "     src=\"/evf/images/bugicon.jpg\""                     << endl;
00677       *out << "     alt=\"main\""                                        << endl;
00678       *out << "     width=\"90\""                                        << endl;
00679       *out << "     height=\"64\""                                       << endl;
00680       *out << "     border=\"\"/>"                                       << endl;
00681       *out << "    <b>"                                                  << endl;
00682       *out <<             moduleName_                                    << endl;
00683       *out << "    </b>"                                                 << endl;
00684       *out << "  </td>"                                                  << endl;
00685       *out << "  <td width=\"32\">"                                      << endl;
00686       *out << "    <a href=\"/urn:xdaq-application:lid=3\">"             << endl;
00687       *out << "      <img"                                               << endl;
00688       *out << "       align=\"middle\""                                  << endl;
00689       *out << "       src=\"/hyperdaq/images/HyperDAQ.jpg\""             << endl;
00690       *out << "       alt=\"HyperDAQ\""                                  << endl;
00691       *out << "       width=\"32\""                                      << endl;
00692       *out << "       height=\"32\""                                     << endl;
00693       *out << "       border=\"\"/>"                                     << endl;
00694       *out << "    </a>"                                                 << endl;
00695       *out << "  </td>"                                                  << endl;
00696       *out << "  <td width=\"32\">"                                      << endl;
00697       *out << "  </td>"                                                  << endl;
00698       *out << "  <td width=\"32\">"                                      << endl;
00699       *out << "    <a href=\"" << original_referrer_  << "\">"           << endl;
00700       *out << "      <img"                                               << endl;
00701       *out << "       align=\"middle\""                                  << endl;
00702       *out << "       src=\"/evf/images/spoticon.jpg\""                  << endl;
00703       *out << "       alt=\"main\""                                      << endl;
00704       *out << "       width=\"32\""                                      << endl;
00705       *out << "       height=\"32\""                                     << endl;
00706       *out << "       border=\"\"/>"                                     << endl;
00707       *out << "    </a>"                                                 << endl;
00708       *out << "  </td>"                                                  << endl;
00709       *out << "</tr>"                                                    << endl;
00710       *out << "</table>"                                                 << endl;
00711 
00712       *out << "<hr/>"                                                    << endl;
00713   
00714       *out << cgicc::form().set("method","GET").set("action", path ) 
00715            << std::endl;
00716       boost::char_separator<char> sep("&");
00717       boost::tokenizer<boost::char_separator<char> > tokens(query, sep);
00718       for (boost::tokenizer<boost::char_separator<char> >::iterator tok_iter = tokens.begin();
00719            tok_iter != tokens.end(); ++tok_iter){
00720         size_t pos = (*tok_iter).find_first_of("=");
00721         if(pos != std::string::npos){
00722           std::string first  = (*tok_iter).substr(0    ,                        pos);
00723           std::string second = (*tok_iter).substr(pos+1, (*tok_iter).length()-pos-1);
00724           *out << cgicc::input().set("type","hidden").set("name",first).set("value", second) 
00725                << std::endl;
00726         }
00727       }
00728 
00729       *out << cgicc::input().set("type","hidden").set("name","gotostopping").set("value","true")
00730            << std::endl;
00731       *out << cgicc::input().set("type","submit").set("value","Go To Stopping")              << std::endl;
00732       *out << cgicc::form()                                                << std::endl;  
00733 
00734       *out << "</body>"                                                  << endl;
00735       *out << "</html>"                                                  << endl;
00736   }
00737 }