Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-22 06:27:20

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/ProductDescription.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<ProductDescription 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     ProductDescription const& productDescription_() const final { return *getProductData().productDescription(); }
0090     void resetProductDescription_(std::shared_ptr<ProductDescription const> bd) final {
0091       productData_.resetProductDescription(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<ProductDescription 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<ProductDescription 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<ProductDescription 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<ProductDescription 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<ProductDescription 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<ProductDescription 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<ProductDescription 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<ProductDescription 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     ProductDescription const& productDescription_() const override { return *bd_; }
0323     void resetProductDescription_(std::shared_ptr<ProductDescription 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<ProductDescription 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<ProductDescription 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     ProductDescription const& productDescription_() const final {
0364       return *productData_.productDescription();
0365       ;
0366     }
0367     void resetProductDescription_(std::shared_ptr<ProductDescription const> bd) final {
0368       productData_.resetProductDescription(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<ProductDescription 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<ProductDescription 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 NoProcessProductResolver : public ProductResolverBase {
0442   public:
0443     typedef ProducedProductResolver::ProductStatus ProductStatus;
0444     NoProcessProductResolver(std::vector<ProductResolverIndex> const& matchingHolders,
0445                              std::vector<bool> const& ambiguous,
0446                              bool madeAtEnd);
0447 
0448     void connectTo(ProductResolverBase const& iOther, Principal const*) final;
0449 
0450     void tryPrefetchResolverAsync(unsigned int iProcessingIndex,
0451                                   Principal const& principal,
0452                                   bool skipCurrentProcess,
0453                                   SharedResourcesAcquirer* sra,
0454                                   ModuleCallingContext const* mcc,
0455                                   ServiceToken token,
0456                                   oneapi::tbb::task_group*) const noexcept;
0457 
0458     bool dataValidFromResolver(unsigned int iProcessingIndex,
0459                                Principal const& principal,
0460                                bool iSkipCurrentProcess) const;
0461 
0462     void prefetchFailed(unsigned int iProcessingIndex,
0463                         Principal const& principal,
0464                         bool iSkipCurrentProcess,
0465                         std::exception_ptr iExceptPtr) const;
0466 
0467   private:
0468     unsigned int unsetIndexValue() const;
0469     Resolution resolveProduct_(Principal const& principal,
0470                                bool skipCurrentProcess,
0471                                SharedResourcesAcquirer* sra,
0472                                ModuleCallingContext const* mcc) const override;
0473     void prefetchAsync_(WaitingTaskHolder waitTask,
0474                         Principal const& principal,
0475                         bool skipCurrentProcess,
0476                         ServiceToken const& token,
0477                         SharedResourcesAcquirer* sra,
0478                         ModuleCallingContext const* mcc) const noexcept override;
0479     bool unscheduledWasNotRun_() const override;
0480     bool productUnavailable_() const override;
0481     bool productWasDeleted_() const override;
0482     bool productResolved_() const final;
0483     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const override;
0484 
0485     ProductDescription const& productDescription_() const override;
0486     void resetProductDescription_(std::shared_ptr<ProductDescription const> bd) override;
0487     Provenance const* provenance_() const override;
0488 
0489     std::string const& resolvedModuleLabel_() const override { return moduleLabel(); }
0490     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) override;
0491     void setProductID_(ProductID const& pid) override;
0492     ProductProvenance const* productProvenancePtr_() const override;
0493     void resetProductData_(bool deleteEarly) override;
0494     bool singleProduct_() const override;
0495 
0496     Resolution tryResolver(unsigned int index,
0497                            Principal const& principal,
0498                            bool skipCurrentProcess,
0499                            SharedResourcesAcquirer* sra,
0500                            ModuleCallingContext const* mcc) const;
0501 
0502     void setCache(bool skipCurrentProcess, ProductResolverIndex index, std::exception_ptr exceptionPtr) const;
0503 
0504     std::vector<ProductResolverIndex> matchingHolders_;
0505     std::vector<bool> ambiguous_;
0506     CMS_THREAD_SAFE mutable WaitingTaskList waitingTasks_;
0507     CMS_THREAD_SAFE mutable WaitingTaskList skippingWaitingTasks_;
0508     mutable std::atomic<unsigned int> lastCheckIndex_;
0509     mutable std::atomic<unsigned int> lastSkipCurrentCheckIndex_;
0510     mutable std::atomic<bool> prefetchRequested_;
0511     mutable std::atomic<bool> skippingPrefetchRequested_;
0512     const bool madeAtEnd_;
0513   };
0514 
0515   class SingleChoiceNoProcessProductResolver : public ProductResolverBase {
0516   public:
0517     typedef ProducedProductResolver::ProductStatus ProductStatus;
0518     SingleChoiceNoProcessProductResolver(ProductResolverIndex iChoice)
0519         : ProductResolverBase(), realResolverIndex_(iChoice) {}
0520 
0521     void connectTo(ProductResolverBase const& iOther, Principal const*) final;
0522 
0523   private:
0524     Resolution resolveProduct_(Principal const& principal,
0525                                bool skipCurrentProcess,
0526                                SharedResourcesAcquirer* sra,
0527                                ModuleCallingContext const* mcc) const override;
0528     void prefetchAsync_(WaitingTaskHolder waitTask,
0529                         Principal const& principal,
0530                         bool skipCurrentProcess,
0531                         ServiceToken const& token,
0532                         SharedResourcesAcquirer* sra,
0533                         ModuleCallingContext const* mcc) const noexcept override;
0534     bool unscheduledWasNotRun_() const override;
0535     bool productUnavailable_() const override;
0536     bool productWasDeleted_() const override;
0537     bool productResolved_() const final;
0538     bool productWasFetchedAndIsValid_(bool iSkipCurrentProcess) const override;
0539 
0540     ProductDescription const& productDescription_() const override;
0541     void resetProductDescription_(std::shared_ptr<ProductDescription const> bd) override;
0542     Provenance const* provenance_() const override;
0543 
0544     std::string const& resolvedModuleLabel_() const override { return moduleLabel(); }
0545     void setProductProvenanceRetriever_(ProductProvenanceRetriever const* provRetriever) override;
0546     void setProductID_(ProductID const& pid) override;
0547     ProductProvenance const* productProvenancePtr_() const override;
0548     void resetProductData_(bool deleteEarly) override;
0549     bool singleProduct_() const override;
0550 
0551     ProductResolverIndex realResolverIndex_;
0552   };
0553 
0554 }  // namespace edm
0555 
0556 #endif