Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:31:54

0001 #ifndef Utilities_XrdAdaptor_XrdRequest_h
0002 #define Utilities_XrdAdaptor_XrdRequest_h
0003 
0004 #include <future>
0005 #include <vector>
0006 
0007 #include <XrdCl/XrdClXRootDResponses.hh>
0008 
0009 #include "Utilities/StorageFactory/interface/Storage.h"
0010 #include "FWCore/Utilities/interface/get_underlying_safe.h"
0011 
0012 #include "QualityMetric.h"
0013 
0014 namespace XrdAdaptor {
0015 
0016   class Source;
0017 
0018   class RequestManager;
0019 
0020   class XrdReadStatistics;
0021 
0022   class ClientRequest : public XrdCl::ResponseHandler {
0023     friend class Source;
0024 
0025   public:
0026     using IOPosBuffer = edm::storage::IOPosBuffer;
0027     using IOSize = edm::storage::IOSize;
0028     using IOOffset = edm::storage::IOOffset;
0029 
0030     ClientRequest(const ClientRequest &) = delete;
0031     ClientRequest &operator=(const ClientRequest &) = delete;
0032 
0033     ClientRequest(RequestManager &manager, void *into, IOSize size, IOOffset off)
0034         : m_failure_count(0), m_into(into), m_size(size), m_off(off), m_iolist(nullptr), m_manager(manager) {}
0035 
0036     ClientRequest(RequestManager &manager, std::shared_ptr<std::vector<IOPosBuffer>> iolist, IOSize size = 0)
0037         : m_failure_count(0), m_into(nullptr), m_size(size), m_off(0), m_iolist(iolist), m_manager(manager) {
0038       if (!m_iolist->empty() && !m_size) {
0039         for (edm::storage::IOPosBuffer const &buf : *m_iolist) {
0040           m_size += buf.size();
0041         }
0042       }
0043     }
0044 
0045     void setStatistics(std::shared_ptr<XrdReadStatistics> stats) { m_stats = stats; }
0046 
0047     ~ClientRequest() override;
0048 
0049     std::future<edm::storage::IOSize> get_future() { return m_promise.get_future(); }
0050 
0051     /**
0052      * Handle the response from the Xrootd server.
0053      */
0054     void HandleResponse(XrdCl::XRootDStatus *status, XrdCl::AnyObject *response) override;
0055 
0056     edm::storage::IOSize getSize() const { return m_size; }
0057 
0058     size_t getCount() const { return m_into ? 1 : m_iolist->size(); }
0059 
0060     /**
0061      * Returns a pointer to the current source; may be nullptr
0062      * if there is no outstanding IO
0063      */
0064     std::shared_ptr<Source const> getCurrentSource() const { return get_underlying_safe(m_source); }
0065     std::shared_ptr<Source> &getCurrentSource() { return get_underlying_safe(m_source); }
0066 
0067   private:
0068     std::shared_ptr<ClientRequest const> self_reference() const { return get_underlying_safe(m_self_reference); }
0069     std::shared_ptr<ClientRequest> &self_reference() { return get_underlying_safe(m_self_reference); }
0070 
0071     unsigned m_failure_count;
0072     void *m_into;
0073     edm::storage::IOSize m_size;
0074     edm::storage::IOOffset m_off;
0075     edm::propagate_const<std::shared_ptr<std::vector<edm::storage::IOPosBuffer>>> m_iolist;
0076     RequestManager &m_manager;
0077     edm::propagate_const<std::shared_ptr<Source>> m_source;
0078     edm::propagate_const<std::shared_ptr<XrdReadStatistics>> m_stats;
0079 
0080     // Some explanation is due here.  When an IO is outstanding,
0081     // Xrootd takes a raw pointer to this object.  Hence we cannot
0082     // allow it to go out of scope until some indeterminate time in the
0083     // future.  So, while the IO is outstanding, we take a reference to
0084     // ourself to prevent the object from being unexpectedly deleted.
0085     edm::propagate_const<std::shared_ptr<ClientRequest>> m_self_reference;
0086 
0087     std::promise<edm::storage::IOSize> m_promise;
0088 
0089     QualityMetricWatch m_qmw;
0090   };
0091 
0092 }  // namespace XrdAdaptor
0093 
0094 #endif