18 #include "GaudiKernel/ISvcLocator.h"
19 #include "GaudiKernel/IIncidentSvc.h"
20 #include "GaudiKernel/Incident.h"
21 #include "GaudiKernel/IAlgTool.h"
22 #include "GaudiKernel/IToolSvc.h"
23 #include "GaudiKernel/IClassIDSvc.h"
24 #include "GaudiKernel/Guards.h"
25 #include "GaudiKernel/ConcurrencyFlags.h"
50 const char *cstr =
str.c_str();
52 for (
unsigned int i=0;
i <
str.length(); ++
i) {
53 str2 += toupper(*(cstr+
i));
60 std::atomic<bool> s_firstRun(
true);
75 if (
x->clID() ==
y->clID() ) {
76 return (
x->name() <
y->name() );
78 return (
x->clID() <
y->clID() );
90 if (
a->name()!=
b->name())
return a->name()<
b->name();
91 if (
a->clID()!=
b->clID())
return a->clID()<
b->clID();
104 const IInterface*
parent):
106 m_storeName(
"StoreGateSvc"),
107 p_cndSvc(
"DetectorStore",
name),
108 p_incSvc(
"IncidentSvc",
name), p_PPSvc(
"ProxyProviderSvc",
name),
109 p_CLIDSvc(
"ClassIDSvc",
name), p_toolSvc(
"ToolSvc",
name),
130 delete ( oitr->second );
140 std::set< const TransientAddress*, SortTADptr >::const_iterator titr;
155 SmartIF<IProperty> iovSvcProp{service(
"IOVSvc")};
158 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"preLoadRanges") ) );
159 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"preLoadData") ) );
160 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"partialPreLoadData") ) );
161 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"preLoadExtensibleFolders") ) );
162 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"updateInterval") ) );
163 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"sortKeys") ) );
164 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"forceResetAtBeginRun") ) );
165 ATH_CHECK( setProperty( iovSvcProp->getProperty(
"OutputLevel") ) );
174 p_incSvc->addListener(
this,
"BeginRun", pri,
true);
177 msg() <<
"IOVRanges will be checked only ";
178 msg().setColor(MSG::CYAN);
181 msg() <<
" at the start of the job" <<
endmsg;
182 }
else if (updi ==
"RUN") {
184 p_incSvc->addListener(
this,
"BeginRun", pri,
true);
187 msg() <<
"IOVRanges will be checked at every ";
188 msg().setColor(MSG::CYAN);
190 }
else if (updi ==
"EVENT") {
192 p_incSvc->addListener(
this,
"BeginEvent", pri,
true);
193 p_incSvc->addListener(
this,
"BeginRun", pri,
true);
196 msg() <<
"IOVRanges will be checked at every ";
197 msg().setColor(MSG::CYAN);
201 <<
"\"event\" \"run\" or \"job\"");
202 return StatusCode::FAILURE;
208 msg() <<
"IOV Data will be preloaded at the same interval" <<
endmsg;
213 return StatusCode::SUCCESS;
230 else if (!initial_first) {
231 if ( inc.type() !=
m_checkTrigger && inc.type() != IncidentType::BeginRun ) {
236 std::lock_guard<std::recursive_mutex>
lock(m_handleMutex);
243 if ( inc.type() !=
m_checkTrigger && inc.type() != IncidentType::BeginRun ) {
252 if (
proxy ==
nullptr) {
266 const bool first = initial_first;
269 if(Gaudi::Concurrency::ConcurrencyFlags::numProcs()==0) {
270 if (inc.type() == IncidentType::BeginRun) {
282 set< DataProxy*, SortDPptr > proxiesToReset;
283 if ( inc.type() ==
m_checkTrigger || inc.type() == IncidentType::BeginRun ) {
285 const EventContext& context = inc.context();
289 const EventIDBase& eventID = context.eventID();
290 uint32_t event = eventID.lumi_block();
297 curTime.setTimestamp(1000000000
L*(
uint64_t)eventID.time_stamp() + eventID.time_stamp_ns_offset());
301 msg() << inc.type() <<
": [R/LB] = " << curTime <<
endmsg;
304 if (inc.type() == IncidentType::BeginRun) {
306 SmartIF<IIOVDbSvc> iovDB{service(
"IOVDbSvc",
false)};
311 if (StatusCode::SUCCESS != iovDB->signalBeginRun(curTime,
324 std::set< const TransientAddress*, SortTADptr >::const_iterator titr;
328 if (StatusCode::SUCCESS !=
sc) {
348 throw( std::runtime_error(
"IOVSvcTool::preLoadProxies") );
352 SmartIF<IIOVDbSvc> iovDB{service(
"IOVDbSvc",
false)};
354 iovDB->signalEndProxyPreload();
355 ATH_MSG_DEBUG(
"Signaled end proxy preload to IOVDbSvc " << curTime);
373 std::map<BFCN*, std::list<std::string> > resetKeys;
380 if (inc.type() == IncidentType::BeginRun &&
m_forceReset && !s_firstRun) {
382 ATH_MSG_DEBUG(
"Resetting all proxies on BeginRun incident for store \""
386 std::set< const SG::DataProxy* >::const_iterator pit;
403 auto itr = proxiesToReset.find(
p);
404 if (itr != proxiesToReset.end()) {
405 proxiesToReset.erase( itr );
410 if (!
first && proxiesToReset.size() > 0 &&
412 Gaudi::Concurrency::ConcurrencyFlags::numConcurrentEvents()) > 0 ) ) {
413 ATH_MSG_FATAL(
"Cannot update Conditions via callback functions in MT after the first event");
414 for (
const auto* prox : proxiesToReset) {
415 ATH_MSG_FATAL(
"CLID=" << prox->clID() <<
", name=" << prox->name());
417 throw GaudiException(
"Cannot update Conditions via callback functions in MT after the first event",
name(),StatusCode::FAILURE);
441 Gaudi::Guards::AuditorGuard auditor(
m_names.at(prx), auditorSvc(),
"preLoadProxy");
442 if (prx->accessData() ==
nullptr) {
447 std::list<std::string>
keys;
448 pair<pmITR,pmITR> fitr =
m_proxyMap.equal_range( prx );
449 for (
pmITR p=fitr.first;
p!=fitr.second; ++
p) {
451 std::string
key = prx->name();
452 resetKeys[
f].push_back(
key);
465 CBTree::nodeSet::const_iterator itt, itt_s, itt_e;
467 for (itt = itt_s; itt != itt_e; ++itt) {
470 if (
node->trigger()) {
472 auditorSvc()->before(
"Callback",
m_fcnMap.at(
ff).name(),inc.context());
473 if ((*
ff)(
i,resetKeys[
ff]).isFailure()) {
474 auditorSvc()->after(
"Callback",
m_fcnMap.at(
ff).name(),inc.context());
476 << std::endl <<
"Skipping all subsequent callbacks.");
481 auditorSvc()->after(
"Callback",
m_fcnMap.at(
ff).name(),inc.context());
484 if (
perr !=
nullptr)
break;
508 if ( pitr !=
m_entries.end() && pitr->second->range()->isInRange(curTime) ) {
512 if (!prx->updateAddress()) {
520 IOpaqueAddress *ioa = prx->address();
524 if (iova !=
nullptr) {
535 if ( inc.type() == IncidentType::BeginRun) {
550 if (
proxy ==
nullptr) {
552 return StatusCode::FAILURE;
559 <<
" already registered: " <<
proxy->name());
560 return StatusCode::SUCCESS;
563 std::string tname, fullname;
566 fullname = tname +
"[" +
key +
"]";
573 return StatusCode::SUCCESS;
587 if (
proxy ==
nullptr) {
589 return StatusCode::FAILURE;
597 <<
" not registered: " <<
proxy->name());
598 return StatusCode::SUCCESS;
605 return StatusCode::SUCCESS;
617 while (
it !=
set.end() && !
set.key_comp()(*
it, ent) && !
set.key_comp()(ent,*
it)) {
636 std::lock_guard<std::recursive_mutex>
lock(m_handleMutex);
637 assert(
nullptr != pOld);
638 assert(
nullptr != pNew);
648 return StatusCode::SUCCESS;
667 setRange_impl (pNew, *(
const_cast<IOVRange*
>(ent->second->range())));
674 StatusCode::SUCCESS :
675 StatusCode::FAILURE );
688 if (
proxy ==
nullptr) {
691 return StatusCode::FAILURE;
708 if (
proxy ==
nullptr) {
711 return StatusCode::FAILURE;
729 << tad_in->
clID() <<
"/" << tad_in->
name()
730 <<
") alread in preLoad set. Not inserting");
731 return StatusCode::SUCCESS;
737 << tad_in->
clID() <<
"/" << tad_in->
name()
738 <<
") alread in partPreLoad set. Not inserting");
739 return StatusCode::SUCCESS;
745 return StatusCode::SUCCESS;
759 <<
" alread in preLoad set. Not inserting");
760 return StatusCode::SUCCESS;
766 <<
" alread in partPreLoad set. Not inserting");
767 return StatusCode::SUCCESS;
774 return StatusCode::SUCCESS;
781 if (iovr.start().isTimestamp()) {
789 IOVRange *
range =
new IOVRange(iovr);
795 const IOVRange *irn = ent->
range();
836 <<
" in IOVrange:" << iovr);
838 if (!iovr.start().isValid() || !iovr.stop().isValid()) {
839 ATH_MSG_ERROR(
"IOVRange " << iovr <<
"is not valid. Start OK: "
840 << iovr.start().isValid() <<
" Stop OK: " << iovr.stop().isValid()
841 <<
" run/evt/time min/max "
845 return StatusCode::FAILURE;
850 if (
proxy ==
nullptr) {
852 return StatusCode::FAILURE;
855 std::lock_guard<std::recursive_mutex>
lock(m_handleMutex);
857 return StatusCode::SUCCESS;
863 IOVRange&
iov)
const {
867 std::lock_guard<std::recursive_mutex>
lock(m_handleMutex);
868 std::map<const DataProxy*,IOVEntry*>::const_iterator itr(
m_entries.find(
dp));
870 return StatusCode::FAILURE;
873 iov = *(itr->second->range());
875 return StatusCode::SUCCESS;
884 std::unique_ptr<IOpaqueAddress>& ioa,
885 const IOVTime& curTime)
const {
887 if (curTime.isValid()) {
891 return StatusCode::FAILURE;
902 std::unique_ptr<IOpaqueAddress>& ioa)
const {
908 if (
idb !=
nullptr) {
923 const IOVRange&
range,
const std::string &
tag) {
926 if (!
range.start().isValid() || !
range.stop().isValid()) {
928 return StatusCode::FAILURE;
935 return StatusCode::FAILURE;
938 std::lock_guard<std::recursive_mutex>
lock(m_handleMutex);
939 std::map<const DataProxy*,IOVEntry*>::const_iterator itr(
m_entries.find(
dp));
947 if (
idb !=
nullptr) {
951 return StatusCode::FAILURE;
965 SmartIF<IIOVDbSvc> iovDB{service(
"IOVDbSvc",
false)};
967 std::map<BFCN*, std::list<std::string> > resetKeys;
969 Gaudi::Guards::AuditorGuard auditor(
m_names[
dp], auditorSvc(),
"preLoadProxy");
972 msg().setColor(MSG::CYAN);
973 msg() <<
"loading proxy for CLID: " <<
dp->clID()
977 if (
dp->provider() ==
nullptr) {
979 <<
". It is probably not a conditions object" << endl;
980 msg() <<
"Proxy Map: ";
983 scr = StatusCode::FAILURE;
994 if (!
dp->updateAddress())
995 sc = StatusCode::FAILURE;
1004 iovDB->getKeyInfo(
dp->name(), kinfo) && kinfo.
extensible ) {
1009 <<
dp->clID() <<
"/"
1010 <<
dp->name() <<
")");
1011 if(
dp->accessData() !=
nullptr ) {
1012 sc = StatusCode::SUCCESS;
1014 sc = StatusCode::FAILURE;
1015 ATH_MSG_ERROR(
"preLoading proxies: accessData() failed for " <<
1016 dp->clID() <<
"/" <<
dp->name() <<
")");
1021 if (
sc.isFailure()) scr=
sc;
1026 for (pitr=
pi.first; pitr!=
pi.second; ++pitr) {
1027 BFCN *
f = pitr->second;
1028 std::string
key =
dp->name();
1029 resetKeys[
f].push_back(
key);
1033 if (cn !=
nullptr) {
1039 if (scr.isFailure()) {
1040 ATH_MSG_ERROR(
"Problems preLoading proxies. No callbacks triggered.");
1046 CBTree::nodeSet::const_iterator itt, itt_s, itt_e;
1048 for (itt = itt_s; itt != itt_e; ++itt) {
1051 if (
node->trigger()) {
1055 if ((*
ff)(
i,resetKeys[
ff]).isFailure()) {
1058 return StatusCode::FAILURE;
1079 std::list<std::string> klist;
1080 klist.push_back(
key);
1081 if ( (*fcn)(
I,klist).isFailure() ) {
1083 return StatusCode::FAILURE;
1086 return StatusCode::SUCCESS;
1093 const std::string&
key ) {
1097 std::map<const SG::DataProxy*, BFCN*>::const_iterator pitr =
1101 return StatusCode::FAILURE;
1104 BFCN* fcn = pitr->second;
1115 std::string objname;
1118 msg() << endl <<
"ClockTime start set: " << endl;
1120 objname =
m_names.at( (*start_itr)->proxy() );
1121 msg() <<
" " << objname <<
" (" << (*start_itr)->proxy() <<
") "
1122 << (*start_itr)->range()->start() << endl;
1128 msg() <<
"Run/Event start set: " << endl;
1130 objname =
m_names.at( (*start_itr)->proxy() );
1131 msg() <<
" " << objname <<
" (" << (*start_itr)->proxy() <<
") "
1132 << (*start_itr)->range()->start() << endl;
1143 std::string objname;
1146 msg() << endl <<
"ClockTime stop set: " << endl;
1148 objname =
m_names.at((*stop_itr)->proxy());
1149 msg() <<
" " << objname <<
" (" << (*stop_itr)->proxy() <<
") "
1150 << (*stop_itr)->range()->stop() << endl;
1156 msg() <<
"Run/Event stop set: " << endl;
1158 objname =
m_names.at((*stop_itr)->proxy());
1159 msg() <<
" " << objname <<
" (" << (*stop_itr)->proxy() <<
") "
1160 << (*stop_itr)->range()->stop() << endl;
1170 msg() <<
"------------------------------ IOVSvc Proxy Map "
1171 <<
"------------------------------" << endl;
1176 msg() <<
"----------------------------------------------------------"
1177 <<
"---------------------" << endl;
1185 msg() <<
" " <<
dp <<
" " <<
dp->clID() <<
" "
1188 if (
pi.first ==
pi.second) {
1189 msg() <<
" -> no callback associated" << endl;
1191 for (
auto pitr=
pi.first; pitr!=
pi.second; ++pitr) {
1192 BFCN* fcn = pitr->second;
1193 map<BFCN*,CallBackID>::const_iterator fitr =
m_fcnMap.find(fcn);
1196 msg() <<
" -> " << fcn <<
" " << cbid.
name() << endl;
1211 std::string tname,fullname;
1213 if (
sc.isFailure()) {
1215 return StatusCode::FAILURE;
1217 fullname = tname +
"[" +
dp->name() +
"]";
1222 <<
" with DataHandle " << fullname
1223 <<
" -> Need to bind DataHandle first");
1224 return StatusCode::FAILURE;
1231 std::pair<pmITR,pmITR> fitr =
m_proxyMap.equal_range(
dp );
1232 for (
pmITR p=fitr.first;
p!=fitr.second; ++
p) {
1235 <<
" already registered against " << fullname);
1236 return StatusCode::FAILURE;
1245 obs =
new BFCN(fcn);
1252 m_proxyMap.insert(std::pair<const SG::DataProxy*,BFCN* >(
dp,obs));
1253 m_bfcnMap.insert(std::pair<BFCN*, const SG::DataProxy*> (obs,
dp));
1256 ObjMap::const_iterator oitr =
m_objMap.find(
c.ptr());
1258 oitr->second->insert(
c);
1260 std::set<CallBackID> *cbs =
new std::set<CallBackID>;
1267 if ( cn ==
nullptr) {
1274 ATH_MSG_ERROR(
"Cannot find callback node for parent DataProxy "
1278 ATH_MSG_DEBUG(
"register by " <<
c.name() <<
" bound to " << fullname);
1282 ATH_MSG_INFO(
"Still in initialize phase, not tiggering callback for "
1283 <<
c.name() <<
" bound to " << fullname);
1289 return StatusCode::SUCCESS;
1302 std::set<const SG::DataProxy*> proxyset;
1306 std::pair<fnITR,fnITR> fi1 =
m_bfcnMap.equal_range( obs1 );
1307 for (
fnITR fitr1= fi1.first; fitr1!=fi1.second; ++fitr1) {
1310 std::pair<fnITR,fnITR> fi2 =
m_bfcnMap.equal_range( obs2 );
1311 for (
fnITR fitr2=fi2.first; fitr2!=fi2.second; ++fitr2) {
1316 <<
" cannot be registered since it has already been registered "
1317 <<
"against " <<
m_names[prx1]);
1319 proxyset.insert(prx1);
1324 obs2 =
new BFCN( fcn2 );
1329 std::pair<fnITR,fnITR> fi1 =
m_bfcnMap.equal_range( obs1 );
1330 for(
fnITR fitr1=fi1.first; fitr1!=fi1.second; ++fitr1) {
1332 proxyset.insert(prx1);
1336 if (proxyset.size() == 0) {
1338 <<
" cannot be registered, since it has already been registered"
1339 <<
" against everything it can be.");
1340 return StatusCode::SUCCESS;
1344 ObjMap::const_iterator oitr =
m_objMap.find(
c2.ptr());
1346 oitr->second->insert(
c2);
1348 std::set<CallBackID> *cbs =
new std::set<CallBackID>;
1355 std::list<std::string> klist;
1356 for (pitr=proxyset.begin(); pitr!=proxyset.end(); ++pitr) {
1358 m_proxyMap.insert(std::pair<const SG::DataProxy*,BFCN* >(prx,obs2));
1359 m_bfcnMap.insert(std::pair<BFCN*,const SG::DataProxy*>(obs2,prx));
1362 klist.push_back( prx->name() );
1369 if ( cn ==
nullptr) {
1373 if (
cp ==
nullptr) {
1375 <<
". This should never happen");
1376 return StatusCode::FAILURE;
1384 ATH_MSG_INFO(
"Still in initialize phase, not tiggering callback for "
1385 <<
c2.name() <<
" bound to " << *klist.begin());
1391 return StatusCode::SUCCESS;
1402 ObjMap::const_iterator oitr =
m_objMap.find( ia );
1406 ATH_MSG_ERROR(
"No callback registered with AlgTool " << ia->name());
1407 return StatusCode::FAILURE;
1410 std::set<CallBackID> *
sc = oitr->second;
1412 if (
sc->size() == 1) {
1416 return regFcn(cb,
c2, fcn2, trigger);
1420 ATH_MSG_ERROR(
"More than one callback registered to AlgTool "
1421 << ia->name() <<
". Found : " <<
sc->size());
1422 return StatusCode::FAILURE;
1432 std::set<std::string>&
tools) {
1436 if (
key == pitr->first->name()) {
1442 return ( (
match) ? StatusCode::SUCCESS : StatusCode::FAILURE );
1452 return (StatusCode::SUCCESS);
1459 std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
1460 const IOVTime& curTime)
const {
1462 if (pSet.begin()==pSet.end())
return;
1468 startITR start_itr( pSet.begin() );
1469 while ( start_itr != pSet.end() ) {
1473 msg() <<
"\t" <<
m_names.at((*start_itr)->proxy()) <<
": "
1474 << (*start_itr)->range()->start()<<
" <- removed"<<endl;
1476 proxiesToReset.insert( (*start_itr)->proxy() );
1478 (*start_itr)->setRemovedStart(
true );
1479 pSet.erase(start_itr++);
1496 std::set<SG::DataProxy*, SortDPptr> &proxiesToReset,
1497 const IOVTime& curTime)
const {
1499 if (pSet.begin()==pSet.end())
return;
1504 stopITR stop_itr(pSet.begin());
1505 while ( stop_itr != pSet.end() ) {
1509 msg() <<
" " <<
m_names.at((*stop_itr)->proxy()) <<
": "
1510 << (*stop_itr)->range()->stop()<<
" -> removed"<<endl;
1512 proxiesToReset.insert( (*stop_itr)->proxy() );
1514 (*stop_itr)->setRemovedStop(
true );
1515 pSet.erase(stop_itr++);
1543 if (
proxy ==
nullptr) {
1567 ObjMap::const_iterator oitr =
m_objMap.find( ia );
1610 std::string fullname, tname;
1611 if (
p_CLIDSvc->getTypeNameOfID( clid, tname ).isFailure()) {