Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:19:06

0001 /*----------------------------------------------------------------------
0002 ----------------------------------------------------------------------*/
0003 
0004 #include "RootDelayedReader.h"
0005 #include "InputFile.h"
0006 #include "DataFormats/Common/interface/EDProductGetter.h"
0007 #include "DataFormats/Common/interface/RefCoreStreamer.h"
0008 
0009 #include "FWCore/Framework/interface/SharedResourcesAcquirer.h"
0010 #include "FWCore/Framework/interface/SharedResourcesRegistry.h"
0011 
0012 #include "IOPool/Common/interface/getWrapperBasePtr.h"
0013 
0014 #include "FWCore/Utilities/interface/EDMException.h"
0015 
0016 #include "TBranch.h"
0017 #include "TClass.h"
0018 
0019 #include <cassert>
0020 
0021 namespace edm {
0022 
0023   RootDelayedReader::RootDelayedReader(RootTree const& tree, std::shared_ptr<InputFile> filePtr, InputType inputType)
0024       : tree_(tree),
0025         filePtr_(filePtr),
0026         nextReader_(),
0027         inputType_(inputType),
0028         wrapperBaseTClass_(TClass::GetClass("edm::WrapperBase")) {
0029     if (inputType == InputType::Primary) {
0030       auto resources = SharedResourcesRegistry::instance()->createAcquirerForSourceDelayedReader();
0031       resourceAcquirer_ = std::make_unique<SharedResourcesAcquirer>(std::move(resources.first));
0032       mutex_ = resources.second;
0033     }
0034   }
0035 
0036   RootDelayedReader::~RootDelayedReader() {}
0037 
0038   std::pair<SharedResourcesAcquirer*, std::recursive_mutex*> RootDelayedReader::sharedResources_() const {
0039     return std::make_pair(resourceAcquirer_.get(), mutex_.get());
0040   }
0041 
0042   std::shared_ptr<WrapperBase> RootDelayedReader::getProduct_(BranchID const& k, EDProductGetter const* ep) {
0043     if (lastException_) {
0044       try {
0045         std::rethrow_exception(lastException_);
0046       } catch (edm::Exception const& e) {
0047         //avoid growing the context each time the exception is rethrown.
0048         auto copy = e;
0049         copy.addContext("Rethrowing an exception that happened on a different read request.");
0050         throw copy;
0051       } catch (cms::Exception& e) {
0052         //If we do anything here to 'copy', we would lose the actual type of the exception.
0053         e.addContext("Rethrowing an exception that happened on a different read request.");
0054         throw;
0055       }
0056     }
0057     auto branchInfo = getBranchInfo(k);
0058     if (not branchInfo) {
0059       if (nextReader_) {
0060         return nextReader_->getProduct(k, ep);
0061       } else {
0062         return std::shared_ptr<WrapperBase>();
0063       }
0064     }
0065     TBranch* br = branchInfo->productBranch_;
0066     if (br == nullptr) {
0067       if (nextReader_) {
0068         return nextReader_->getProduct(k, ep);
0069       } else {
0070         return std::shared_ptr<WrapperBase>();
0071       }
0072     }
0073 
0074     setRefCoreStreamer(ep);
0075     //make code exception safe
0076     std::shared_ptr<void> refCoreStreamerGuard(nullptr, [](void*) {
0077       setRefCoreStreamer(false);
0078       ;
0079     });
0080     TClass* cp = branchInfo->classCache_;
0081     if (nullptr == cp) {
0082       branchInfo->classCache_ = TClass::GetClass(branchInfo->branchDescription_.wrappedName().c_str());
0083       cp = branchInfo->classCache_;
0084       branchInfo->offsetToWrapperBase_ = cp->GetBaseClassOffset(wrapperBaseTClass_);
0085     }
0086     void* p = cp->New();
0087     std::unique_ptr<WrapperBase> edp = getWrapperBasePtr(p, branchInfo->offsetToWrapperBase_);
0088     br->SetAddress(&p);
0089     try {
0090       //Run, Lumi, and ProcessBlock only have 1 entry number, which is index 0
0091       tree_.getEntry(br, tree_.entryNumberForIndex(tree_.branchType() == InEvent ? ep->transitionIndex() : 0));
0092     } catch (...) {
0093       lastException_ = std::current_exception();
0094       std::rethrow_exception(lastException_);
0095     }
0096     if (tree_.branchType() == InEvent) {
0097       // CMS-THREADING For the primary input source calls to this function need to be serialized
0098       InputFile::reportReadBranch(inputType_, std::string(br->GetName()));
0099     }
0100     return edp;
0101   }
0102 }  // namespace edm