Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-05-11 03:34:15

0001 #ifndef FWCore_Framework_ProductResolvers_h
0002 #define FWCore_Framework_ProductResolvers_h
0003 
0004 /*----------------------------------------------------------------------
0005 
0006 ProductResolver: A collection of information related to a single WrapperBase or
0007 a set of related EDProducts. This is the storage unit of such information.
0008 
0009 ----------------------------------------------------------------------*/
0010 #include "FWCore/Framework/interface/ProductResolverBase.h"
0011 #include "FWCore/Framework/interface/ProductPutterBase.h"
0012 #include "FWCore/Framework/src/ProductPutOrMergerBase.h"
0013 #include "DataFormats/Common/interface/WrapperBase.h"
0014 #include "DataFormats/Common/interface/ProductData.h"
0015 #include "DataFormats/Provenance/interface/BranchDescription.h"
0016 #include "DataFormats/Provenance/interface/BranchID.h"
0017 #include "DataFormats/Provenance/interface/Provenance.h"
0018 #include "FWCore/Framework/interface/Principal.h"
0019 #include "FWCore/ServiceRegistry/interface/GlobalContext.h"
0020 #include "FWCore/ServiceRegistry/interface/ModuleCallingContext.h"
0021 #include "FWCore/Utilities/interface/BranchType.h"
0022 #include "FWCore/Utilities/interface/ProductResolverIndex.h"
0023 #include "FWCore/Utilities/interface/TypeID.h"
0024 #include "FWCore/Utilities/interface/thread_safety_macros.h"
0025 #include "FWCore/Concurrency/interface/WaitingTaskList.h"
0026 #include "FWCore/Concurrency/interface/WaitingTaskHolder.h"
0027 
0028 #include <atomic>
0029 #include <memory>
0030 #include <string>
0031 
0032 namespace edm {
0033   class MergeableRunProductMetadata;
0034   class ProductProvenanceRetriever;
0035   class DelayedReader;
0036   class SharedResourcesAcquirer;
0037   class UnscheduledAuxiliary;
0038   class Worker;
0039   class ServiceToken;
0040 
0041   class DataManagingOrAliasProductResolver : public ProductResolverBase {
0042   public:
0043     DataManagingOrAliasProductResolver() : ProductResolverBase{} {}
0044 
0045     // Give AliasProductResolver and SwitchBaseProductResolver access by moving this method to public
0046     void resetProductData_(bool deleteEarly) override = 0;
0047     virtual ProductData const& getProductData() const = 0;
0048   };
0049 
0050   class DataManagingProductResolver : public DataManagingOrAliasProductResolver {
0051   public:
0052     enum class ProductStatus { ProductSet, NotPut, ResolveFailed, ResolveNotRun, ProductDeleted };
0053 
0054     DataManagingProductResolver(std::shared_ptr<BranchDescription const> bd, ProductStatus iDefaultStatus)
0055         : DataManagingOrAliasProductResolver(),
0056           productData_(bd),
0057           theStatus_(iDefaultStatus),
0058           defaultStatus_(iDefaultStatus) {}
0059 
0060     void connectTo(ProductResolverBase const&, Principal const*) final;
0061 
0062     void resetStatus() { theStatus_ = defaultStatus_; }
0063 
0064     void resetProductData_(bool deleteEarly) override;
0065 
0066   protected:
0067     void setProduct(std::unique_ptr<WrapperBase> edp) const;
0068     void setProduct(std::shared_ptr<WrapperBase> edp) const;
0069     ProductStatus status() const { return theStatus_; }
0070     ProductStatus defaultStatus() const { return defaultStatus_; }
0071     void setFailedStatus() const { theStatus_ = ProductStatus::ResolveFailed; }
0072     //Handle the boilerplate code needed for resolveProduct_
0073     template <bool callResolver, typename FUNC>
0074     Resolution resolveProductImpl(FUNC resolver) const;
0075     ProductData const& getProductData() const final { return productData_; }
0076     void setMergeableRunProductMetadataInProductData(MergeableRunProductMetadata const*);
0077 
0078     void checkType(WrapperBase const& prod) const;
0079 
0080   private:
0081     void throwProductDeletedException() const;
0082     virtual bool isFromCurrentProcess() const = 0;
0083 
0084     bool productUnavailable_() const final;
0085     bool productResolved_() const final;
0086     bool productWasDeleted_() const final;
0087     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const final;
0088 
0089     BranchDescription const& branchDescription_() const final { return *getProductData().branchDescription(); }
0090     void resetBranchDescription_(std::shared_ptr<BranchDescription const> bd) final {
0091       productData_.resetBranchDescription(bd);
0092     }
0093     Provenance const* provenance_() const final { return &productData_.provenance(); }
0094 
0095     std::string const& resolvedModuleLabel_() const final { return moduleLabel(); }
0096     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) final;
0097     void setProductID_(ProductID const& pid) final;
0098     ProductProvenance const* productProvenancePtr_() const final;
0099     bool singleProduct_() const final;
0100 
0101     ProductData productData_;
0102     mutable std::atomic<ProductStatus> theStatus_;
0103     ProductStatus const defaultStatus_;
0104   };
0105 
0106   class MergeableInputProductResolver : public DataManagingProductResolver {
0107   public:
0108     MergeableInputProductResolver(std::shared_ptr<BranchDescription const> bd, ProductStatus iDefaultStatus)
0109         : DataManagingProductResolver(bd, iDefaultStatus) {}
0110 
0111   protected:
0112     void setOrMergeProduct(std::shared_ptr<WrapperBase> prod,
0113                            MergeableRunProductMetadata const* mergeableRunProductMetadata) const;
0114 
0115     // merges the product with the pre-existing product
0116     void mergeProduct(std::shared_ptr<WrapperBase> edp, MergeableRunProductMetadata const*) const;
0117   };
0118 
0119   class DelayedReaderInputProductResolver : public MergeableInputProductResolver {
0120   public:
0121     explicit DelayedReaderInputProductResolver(std::shared_ptr<BranchDescription const> bd)
0122         : MergeableInputProductResolver(bd, ProductStatus::ResolveNotRun), m_prefetchRequested{false}, aux_{nullptr} {
0123       assert(bd->onDemand());
0124       assert(not bd->produced());
0125     }
0126 
0127     void setupUnscheduled(UnscheduledConfigurator const&) final;
0128 
0129   private:
0130     bool isFromCurrentProcess() const final;
0131 
0132     Resolution resolveProduct_(Principal const& principal,
0133                                bool skipCurrentProcess,
0134                                SharedResourcesAcquirer* sra,
0135                                ModuleCallingContext const* mcc) const override;
0136     void prefetchAsync_(WaitingTaskHolder waitTask,
0137                         Principal const& principal,
0138                         bool skipCurrentProcess,
0139                         ServiceToken const& token,
0140                         SharedResourcesAcquirer* sra,
0141                         ModuleCallingContext const* mcc) const noexcept override;
0142 
0143     void retrieveAndMerge_(Principal const& principal,
0144                            MergeableRunProductMetadata const* mergeableRunProductMetadata) const override;
0145 
0146     void setMergeableRunProductMetadata_(MergeableRunProductMetadata const*) override;
0147 
0148     bool unscheduledWasNotRun_() const final { return false; }
0149 
0150     void resetProductData_(bool deleteEarly) override;
0151 
0152     mutable std::atomic<bool> m_prefetchRequested;
0153     CMS_THREAD_SAFE mutable WaitingTaskList m_waitingTasks;
0154     UnscheduledAuxiliary const* aux_;  //provides access to the delayedGet signals
0155   };
0156 
0157   class PutOnReadInputProductResolver : public MergeableInputProductResolver,
0158                                         public ProductPutterBase,
0159                                         public ProductPutOrMergerBase {
0160   public:
0161     PutOnReadInputProductResolver(std::shared_ptr<BranchDescription const> bd)
0162         : MergeableInputProductResolver(bd, ProductStatus::ResolveNotRun) {
0163       assert(not bd->produced());
0164       assert(not bd->onDemand());
0165     }
0166 
0167   protected:
0168     void putProduct(std::unique_ptr<WrapperBase> edp) const override;
0169     void putOrMergeProduct(std::unique_ptr<WrapperBase> prod) const override;
0170 
0171     Resolution resolveProduct_(Principal const& principal,
0172                                bool skipCurrentProcess,
0173                                SharedResourcesAcquirer* sra,
0174                                ModuleCallingContext const* mcc) const final;
0175     void prefetchAsync_(WaitingTaskHolder waitTask,
0176                         Principal const& principal,
0177                         bool skipCurrentProcess,
0178                         ServiceToken const& token,
0179                         SharedResourcesAcquirer* sra,
0180                         ModuleCallingContext const* mcc) const noexcept final;
0181     bool unscheduledWasNotRun_() const final { return false; }
0182 
0183   private:
0184     bool isFromCurrentProcess() const final;
0185   };
0186 
0187   class ProducedProductResolver : public DataManagingProductResolver, public ProductPutterBase {
0188   public:
0189     ProducedProductResolver(std::shared_ptr<BranchDescription const> bd, ProductStatus iDefaultStatus)
0190         : DataManagingProductResolver(bd, iDefaultStatus) {
0191       assert(bd->produced());
0192     }
0193 
0194   protected:
0195     void putProduct(std::unique_ptr<WrapperBase> edp) const override;
0196 
0197   private:
0198     bool isFromCurrentProcess() const final;
0199   };
0200 
0201   class PuttableProductResolver : public ProducedProductResolver {
0202   public:
0203     explicit PuttableProductResolver(std::shared_ptr<BranchDescription const> bd)
0204         : ProducedProductResolver(bd, ProductStatus::NotPut) {}
0205 
0206     void setupUnscheduled(UnscheduledConfigurator const&) final;
0207 
0208   private:
0209     Resolution resolveProduct_(Principal const& principal,
0210                                bool skipCurrentProcess,
0211                                SharedResourcesAcquirer* sra,
0212                                ModuleCallingContext const* mcc) const override;
0213     void prefetchAsync_(WaitingTaskHolder waitTask,
0214                         Principal const& principal,
0215                         bool skipCurrentProcess,
0216                         ServiceToken const& token,
0217                         SharedResourcesAcquirer* sra,
0218                         ModuleCallingContext const* mcc) const noexcept override;
0219     bool unscheduledWasNotRun_() const override { return false; }
0220 
0221     // The WaitingTaskList below is the one from the worker, if one
0222     // corresponds to this ProductResolver. For the Source-like cases
0223     // where there is no such Worker, the tasks depending on the data
0224     // depending on this ProductResolver are assumed to be eligible to
0225     // run immediately after their prefetch.
0226     WaitingTaskList* waitingTasks_ = nullptr;
0227   };
0228 
0229   class UnscheduledProductResolver : public ProducedProductResolver {
0230   public:
0231     explicit UnscheduledProductResolver(std::shared_ptr<BranchDescription const> bd)
0232         : ProducedProductResolver(bd, ProductStatus::ResolveNotRun) {}
0233 
0234     void setupUnscheduled(UnscheduledConfigurator const&) final;
0235 
0236   private:
0237     Resolution resolveProduct_(Principal const& principal,
0238                                bool skipCurrentProcess,
0239                                SharedResourcesAcquirer* sra,
0240                                ModuleCallingContext const* mcc) const override;
0241     void prefetchAsync_(WaitingTaskHolder waitTask,
0242                         Principal const& principal,
0243                         bool skipCurrentProcess,
0244                         ServiceToken const& token,
0245                         SharedResourcesAcquirer* sra,
0246                         ModuleCallingContext const* mcc) const noexcept override;
0247     bool unscheduledWasNotRun_() const override { return status() == ProductStatus::ResolveNotRun; }
0248 
0249     void resetProductData_(bool deleteEarly) override;
0250 
0251     CMS_THREAD_SAFE mutable WaitingTaskList waitingTasks_;
0252     UnscheduledAuxiliary const* aux_ = nullptr;
0253     Worker* worker_ = nullptr;
0254     mutable std::atomic<bool> prefetchRequested_ = false;
0255   };
0256 
0257   class TransformingProductResolver : public ProducedProductResolver {
0258   public:
0259     explicit TransformingProductResolver(std::shared_ptr<BranchDescription const> bd)
0260         : ProducedProductResolver(bd, ProductStatus::ResolveNotRun), mcc_(nullptr) {}
0261 
0262     void setupUnscheduled(UnscheduledConfigurator const&) final;
0263 
0264   private:
0265     void putProduct(std::unique_ptr<WrapperBase> edp) const override;
0266     Resolution resolveProduct_(Principal const& principal,
0267                                bool skipCurrentProcess,
0268                                SharedResourcesAcquirer* sra,
0269                                ModuleCallingContext const* mcc) const override;
0270     void prefetchAsync_(WaitingTaskHolder waitTask,
0271                         Principal const& principal,
0272                         bool skipCurrentProcess,
0273                         ServiceToken const& token,
0274                         SharedResourcesAcquirer* sra,
0275                         ModuleCallingContext const* mcc) const noexcept override;
0276     bool unscheduledWasNotRun_() const override { return status() == ProductStatus::ResolveNotRun; }
0277 
0278     void resetProductData_(bool deleteEarly) override;
0279 
0280     CMS_THREAD_SAFE mutable WaitingTaskList waitingTasks_;
0281     UnscheduledAuxiliary const* aux_ = nullptr;
0282     Worker* worker_ = nullptr;
0283     CMS_THREAD_GUARD(prefetchRequested_) mutable ModuleCallingContext mcc_;
0284     size_t index_;
0285     mutable std::atomic<bool> prefetchRequested_ = false;
0286   };
0287 
0288   class AliasProductResolver : public DataManagingOrAliasProductResolver {
0289   public:
0290     typedef ProducedProductResolver::ProductStatus ProductStatus;
0291     explicit AliasProductResolver(std::shared_ptr<BranchDescription const> bd,
0292                                   DataManagingOrAliasProductResolver& realProduct)
0293         : DataManagingOrAliasProductResolver(), realProduct_(realProduct), bd_(bd) {}
0294 
0295     void connectTo(ProductResolverBase const& iOther, Principal const* iParentPrincipal) final {
0296       realProduct_.connectTo(iOther, iParentPrincipal);
0297     };
0298 
0299   private:
0300     Resolution resolveProduct_(Principal const& principal,
0301                                bool skipCurrentProcess,
0302                                SharedResourcesAcquirer* sra,
0303                                ModuleCallingContext const* mcc) const override {
0304       return realProduct_.resolveProduct(principal, skipCurrentProcess, sra, mcc);
0305     }
0306     void prefetchAsync_(WaitingTaskHolder waitTask,
0307                         Principal const& principal,
0308                         bool skipCurrentProcess,
0309                         ServiceToken const& token,
0310                         SharedResourcesAcquirer* sra,
0311                         ModuleCallingContext const* mcc) const noexcept override {
0312       realProduct_.prefetchAsync(waitTask, principal, skipCurrentProcess, token, sra, mcc);
0313     }
0314     bool unscheduledWasNotRun_() const override { return realProduct_.unscheduledWasNotRun(); }
0315     bool productUnavailable_() const override { return realProduct_.productUnavailable(); }
0316     bool productResolved_() const final { return realProduct_.productResolved(); }
0317     bool productWasDeleted_() const override { return realProduct_.productWasDeleted(); }
0318     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const final {
0319       return realProduct_.productWasFetchedAndIsValid(iSkipCurrentProcess);
0320     }
0321 
0322     BranchDescription const& branchDescription_() const override { return *bd_; }
0323     void resetBranchDescription_(std::shared_ptr<BranchDescription const> bd) override { bd_ = bd; }
0324     Provenance const* provenance_() const final { return realProduct_.provenance(); }
0325 
0326     std::string const& resolvedModuleLabel_() const override { return realProduct_.moduleLabel(); }
0327     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) override;
0328     void setProductID_(ProductID const& pid) override;
0329     ProductProvenance const* productProvenancePtr_() const override;
0330     void resetProductData_(bool deleteEarly) override;
0331     ProductData const& getProductData() const final { return realProduct_.getProductData(); }
0332     bool singleProduct_() const override;
0333 
0334     DataManagingOrAliasProductResolver& realProduct_;
0335     std::shared_ptr<BranchDescription const> bd_;
0336   };
0337 
0338   // Switch is a mixture of DataManaging (for worker and provenance) and Alias (for product)
0339   class SwitchBaseProductResolver : public DataManagingOrAliasProductResolver {
0340   public:
0341     using ProductStatus = DataManagingProductResolver::ProductStatus;
0342     SwitchBaseProductResolver(std::shared_ptr<BranchDescription const> bd,
0343                               DataManagingOrAliasProductResolver& realProduct);
0344 
0345     void connectTo(ProductResolverBase const& iOther, Principal const* iParentPrincipal) final;
0346     void setupUnscheduled(UnscheduledConfigurator const& iConfigure) final;
0347 
0348   protected:
0349     Resolution resolveProductImpl(Resolution) const;
0350     WaitingTaskList& waitingTasks() const { return waitingTasks_; }
0351     Worker* worker() const { return worker_; }
0352     DataManagingOrAliasProductResolver const& realProduct() const { return realProduct_; }
0353     std::atomic<bool>& prefetchRequested() const { return prefetchRequested_; }
0354     void unsafe_setWrapperAndProvenance() const;
0355     void resetProductData_(bool deleteEarly) override;
0356 
0357   private:
0358     bool productResolved_() const final;
0359     bool productWasDeleted_() const final { return realProduct_.productWasDeleted(); }
0360     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const final {
0361       return realProduct_.productWasFetchedAndIsValid(iSkipCurrentProcess);
0362     }
0363     BranchDescription const& branchDescription_() const final {
0364       return *productData_.branchDescription();
0365       ;
0366     }
0367     void resetBranchDescription_(std::shared_ptr<BranchDescription const> bd) final {
0368       productData_.resetBranchDescription(bd);
0369     }
0370     Provenance const* provenance_() const final { return &productData_.provenance(); }
0371     std::string const& resolvedModuleLabel_() const final { return moduleLabel(); }
0372     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) final;
0373     void setProductID_(ProductID const& pid) final;
0374     ProductProvenance const* productProvenancePtr_() const final { return provenance()->productProvenance(); }
0375     ProductData const& getProductData() const final { return productData_; }
0376     bool singleProduct_() const final { return true; }
0377 
0378     // for "alias" view
0379     DataManagingOrAliasProductResolver& realProduct_;
0380     // for "product" view
0381     ProductData productData_;
0382     Worker* worker_ = nullptr;
0383     CMS_THREAD_SAFE mutable WaitingTaskList waitingTasks_;
0384     mutable std::atomic<bool> prefetchRequested_;
0385     // for provenance
0386     ParentageID parentageID_;
0387   };
0388 
0389   // For the case when SwitchProducer is on a Path
0390   class SwitchProducerProductResolver : public SwitchBaseProductResolver, public ProductPutterBase {
0391   public:
0392     SwitchProducerProductResolver(std::shared_ptr<BranchDescription const> bd,
0393                                   DataManagingOrAliasProductResolver& realProduct);
0394 
0395   private:
0396     Resolution resolveProduct_(Principal const& principal,
0397                                bool skipCurrentProcess,
0398                                SharedResourcesAcquirer* sra,
0399                                ModuleCallingContext const* mcc) const final;
0400     void prefetchAsync_(WaitingTaskHolder waitTask,
0401                         Principal const& principal,
0402                         bool skipCurrentProcess,
0403                         ServiceToken const& token,
0404                         SharedResourcesAcquirer* sra,
0405                         ModuleCallingContext const* mcc) const noexcept final;
0406     void putProduct(std::unique_ptr<WrapperBase> edp) const final;
0407     bool unscheduledWasNotRun_() const final { return false; }
0408     bool productUnavailable_() const final;
0409     void resetProductData_(bool deleteEarly) final;
0410 
0411     constexpr static const ProductStatus defaultStatus_ = ProductStatus::NotPut;
0412 
0413     // for filter in a Path
0414     // The variable is only modified or read at times where the
0415     //  framework has guaranteed synchronization between write and read
0416     CMS_THREAD_SAFE mutable ProductStatus status_;
0417   };
0418 
0419   // For the case when SwitchProducer is not on any Path
0420   class SwitchAliasProductResolver : public SwitchBaseProductResolver {
0421   public:
0422     SwitchAliasProductResolver(std::shared_ptr<BranchDescription const> bd,
0423                                DataManagingOrAliasProductResolver& realProduct)
0424         : SwitchBaseProductResolver(std::move(bd), realProduct) {}
0425 
0426   private:
0427     Resolution resolveProduct_(Principal const& principal,
0428                                bool skipCurrentProcess,
0429                                SharedResourcesAcquirer* sra,
0430                                ModuleCallingContext const* mcc) const final;
0431     void prefetchAsync_(WaitingTaskHolder waitTask,
0432                         Principal const& principal,
0433                         bool skipCurrentProcess,
0434                         ServiceToken const& token,
0435                         SharedResourcesAcquirer* sra,
0436                         ModuleCallingContext const* mcc) const noexcept final;
0437     bool unscheduledWasNotRun_() const final { return realProduct().unscheduledWasNotRun(); }
0438     bool productUnavailable_() const final { return realProduct().productUnavailable(); }
0439   };
0440 
0441   class ParentProcessProductResolver : public ProductResolverBase {
0442   public:
0443     typedef ProducedProductResolver::ProductStatus ProductStatus;
0444     explicit ParentProcessProductResolver(std::shared_ptr<BranchDescription const> bd)
0445         : ProductResolverBase(), realProduct_(nullptr), bd_(bd), provRetriever_(nullptr), parentPrincipal_(nullptr) {}
0446 
0447     void connectTo(ProductResolverBase const& iOther, Principal const* iParentPrincipal) final {
0448       realProduct_ = &iOther;
0449       parentPrincipal_ = iParentPrincipal;
0450     };
0451 
0452   private:
0453     Resolution resolveProduct_(Principal const& principal,
0454                                bool skipCurrentProcess,
0455                                SharedResourcesAcquirer* sra,
0456                                ModuleCallingContext const* mcc) const override {
0457       if (principal.branchType() == InProcess &&
0458           (mcc->parent().globalContext()->transition() == GlobalContext::Transition::kBeginProcessBlock ||
0459            mcc->parent().globalContext()->transition() == GlobalContext::Transition::kEndProcessBlock)) {
0460         return Resolution(nullptr);
0461       }
0462 
0463       skipCurrentProcess = false;
0464       return realProduct_->resolveProduct(*parentPrincipal_, skipCurrentProcess, sra, mcc);
0465     }
0466     void prefetchAsync_(WaitingTaskHolder waitTask,
0467                         Principal const& principal,
0468                         bool skipCurrentProcess,
0469                         ServiceToken const& token,
0470                         SharedResourcesAcquirer* sra,
0471                         ModuleCallingContext const* mcc) const noexcept override {
0472       if (principal.branchType() == InProcess &&
0473           (mcc->parent().globalContext()->transition() == GlobalContext::Transition::kBeginProcessBlock ||
0474            mcc->parent().globalContext()->transition() == GlobalContext::Transition::kEndProcessBlock)) {
0475         return;
0476       }
0477 
0478       skipCurrentProcess = false;
0479       realProduct_->prefetchAsync(waitTask, *parentPrincipal_, skipCurrentProcess, token, sra, mcc);
0480     }
0481     bool unscheduledWasNotRun_() const override {
0482       if (realProduct_)
0483         return realProduct_->unscheduledWasNotRun();
0484       throwNullRealProduct();
0485       return false;
0486     }
0487     bool productUnavailable_() const override { return realProduct_->productUnavailable(); }
0488     bool productResolved_() const final { return realProduct_->productResolved(); }
0489     bool productWasDeleted_() const override { return realProduct_->productWasDeleted(); }
0490     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const override {
0491       iSkipCurrentProcess = false;
0492       return realProduct_->productWasFetchedAndIsValid(iSkipCurrentProcess);
0493     }
0494 
0495     BranchDescription const& branchDescription_() const override { return *bd_; }
0496     void resetBranchDescription_(std::shared_ptr<BranchDescription const> bd) override { bd_ = bd; }
0497     Provenance const* provenance_() const final { return realProduct_->provenance(); }
0498     std::string const& resolvedModuleLabel_() const override { return realProduct_->moduleLabel(); }
0499     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) override;
0500     void setProductID_(ProductID const& pid) override;
0501     ProductProvenance const* productProvenancePtr_() const override;
0502     void resetProductData_(bool deleteEarly) override;
0503     bool singleProduct_() const override;
0504     void throwNullRealProduct() const;
0505 
0506     ProductResolverBase const* realProduct_;
0507     std::shared_ptr<BranchDescription const> bd_;
0508     ProductProvenanceRetriever const* provRetriever_;
0509     Principal const* parentPrincipal_;
0510   };
0511 
0512   class NoProcessProductResolver : public ProductResolverBase {
0513   public:
0514     typedef ProducedProductResolver::ProductStatus ProductStatus;
0515     NoProcessProductResolver(std::vector<ProductResolverIndex> const& matchingHolders,
0516                              std::vector<bool> const& ambiguous,
0517                              bool madeAtEnd);
0518 
0519     void connectTo(ProductResolverBase const& iOther, Principal const*) final;
0520 
0521     void tryPrefetchResolverAsync(unsigned int iProcessingIndex,
0522                                   Principal const& principal,
0523                                   bool skipCurrentProcess,
0524                                   SharedResourcesAcquirer* sra,
0525                                   ModuleCallingContext const* mcc,
0526                                   ServiceToken token,
0527                                   oneapi::tbb::task_group*) const noexcept;
0528 
0529     bool dataValidFromResolver(unsigned int iProcessingIndex,
0530                                Principal const& principal,
0531                                bool iSkipCurrentProcess) const;
0532 
0533     void prefetchFailed(unsigned int iProcessingIndex,
0534                         Principal const& principal,
0535                         bool iSkipCurrentProcess,
0536                         std::exception_ptr iExceptPtr) const;
0537 
0538   private:
0539     unsigned int unsetIndexValue() const;
0540     Resolution resolveProduct_(Principal const& principal,
0541                                bool skipCurrentProcess,
0542                                SharedResourcesAcquirer* sra,
0543                                ModuleCallingContext const* mcc) const override;
0544     void prefetchAsync_(WaitingTaskHolder waitTask,
0545                         Principal const& principal,
0546                         bool skipCurrentProcess,
0547                         ServiceToken const& token,
0548                         SharedResourcesAcquirer* sra,
0549                         ModuleCallingContext const* mcc) const noexcept override;
0550     bool unscheduledWasNotRun_() const override;
0551     bool productUnavailable_() const override;
0552     bool productWasDeleted_() const override;
0553     bool productResolved_() const final;
0554     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const override;
0555 
0556     BranchDescription const& branchDescription_() const override;
0557     void resetBranchDescription_(std::shared_ptr<BranchDescription const> bd) override;
0558     Provenance const* provenance_() const override;
0559 
0560     std::string const& resolvedModuleLabel_() const override { return moduleLabel(); }
0561     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) override;
0562     void setProductID_(ProductID const& pid) override;
0563     ProductProvenance const* productProvenancePtr_() const override;
0564     void resetProductData_(bool deleteEarly) override;
0565     bool singleProduct_() const override;
0566 
0567     Resolution tryResolver(unsigned int index,
0568                            Principal const& principal,
0569                            bool skipCurrentProcess,
0570                            SharedResourcesAcquirer* sra,
0571                            ModuleCallingContext const* mcc) const;
0572 
0573     void setCache(bool skipCurrentProcess, ProductResolverIndex index, std::exception_ptr exceptionPtr) const;
0574 
0575     std::vector<ProductResolverIndex> matchingHolders_;
0576     std::vector<bool> ambiguous_;
0577     CMS_THREAD_SAFE mutable WaitingTaskList waitingTasks_;
0578     CMS_THREAD_SAFE mutable WaitingTaskList skippingWaitingTasks_;
0579     mutable std::atomic<unsigned int> lastCheckIndex_;
0580     mutable std::atomic<unsigned int> lastSkipCurrentCheckIndex_;
0581     mutable std::atomic<bool> prefetchRequested_;
0582     mutable std::atomic<bool> skippingPrefetchRequested_;
0583     const bool madeAtEnd_;
0584   };
0585 
0586   class SingleChoiceNoProcessProductResolver : public ProductResolverBase {
0587   public:
0588     typedef ProducedProductResolver::ProductStatus ProductStatus;
0589     SingleChoiceNoProcessProductResolver(ProductResolverIndex iChoice)
0590         : ProductResolverBase(), realResolverIndex_(iChoice) {}
0591 
0592     void connectTo(ProductResolverBase const& iOther, Principal const*) final;
0593 
0594   private:
0595     Resolution resolveProduct_(Principal const& principal,
0596                                bool skipCurrentProcess,
0597                                SharedResourcesAcquirer* sra,
0598                                ModuleCallingContext const* mcc) const override;
0599     void prefetchAsync_(WaitingTaskHolder waitTask,
0600                         Principal const& principal,
0601                         bool skipCurrentProcess,
0602                         ServiceToken const& token,
0603                         SharedResourcesAcquirer* sra,
0604                         ModuleCallingContext const* mcc) const noexcept override;
0605     bool unscheduledWasNotRun_() const override;
0606     bool productUnavailable_() const override;
0607     bool productWasDeleted_() const override;
0608     bool productResolved_() const final;
0609     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const override;
0610 
0611     BranchDescription const& branchDescription_() const override;
0612     void resetBranchDescription_(std::shared_ptr<BranchDescription const> bd) override;
0613     Provenance const* provenance_() const override;
0614 
0615     std::string const& resolvedModuleLabel_() const override { return moduleLabel(); }
0616     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) override;
0617     void setProductID_(ProductID const& pid) override;
0618     ProductProvenance const* productProvenancePtr_() const override;
0619     void resetProductData_(bool deleteEarly) override;
0620     bool singleProduct_() const override;
0621 
0622     ProductResolverIndex realResolverIndex_;
0623   };
0624 
0625 }  // namespace edm
0626 
0627 #endif