CMS 3D CMS Logo

List of all members | Public Member Functions | Static Public Member Functions | Private Member Functions | Private Attributes
XrdAdaptor::RequestManager::OpenHandler Class Reference
Inheritance diagram for XrdAdaptor::RequestManager::OpenHandler:

Public Member Functions

std::string current_source ()
 
void HandleResponseWithHosts (XrdCl::XRootDStatus *status, XrdCl::AnyObject *response, XrdCl::HostList *hostList) override
 
std::shared_future< std::shared_ptr< Source > > open ()
 
 ~OpenHandler () override
 

Static Public Member Functions

static std::shared_ptr< OpenHandlergetInstance (std::weak_ptr< RequestManager > manager)
 

Private Member Functions

 OpenHandler (std::weak_ptr< RequestManager > manager)
 

Private Attributes

std::unique_ptr< XrdCl::File > m_file
 
std::weak_ptr< RequestManagerm_manager
 
std::recursive_mutex m_mutex
 
std::atomic< bool > m_outstanding_open {false}
 
std::promise< std::shared_ptr< Source > > m_promise
 
std::shared_ptr< OpenHandlerm_self
 
std::weak_ptr< OpenHandlerm_self_weak
 
std::shared_future< std::shared_ptr< Source > > m_shared_future
 

Detailed Description

Definition at line 241 of file XrdRequestManager.h.

Constructor & Destructor Documentation

XrdAdaptor::RequestManager::OpenHandler::~OpenHandler ( )
override

Definition at line 965 of file XrdRequestManager.cc.

965 {}
XrdAdaptor::RequestManager::OpenHandler::OpenHandler ( std::weak_ptr< RequestManager manager)
private

Definition at line 961 of file XrdRequestManager.cc.

961 : m_manager(manager) {}
std::weak_ptr< RequestManager > m_manager

Member Function Documentation

std::string XrdAdaptor::RequestManager::OpenHandler::current_source ( )

Returns the current source server name. Useful primarily for debugging.

Definition at line 1021 of file XrdRequestManager.cc.

References m_file, m_mutex, and AlCaHLTBitMon_QueryRunRegistry::string.

1021  {
1022  std::lock_guard<std::recursive_mutex> sentry(m_mutex);
1023 
1024  if (!m_file.get()) {
1025  return "(no open in progress)";
1026  }
1027  std::string dataServer;
1028  m_file->GetProperty("DataServer", dataServer);
1029  if (dataServer.empty()) {
1030  return "(unknown source)";
1031  }
1032  return dataServer;
1033 }
std::unique_ptr< XrdCl::File > m_file
static std::shared_ptr<OpenHandler> XrdAdaptor::RequestManager::OpenHandler::getInstance ( std::weak_ptr< RequestManager manager)
inlinestatic

Definition at line 245 of file XrdRequestManager.h.

References instance, m_self_weak, and AlCaHLTBitMon_QueryRunRegistry::string.

Referenced by XrdAdaptor::RequestManager::initialize().

246  {
247  OpenHandler *instance_ptr = new OpenHandler(manager);
248  std::shared_ptr<OpenHandler> instance(instance_ptr);
249  instance_ptr->m_self_weak = instance;
250  return instance;
251  }
static PFTauRenderPlugin instance
OpenHandler(std::weak_ptr< RequestManager > manager)
void XrdAdaptor::RequestManager::OpenHandler::HandleResponseWithHosts ( XrdCl::XRootDStatus *  status,
XrdCl::AnyObject *  response,
XrdCl::HostList *  hostList 
)
override

Handle the file-open response

Definition at line 967 of file XrdRequestManager.cc.

References cms::Exception::addContext(), TauDecayModes::dec, XrdAdaptor::Source::determineHostExcludeString(), edm::errors::FileOpenError, GET_CLOCK_MONOTONIC, m_file, m_manager, m_mutex, m_outstanding_open, m_promise, m_self, eostools::move(), cmsPerfSuiteHarvest::now, SendMonitoringInfo(), PFJetToCaloProducer_cfi::Source, source, mps_update::status, and AlCaHLTBitMon_QueryRunRegistry::string.

969  {
970  // Make sure we get rid of the strong self-reference when the callback finishes.
971  std::shared_ptr<OpenHandler> self = m_self;
972  m_self.reset();
973 
974  // NOTE: as in XrdCl::File (synchronous), we ignore the response object.
975  // Make sure that we set m_outstanding_open to false on exit from this function.
976  // NOTE: we need to pass non-nullptr to unique_ptr in order for the guard to run
977  std::unique_ptr<OpenHandler, std::function<void(OpenHandler *)>> outstanding_guard(
978  this, [&](OpenHandler *) { m_outstanding_open = false; });
979 
980  std::shared_ptr<Source> source;
981  std::unique_ptr<XrdCl::XRootDStatus> status(status_ptr);
982  std::unique_ptr<XrdCl::HostList> hostList(hostList_ptr);
983 
984  auto manager = m_manager.lock();
985  // Manager object has already been deleted. Cleanup the
986  // response objects, remove our self-reference, and ignore the response.
987  if (!manager) {
988  return;
989  }
990  //if we need to delete the File object we must do it outside
991  // of the lock to avoid a potential deadlock
992  std::unique_ptr<XrdCl::File> releaseFile;
993  {
994  std::lock_guard<std::recursive_mutex> sentry(m_mutex);
995 
996  if (status->IsOK()) {
998  timespec now;
999  GET_CLOCK_MONOTONIC(now);
1000 
1001  std::string excludeString;
1002  Source::determineHostExcludeString(*m_file, hostList.get(), excludeString);
1003 
1004  source.reset(new Source(now, std::move(m_file), excludeString));
1005  m_promise.set_value(source);
1006  } else {
1007  releaseFile = std::move(m_file);
1009  ex << "XrdCl::File::Open(name='" << manager->m_name << "', flags=0x" << std::hex << manager->m_flags
1010  << ", permissions=0" << std::oct << manager->m_perms << std::dec << ") => error '" << status->ToStr()
1011  << "' (errno=" << status->errNo << ", code=" << status->code << ")";
1012  ex.addContext("In XrdAdaptor::RequestManager::OpenHandler::HandleResponseWithHosts()");
1013  manager->addConnections(ex);
1014 
1015  m_promise.set_exception(std::make_exception_ptr(ex));
1016  }
1017  }
1018  manager->handleOpen(*status, source);
1019 }
#define GET_CLOCK_MONOTONIC(ts)
static void determineHostExcludeString(XrdCl::File &file, const XrdCl::HostList *hostList, std::string &exclude)
Definition: XrdSource.cc:307
OpenHandler(std::weak_ptr< RequestManager > manager)
std::shared_ptr< OpenHandler > m_self
static void SendMonitoringInfo(XrdCl::File &file)
std::weak_ptr< RequestManager > m_manager
std::unique_ptr< XrdCl::File > m_file
std::promise< std::shared_ptr< Source > > m_promise
static std::string const source
Definition: EdmProvDump.cc:47
def move(src, dest)
Definition: eostools.py:511
std::shared_future< std::shared_ptr< Source > > XrdAdaptor::RequestManager::OpenHandler::open ( )

Future-based version of the handler If called while a file-open is in progress, we will not start a new file-open. Instead, the callback will be fired for the ongoing open.

NOTE NOTE: This function is not thread-safe due to a lock-ordering issue. The caller must ensure it is not called from multiple threads at once for this object.

Definition at line 1035 of file XrdRequestManager.cc.

References XrdAdaptor::RequestManager::addConnections(), cms::Exception::addContext(), TauDecayModes::dec, ecalTB2006H4_GenSimDigiReco_cfg::File, edm::errors::FileOpenError, edm::errors::LogicError, m_file, XrdAdaptor::RequestManager::m_flags, m_manager, m_mutex, XrdAdaptor::RequestManager::m_name, m_outstanding_open, XrdAdaptor::RequestManager::m_perms, m_promise, m_self, m_self_weak, m_shared_future, XrdAdaptor::RequestManager::prepareOpaqueString(), mps_update::status, and AlCaHLTBitMon_QueryRunRegistry::string.

1035  {
1036  auto manager_ptr = m_manager.lock();
1037  if (!manager_ptr) {
1039  ex << "XrdCl::File::Open() =>"
1040  << " error: OpenHandler called within an invalid RequestManager context."
1041  << " This is a logic error and should be reported to the CMSSW developers.";
1042  ex.addContext("Calling XrdAdaptor::RequestManager::OpenHandler::open()");
1043  throw ex;
1044  }
1045  RequestManager &manager = *manager_ptr;
1046  auto self_ptr = m_self_weak.lock();
1047  if (!self_ptr) {
1049  ex << "XrdCl::File::Open() => error: "
1050  << "OpenHandler called after it was deleted. This is a logic error "
1051  << "and should be reported to the CMSSW developers.";
1052  ex.addContext("Calling XrdAdapter::RequestManager::OpenHandler::open()");
1053  throw ex;
1054  }
1055 
1056  // NOTE NOTE: we look at this variable *without* the lock. This means the method
1057  // is not thread-safe; the caller is responsible to verify it is not called from
1058  // multiple threads simultaneously.
1059  //
1060  // This is done because ::open may be called from a Xrootd callback; if we
1061  // tried to hold m_mutex here, this object's callback may also be active, hold m_mutex,
1062  // and make a call into xrootd (when it invokes m_file.reset()). Hence, our callback
1063  // holds our mutex and attempts to grab an Xrootd mutex; RequestManager::requestFailure holds
1064  // an Xrootd mutex and tries to hold m_mutex. This is a classic deadlock.
1065  if (m_outstanding_open) {
1066  return m_shared_future;
1067  }
1068  std::lock_guard<std::recursive_mutex> sentry(m_mutex);
1069  std::promise<std::shared_ptr<Source>> new_promise;
1070  m_promise.swap(new_promise);
1071  m_shared_future = m_promise.get_future().share();
1072 
1073  auto opaque = manager.prepareOpaqueString();
1074  std::string new_name = manager.m_name + ((manager.m_name.find("?") == manager.m_name.npos) ? "?" : "&") + opaque;
1075  edm::LogVerbatim("XrdAdaptorInternal") << "Trying to open URL: " << new_name;
1076  m_file.reset(new XrdCl::File());
1077  m_outstanding_open = true;
1078 
1079  // Always make sure we release m_file and set m_outstanding_open to false on error.
1080  std::unique_ptr<OpenHandler, std::function<void(OpenHandler *)>> exit_guard(this, [&](OpenHandler *) {
1081  m_outstanding_open = false;
1082  m_file.reset();
1083  });
1084 
1085  XrdCl::XRootDStatus status;
1086  if (!(status = m_file->Open(new_name, manager.m_flags, manager.m_perms, this)).IsOK()) {
1088  ex << "XrdCl::File::Open(name='" << new_name << "', flags=0x" << std::hex << manager.m_flags << ", permissions=0"
1089  << std::oct << manager.m_perms << std::dec << ") => error '" << status.ToStr() << "' (errno=" << status.errNo
1090  << ", code=" << status.code << ")";
1091  ex.addContext("Calling XrdAdaptor::RequestManager::OpenHandler::open()");
1092  manager.addConnections(ex);
1093  throw ex;
1094  }
1095  exit_guard.release();
1096  // Have a strong self-reference for as long as the callback is in-progress.
1097  m_self = self_ptr;
1098  return m_shared_future;
1099 }
std::string prepareOpaqueString() const
OpenHandler(std::weak_ptr< RequestManager > manager)
std::shared_ptr< OpenHandler > m_self
std::weak_ptr< OpenHandler > m_self_weak
void addConnections(cms::Exception &) const
std::shared_future< std::shared_ptr< Source > > m_shared_future
std::weak_ptr< RequestManager > m_manager
XrdCl::OpenFlags::Flags m_flags
XrdCl::Access::Mode m_perms
std::unique_ptr< XrdCl::File > m_file
std::promise< std::shared_ptr< Source > > m_promise

Member Data Documentation

std::unique_ptr<XrdCl::File> XrdAdaptor::RequestManager::OpenHandler::m_file
private

Definition at line 286 of file XrdRequestManager.h.

Referenced by current_source(), HandleResponseWithHosts(), and open().

std::weak_ptr<RequestManager> XrdAdaptor::RequestManager::OpenHandler::m_manager
private

Definition at line 294 of file XrdRequestManager.h.

Referenced by HandleResponseWithHosts(), and open().

std::recursive_mutex XrdAdaptor::RequestManager::OpenHandler::m_mutex
private

Definition at line 287 of file XrdRequestManager.h.

Referenced by current_source(), HandleResponseWithHosts(), and open().

std::atomic<bool> XrdAdaptor::RequestManager::OpenHandler::m_outstanding_open {false}
private

Definition at line 284 of file XrdRequestManager.h.

Referenced by HandleResponseWithHosts(), and open().

std::promise<std::shared_ptr<Source> > XrdAdaptor::RequestManager::OpenHandler::m_promise
private

Definition at line 280 of file XrdRequestManager.h.

Referenced by HandleResponseWithHosts(), and open().

std::shared_ptr<OpenHandler> XrdAdaptor::RequestManager::OpenHandler::m_self
private

Definition at line 288 of file XrdRequestManager.h.

Referenced by HandleResponseWithHosts(), and open().

std::weak_ptr<OpenHandler> XrdAdaptor::RequestManager::OpenHandler::m_self_weak
private

Definition at line 293 of file XrdRequestManager.h.

Referenced by getInstance(), and open().

std::shared_future<std::shared_ptr<Source> > XrdAdaptor::RequestManager::OpenHandler::m_shared_future
private

Definition at line 279 of file XrdRequestManager.h.

Referenced by open().