11 #define ON_DEBUG if (msgLevel(MSG::DEBUG)) 12 #define ON_VERBOSE if (msgLevel(MSG::VERBOSE)) 25 void set_bit(
int& f,
const unsigned int& b) {
29 bool get_bit(
const int& f,
const unsigned int& b) {
35 constexpr
struct to_name_t {
40 constexpr
struct select1st_t {
41 template <
typename T,
typename S>
42 const T& operator()(
const std::pair<T,S>& p)
const {
return p.first; }
45 constexpr
struct select2nd_t {
46 template <
typename T,
typename S>
47 const S& operator()(
const std::pair<T,S>& p)
const {
return p.second; }
50 template <
typename InputIterator,
typename OutputIterator,
typename UnaryOperation,
typename UnaryPredicate>
51 OutputIterator transform_if( InputIterator first, InputIterator last,
52 OutputIterator result,
54 UnaryPredicate pred) {
55 while (first != last) {
56 if (pred(*first)) *result++ = op(*first);
62 template <
typename InputIterator,
typename OutputIterator,
typename UnaryOperation,
typename UnaryPredicate>
63 OutputIterator transform_copy_if( InputIterator first, InputIterator last,
64 OutputIterator result,
66 UnaryPredicate pred) {
67 while (first != last) {
93 debug() <<
"Failed to initialize the base class (Service)" 101 if (m_loadRootHandler.value()) {
105 msgSvc()->setOutputLevel(
"RootFileHandler", m_outputLevel.value());
108 auto rfh = m_rfh.get();
113 return rfh->openRootFile(n, f, desc, fd, ptr);
116 return rfh->closeRootFile(ptr);
119 return rfh->reopenRootFile(ptr, f);
122 if (regHandler(hdlr).isFailure()) {
124 <<
"unable to register ROOT file handler with FileMgr" 129 if (m_loadPosixHandler.value()) {
133 msgSvc()->setOutputLevel(
"POSIXFileHandler", m_outputLevel.value());
136 auto pfh = m_pfh.get();
141 return pfh->openPOSIXFile(n, f, desc, fd, ptr);
144 return pfh->closePOSIXFile(fd);
147 return pfh->reopenPOSIXFile(fd, f);
150 if (regHandler(hdlp).isFailure()) {
152 <<
"unable to register ROOT file handler with FileMgr" 179 if (!m_files.empty()) {
180 auto&
log = warning();
181 log <<
"At finalize, the following files remained open:" <<
endl;
182 for (
const auto& itr : m_files)
log << *(itr.second) << endl;
186 if (m_logfile.value() !=
"") {
188 ofs.
open(m_logfile.value().c_str());
190 error() <<
"Unable to open output file \"" << m_logfile.value()
195 debug() <<
"Saving log to \"" << m_logfile.value() <<
"\"" 197 for (
const auto& itr : m_files) {
198 ofs << itr.second->name() <<
" " << itr.second->tech() <<
" " 199 << itr.second->desc() <<
" " << itr.second->iflags() <<
endl;
203 for (
const auto& it2 : m_oldFiles) fs.
insert(*it2);
204 for (
const auto& it3 : fs ) {
205 ofs << it3.name() <<
" " << it3.tech() <<
" " << it3.desc()
206 <<
" " << it3.iflags()
207 << ( it3.isShared() ?
" SHARED" :
"" )
225 debug() <<
"Service finalised successfully" <<
endmsg;
245 if (m_handlers.find(tech) != m_handlers.end()) {
247 <<
"Handler for IoTech " << tech <<
" already registered. Ignoring." 254 <<
"open handler for tech " << tech <<
" is NULL" 261 <<
"no close handler for tech " << tech <<
" registered" 268 <<
"no reopen handler for tech " << tech <<
" registered" 276 <<
"Successfully registered handler for tech \"" << tech <<
"\"" 279 m_handlers[tech] = fh;
291 auto itr = m_handlers.find(tech);
292 if (itr == m_handlers.end()) {
293 error() <<
"Can't de-register tech " << tech
294 <<
" as it hasn't been registered!" 299 m_handlers.erase(itr);
308 auto itr = m_handlers.find(tech);
321 return open(tech, caller, fname, desc, flags, fd, ptr, sh);
333 return open(tech, caller, fname, desc, flags, fd, dummy, sh);
345 return open(tech, caller, fname, desc, flags, dummy, ptr, sh);
355 const IoFlags& flags,
Fd&
fd,
void*& ptr,
bool shared) {
374 verbose() <<
"open(" << tech <<
"," 376 <<
",\"" << fname <<
"\",\"" 379 << ( shared ?
",shared" :
",unshared")
385 if (getHandler(tech,fh).isFailure())
return r;
388 auto fitr = m_files.equal_range(fname);
392 auto itr =
std::find_if( fitr.first, fitr.second, [&](fileMap::const_reference i) { return i.second->tech()!=tech; } );
393 if (itr != fitr.second) {
394 error() <<
"when calling open on " << fname
395 <<
" with tech " << tech
396 <<
", file already opened with different tech " 397 << itr->second->tech()
408 bool shareable(
true);
410 for (
auto itr=fitr.first; itr != fitr.second; ++itr) {
413 if (! fa->
isShared()) shareable =
false;
416 if ( shareable && fa->
flags().
match(flags,
false) ) {
419 debug() <<
" found shared file: " 442 error() <<
"when calling open handler for " << tech
444 << fname <<
" caught " << err.
what() <<
endmsg;
447 error() <<
"when calling open handler for " << tech
449 << fname <<
" caught an unknown exception." <<
endmsg;
455 <<
"open of file \"" << fname <<
"\", tech: \"" << tech
456 <<
"\", flags: \"" << flags <<
"\" requested by " 458 <<
" failed. return code: " << r
461 FileAttr xfa(-1,fname,desc,tech,flags,0,
false);
475 debug() <<
"opened file " << *fa <<
endmsg;
478 if (
fd == -1 && ptr == 0) {
479 warning() <<
"when opening " << *fa <<
" both File Descriptor" 480 <<
" and File Ptr are invalid" <<
endmsg;
485 for (
auto itr = fitr.first; itr != fitr.second; ++itr) {
488 }
else if (*fa == *(itr->second) ) {
489 warning() <<
"open call for file \"" << fname
490 <<
"\" returned a pre-existing file with identical" 491 <<
" FileAttributes: " << *fa <<
endmsg;
494 warning() <<
"open call for file \"" << fname
495 <<
"\" returned a pre-existing file with different" 496 <<
" FileAttributes -" 497 <<
endl <<
"old: " << *(itr->second)
498 <<
endl <<
"new: " << *fa << endmsg;
503 m_files.emplace( fname,fa );
506 if (execAction( fa, caller,
Io::OPEN ).isFailure()) {
508 <<
"at least one open callback action failed" 536 [&](fileMap::const_reference i) {
return i.second->fd() ==
fd; } );
540 error() <<
"unknown file descriptor \"" <<
fd 541 <<
"\" when calling close()" 547 IoTech tech = itr->second->tech();
551 if (getHandler(tech,fh).isFailure()) {
556 error() <<
"no close(" << tech <<
",Fd) function registered" 564 auto fitr = m_files.equal_range(fa->
name());
565 int i =
std::count_if(fitr.first, fitr.second, [&](fileMap::const_reference f) {
566 return f.second->fd()==fd; } );
569 verbose() <<
" ref count: " << i
576 debug() <<
"closing file " << fa->
name() <<
" opened " 577 << i <<
" times with Fd " <<
fd <<
endmsg;
582 }
else if (i == 1 || (i>1 && !fa->
isShared()) ) {
584 debug() <<
"closing " << *fa <<
endmsg;
590 error() <<
"when calling close handler for " << tech
591 <<
" on file descriptor " 596 error() <<
"when calling close handler for " << tech
597 <<
" on file descriptor " 598 <<
fd <<
" caught an unknown exception." <<
endmsg;
605 <<
"close of file with FD \"" <<
fd 606 <<
"\", name: \"" << fa->
name()
607 <<
"\", tech: \"" << tech <<
"\" failed" 620 <<
"ref count < 0 when closing " << fa
621 <<
". This should never happen" 631 m_oldFiles.push_back( fa );
635 if (execAction(fa, caller,
Io::CLOSE).isFailure()) {
637 <<
"at least one close callback action failed" 657 verbose() <<
"close(" << vp <<
")" 663 [&](fileMap::const_reference i ) {
return i.second->fptr()==vp; } );
665 if (itr == m_files.end()) {
666 error() <<
"unknown file ptr \"" << vp
667 <<
"\" when calling close()" 672 IoTech tech = itr->second->tech();
676 if (getHandler(tech,fh).isFailure()) {
680 error() <<
"no close(" << tech <<
",void*) function registered" 689 m_files.equal_range(fa->
name());
691 int i =
std::count_if( fitr.first, fitr.second, [&](fileMap::const_reference f)
692 { return f.second->fptr()==vp; } );
695 verbose() <<
" ref count: " << i
701 debug() <<
"closing file " << fa->
name() <<
" opened " 702 << i <<
" times with fptr " << vp <<
endmsg;
707 }
else if (i == 1 || (i>1 && !fa->
isShared()) ) {
709 debug() <<
"closing: " << *fa <<
endmsg;
714 error() <<
"when calling close handler for " << tech
715 <<
" on file " << fa->
name()
717 execAction(fa, caller,
CLOSE_ERR ).ignore();
720 error() <<
"when calling close handler for " << tech
721 <<
" on file " << fa->
name()
722 <<
" caught an unknown exception." <<
endmsg;
723 execAction(fa, caller,
CLOSE_ERR ).ignore();
729 <<
"close of file with ptr \"" << vp
730 <<
"\", name: \"" << fa->
name()
731 <<
"\", tech: \"" << tech <<
"\" failed" 742 <<
"ref count: " << i <<
" < 0 when closing " << fa
743 <<
". This should never happen" 753 m_oldFiles.push_back( fa );
757 if (execAction(fa, caller,
CLOSE).isFailure()) {
759 <<
"at least one close callback action failed" 773 verbose() <<
"reopen(" <<
fd <<
"," << flags
774 <<
"," << caller <<
")" 781 {
return f.second->fd() ==
fd; } );
783 if (itr == m_files.end()) {
784 error() <<
"unregistered FD \"" <<
fd 785 <<
"\" when calling reopen()" 795 if (getHandler(tech,fh).isFailure()) {
802 error() <<
"no reopen(" << tech <<
",Fd) function registered" 813 error() <<
"when calling reopen handler for " << tech
814 <<
" on file descriptor " <<
fd <<
" with flags " 819 error() <<
"when calling reopen handler for " << tech
820 <<
" on file descriptor " <<
fd <<
" with flags " 822 <<
" caught an unknown exception." <<
endmsg;
828 <<
"reopen of file with FD \"" <<
fd 829 <<
"\", name: \"" << fa->
name()
830 <<
"\", tech: \"" << tech
831 <<
"\", flags: \"" << flags <<
"\" failed" 844 if (execAction(fa, caller,
Io::REOPEN).isFailure()) {
846 <<
"at least one reopen callback action failed" 859 verbose() <<
"reopen(" << vp <<
"," << flags
860 <<
"," << caller <<
")" 866 [&](fileMap::const_reference f) {
867 return f.second->fptr() == vp ; } );
868 if (itr == m_files.end()) {
870 <<
"unregistered file ptr \"" << vp
871 <<
"\" when calling reopen()" 880 if (getHandler(tech,fh).isFailure()) {
885 error() <<
"no reopen(" << tech <<
",void*) function registered" 893 error() <<
"when calling reopen handler for " << tech
894 <<
" on file " << fa->
name() <<
" with flags " 899 error() <<
"when calling reopen handler for " << tech
900 <<
" on file " << fa->
name() <<
" with flags " 902 <<
" caught an unknown exception." <<
endmsg;
908 <<
"reopen of file with ptr \"" << vp
909 <<
"\", name: \"" << fa->
name()
910 <<
"\", tech: \"" << tech
911 <<
"\", flags: \"" << flags <<
"\" failed" 924 if (execAction(fa, caller,
Io::REOPEN).isFailure()) {
926 <<
"at least one reopen callback action failed" 941 auto fitr = m_files.equal_range(fname);
957 [&](fileMap::const_reference f ) {
return f.second->fd() ==
fd; } );
980 [&](fileMap::const_reference f) {
return f.second->fptr() == vp; } );
1013 return files.
size();
1027 return files.
size();
1036 if (tech ==
UNKNOWN)
return getFiles(files,op);
1041 [&](fileMap::const_reference f) {
return f.second->tech() == tech &&
1050 return files.
size();
1060 if (tech ==
UNKNOWN)
return getFiles(files,op);
1062 auto matches_tech = [&](
const FileAttr* f) {
return f->tech()==tech; } ;
1066 select2nd, matches_tech );
1072 return files.
size();
1086 auto matches_tech_and_flags = [&](
const FileAttr* f) {
return ( f->tech() == tech || tech ==
UNKNOWN ) && f->flags() == flags ; } ;
1090 [&](fileMap::const_reference f) {
return matches_tech_and_flags( f.second ) && not_in_files( f.first ); } );
1094 [&](
const FileAttr* f) {
return matches_tech_and_flags(f) && not_in_files(f->
name()); } );
1097 return files.
size();
1108 auto matches_tech_and_flags = [&](
const FileAttr* f) {
return ( f->tech() == tech || tech ==
UNKNOWN )
1109 && f->
flags() == flags ; } ;
1113 matches_tech_and_flags );
1116 matches_tech_and_flags );
1119 return files.
size();
1132 return m_descriptors.size();
1144 if (tech ==
UNKNOWN)
return getFd( fd );
1163 transform_if( m_descriptors.begin(), m_descriptors.end(),
1166 return (d.second->tech() == tech || tech ==
UNKNOWN) &&
1167 ( d.second->flags() == flags );
1178 [&](fileMap::const_reference f) {
return f.second->fd() ==
fd; } );
1179 return (itr!=
std::end(m_files)) ? itr->second->name() : s_empty;
1188 auto itr =
std::find_if( m_files.begin(), m_files.end(),
1189 [&](fileMap::const_reference f) {
1190 return f.second->fptr() == vp;
1192 return itr!=m_files.end() ? itr->second->name() : s_empty;
1200 auto fitr = m_files.equal_range(fname);
1201 auto itr =
std::find_if( fitr.first, fitr.second, [](fileMap::const_reference f) {
1202 return f.second->fd() != -1;
1204 return itr!=fitr.second ? itr->second->fd() : -1 ;
1212 auto itr =
std::find_if(m_files.begin(),m_files.end(),[&](fileMap::const_reference f) {
1213 return f.second->fptr() == fptr;
1215 return itr!=m_files.end() ? itr->second->fd() : -1 ;
1222 auto fitr = m_files.equal_range(fname);
1223 auto itr =
std::find_if( fitr.first, fitr.second, [](fileMap::const_reference f) ->
bool {
1224 return f.second->fptr();
1226 return itr!=fitr.second ? itr->second->fptr() :
nullptr;
1234 auto itr =
std::find_if(m_files.begin(),m_files.end(),[&](fileMap::const_reference f) {
1235 return f.second->fd() ==
fd;
1237 return itr!=m_files.end() ? itr->second->fptr() :
nullptr;
1245 info() <<
"listing registered files [" 1246 << (m_files.size() + m_oldFiles.size() )
1249 for (
auto& itr : m_files ) info() << itr.second <<
endl;
1250 for (
auto& it2 : m_oldFiles ) info() << *it2 <<
endl;
1270 auto itr = m_handlers.find(tech);
1271 if (itr == m_handlers.end()) {
1273 <<
"no handler for tech " << tech <<
" registered" 1286 auto fitr = m_files.equal_range(fname);
1287 if (fitr.first == fitr.second) {
1289 <<
"no file \"" << fname <<
"\" registered. Cannot determine tech" 1294 auto itr = fitr.first;
1295 IoTech tech = itr->second->tech();
1298 while( itr != fitr.second ) {
1299 if ( itr->second->tech() != tech ) {
1301 <<
"multiple technologies registered for file \"" << fname
1302 <<
"\". Cannot determine handler" <<
endmsg;
1308 return getHandler(tech,hdlr);
1318 <<
"Listing registered handlers:" <<
endl;
1320 for (
const auto& itr : m_handlers ) info() <<
" " << itr.first <<
endl;
1341 debug() <<
"registering " << a <<
" action " 1343 <<
" for tech " << t <<
endmsg;
1345 m_actions[t][a].emplace_back(bf, (!d.
empty()) ? d
1356 info() <<
"listing registered actions" <<
endl;
1358 for (
const auto& iit : m_actions) {
1363 info() <<
" --- Tech: ";
1365 info() <<
"ALL ---" <<
endl;
1367 info() << t <<
" ---" <<
endl;
1369 for (
const auto& iia : m ) {
1370 for (
const auto& it2 : iia.second ) {
1371 info() <<
" " << iia.first <<
" " 1372 << it2.second <<
endl;
1392 if (itr != m_actions.end() && !itr->second.empty() ) {
1393 s1 = execActs(fa, caller, a, itr->second);
1396 itr = m_actions.find(tech);
1397 if (itr != m_actions.end() && !itr->second.empty() ) {
1398 s2 = execActs(fa, caller, a, itr->second);
1411 auto mitr = m.
find(a);
1413 if (mitr == m.
end() || mitr->second.empty()) {
1419 <<
"executing " << mitr->second.size() <<
" " << a
1428 auto it2 = m_supMap.find(fa->
name());
1429 if (it2 != m_supMap.end()) {
1432 debug() <<
" --> suppressing callback action for " 1439 for (
const auto& itr : mitr->second ) {
1442 debug() <<
"executing " 1445 if ( (((itr.first))(fa,caller)).isFailure() ) {
1446 warning() <<
"execution of " 1447 << itr.second <<
" on " << *fa
1448 <<
" failed during " << a <<
" action" 1466 verbose() <<
"accessMatch old: " << fold
1471 ( (fold &
Io::WRITE) != 0 && (fnew & Io::WRITE) != 0) ||
1472 ( (fold &
Io::RDWR) != 0 && (fnew & Io::RDWR) != 0) ) ;
1490 auto it2 = m_supMap.find(f);
1491 if (it2 == m_supMap.end()) {
1496 set_bit(it2->second, a);
1506 if (m_supMap.empty())
return;
1508 info() <<
"listing suppressed file actions" <<
endl;
1510 for (
auto it2=m_supMap.begin(); it2 != m_supMap.end(); ++it2) {
1511 info() <<
" " << it2->first;
1513 info() <<
" ALL" <<
endl;
1516 if (get_bit(it2->second,i)) { info() <<
" " << (
Io::Action)i; }
StatusCode regHandler(FileHdlr) override
void listHandlers() const override
StatusCode initialize() override
int getFileAttr(const std::string &, std::vector< const FileAttr * > &) const override
void listFiles() const override
StatusCode finalize() override
StatusCode hasHandler(const IoTech &) const override
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
Io::open_t open(const Io::IoTech &, const std::string &caller, const std::string &fname, const Io::IoFlags &, Io::Fd &fd, void *&ptr, const std::string &desc="", const bool shared=false) override
bfcn_reopen_t b_reopen_fcn
void suppressAction(const std::string &) override
bool isSuccess() const
Test for a status code of SUCCESS.
int getFiles(std::vector< std::string > &, bool onlyOpen=true) const override
StatusCode deregHandler(const IoTech &) override
StatusCode execAction(Io::FileAttr *, const std::string &, const Io::Action &) const
bool isFailure() const
Test for a status code of FAILURE.
bool accessMatch(const Io::IoFlags &, const Io::IoFlags &, bool strict=false) const
virtual void listActions() const
Io::Fd fd(const std::string &) const override
const std::string & name() const
void handle(const Incident &) override
StatusCode getHandler(const IoTech &, FileHdlr &) const override
This class is used for returning status codes from appropriate routines.
Io::reopen_t reopen(const Fd, const IoFlags &, const std::string &caller) override
StatusCode execActs(Io::FileAttr *, const std::string &, const Io::Action &, const actionMap &m) const
bfcn_closeP_t b_closeP_fcn
Io::close_t close(const Fd, const std::string &caller) override
bfcn_reopenP_t b_reopenP_fcn
#define DECLARE_SERVICE_FACTORY(x)
StatusCode regAction(Io::bfcn_action_t, const Io::Action &, const std::string &desc="") override
virtual void listSuppression() const
bool match(const IoFlags &fa, bool strict=true) const
T back_inserter(T...args)
Base class for all Incidents (computing events).
const std::string & fname(const Io::Fd &) const override
int getFd(std::vector< Fd > &) const override
StatusCode finalize() override
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
StatusCode initialize() override
int getLastError(std::string &) const override
void * fptr(const std::string &) const override