5 #include "GaudiKernel/ISvcLocator.h"
6 #include "GaudiKernel/IJobOptionsSvc.h"
11 #define ON_DEBUG if (UNLIKELY(outputLevel() <= MSG::DEBUG))
12 #define ON_VERBOSE if (UNLIKELY(outputLevel() <= MSG::VERBOSE))
25 void set_bit(
int& f,
const unsigned int& b) {
29 bool get_bit(
const int& f,
const unsigned int& b) {
33 static const std::string s_empty =
"";
35 constexpr
struct to_name_t {
36 std::string operator()(
const FileAttr* f)
const {
return f->
name(); }
37 std::string operator()(
const std::pair<std::string, FileAttr*>& f)
const {
return f.first; }
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) {
69 if (pred(t)) *result++ = std::move(t);
88 declareProperty(
"TSSL_UserProxy",
m_ssl_proxy=
"X509");
89 declareProperty(
"TSSL_CertDir",
m_ssl_cert=
"X509");
110 auto jos = serviceLocator()->service<
IJobOptionsSvc>(
"JobOptionsSvc", true );
111 const auto *props = ( jos ? jos->getProperties(
name() ) : nullptr );
115 return p->
name() ==
"OutputLevel";
141 msgSvc()->setOutputLevel(
"RootFileHandler", m_outputLevel.value());
144 auto rfh =
m_rfh.get();
147 const std::string& desc,
Io::Fd&
fd,
149 return rfh->openRootFile(n, f, desc, fd, ptr);
152 return rfh->closeRootFile(ptr);
155 return rfh->reopenRootFile(ptr, f);
160 <<
"unable to register ROOT file handler with FileMgr"
169 msgSvc()->setOutputLevel(
"POSIXFileHandler", m_outputLevel.value());
172 auto pfh =
m_pfh.get();
175 const std::string& desc,
Io::Fd&
fd,
177 return pfh->openPOSIXFile(n, f, desc, fd, ptr);
180 return pfh->closePOSIXFile(fd);
183 return pfh->reopenPOSIXFile(fd, f);
188 <<
"unable to register ROOT file handler with FileMgr"
217 <<
"At finalize, the following files remained open:"
219 for (
const auto& itr :
m_files)
m_log << *(itr.second) << endl;
234 for (
const auto& itr :
m_files) {
235 ofs << itr.second->name() <<
" " << itr.second->tech() <<
" "
236 << itr.second->desc() <<
" " << itr.second->iflags() << endl;
240 for (
const auto& it2 :
m_oldFiles) fs.insert(*it2);
241 for (
const auto& it3 : fs ) {
242 ofs << it3.name() <<
" " << it3.tech() <<
" " << it3.desc()
243 <<
" " << it3.iflags()
244 << ( it3.isShared() ?
" SHARED" :
"" )
284 <<
"Handler for IoTech " << tech <<
" already registered. Ignoring."
291 <<
"open handler for tech " << tech <<
" is NULL"
298 <<
"no close handler for tech " << tech <<
" registered"
305 <<
"no reopen handler for tech " << tech <<
" registered"
313 <<
"Successfully registered handler for tech \"" << tech <<
"\""
331 <<
" as it hasn't been registered!"
354 const std::string& fname,
355 const IoFlags& flags,
Fd& fd,
void*& ptr,
356 const std::string& desc,
bool sh) {
358 return open(tech, caller, fname, desc, flags, fd, ptr, sh);
365 const std::string& fname,
366 const IoFlags& flags,
Fd& fd,
const std::string& desc,
370 return open(tech, caller, fname, desc, flags, fd, dummy, sh);
377 const std::string& fname,
378 const IoFlags& flags,
void*& ptr,
const std::string& desc,
382 return open(tech, caller, fname, desc, flags, dummy, ptr, sh);
390 const std::string& fname,
391 const std::string& desc,
392 const IoFlags& flags,
Fd& fd,
void*& ptr,
bool shared) {
413 <<
",\"" << fname <<
"\",\""
416 << ( shared ?
",shared" :
",unshared")
425 auto fitr =
m_files.equal_range(fname);
429 auto itr = std::find_if( fitr.first, fitr.second, [&](fileMap::const_reference
i) { return i.second->tech()!=tech; } );
430 if (itr != fitr.second) {
432 <<
" with tech " << tech
433 <<
", file already opened with different tech "
434 << itr->second->tech()
445 bool shareable(
true);
447 for (
auto itr=fitr.first; itr != fitr.second; ++itr) {
450 if (! fa->
isShared()) shareable =
false;
453 if ( shareable && fa->
flags().
match(flags,
false) ) {
478 }
catch (
const std::bad_function_call& err) {
481 << fname <<
" caught " << err.what() <<
endmsg;
486 << fname <<
" caught an unknown exception." <<
endmsg;
492 <<
"open of file \"" << fname <<
"\", tech: \"" << tech
493 <<
"\", flags: \"" << flags <<
"\" requested by "
495 <<
" failed. return code: " << r
498 FileAttr xfa(-1,fname,desc,tech,flags,0,
false);
515 if (fd == -1 && ptr == 0) {
517 <<
" and File Ptr are invalid" <<
endmsg;
522 for (
auto itr = fitr.first; itr != fitr.second; ++itr) {
525 }
else if (*fa == *(itr->second) ) {
527 <<
"\" returned a pre-existing file with identical"
528 <<
" FileAttributes: " << *fa <<
endmsg;
532 <<
"\" returned a pre-existing file with different"
533 <<
" FileAttributes -"
534 << endl <<
"old: " << *(itr->second)
535 << endl <<
"new: " << *fa << endmsg;
545 <<
"at least one open callback action failed"
573 [&](fileMap::const_reference
i) {
return i.second->fd() ==
fd; } );
578 <<
"\" when calling close()"
584 IoTech tech = itr->second->tech();
593 m_log <<
MSG::ERROR <<
"no close(" << tech <<
",Fd) function registered"
602 int i = std::count_if(fitr.first, fitr.second, [&](fileMap::const_reference f) {
603 return f.second->fd()==fd; } );
614 << i <<
" times with Fd " << fd <<
endmsg;
619 }
else if (i == 1 || (i>1 && !fa->
isShared()) ) {
626 }
catch (
const std::bad_function_call& err) {
628 <<
" on file descriptor "
629 << fd <<
" caught " << err.what() <<
endmsg;
634 <<
" on file descriptor "
635 << fd <<
" caught an unknown exception." <<
endmsg;
642 <<
"close of file with FD \"" << fd
643 <<
"\", name: \"" << fa->
name()
644 <<
"\", tech: \"" << tech <<
"\" failed"
657 <<
"ref count < 0 when closing " << fa
658 <<
". This should never happen"
674 <<
"at least one close callback action failed"
700 [&](fileMap::const_reference i ) {
return i.second->fptr()==vp; } );
704 <<
"\" when calling close()"
709 IoTech tech = itr->second->tech();
717 m_log <<
MSG::ERROR <<
"no close(" << tech <<
",void*) function registered"
725 pair<fileMap::const_iterator, fileMap::const_iterator> fitr =
728 int i = std::count_if( fitr.first, fitr.second, [&](fileMap::const_reference f)
729 { return f.second->fptr()==vp; } );
739 << i <<
" times with fptr " << vp <<
endmsg;
744 }
else if (i == 1 || (i>1 && !fa->
isShared()) ) {
750 }
catch (
const std::bad_function_call& err) {
752 <<
" on file " << fa->
name()
753 <<
" caught " << err.what() <<
endmsg;
758 <<
" on file " << fa->
name()
759 <<
" caught an unknown exception." <<
endmsg;
766 <<
"close of file with ptr \"" << vp
767 <<
"\", name: \"" << fa->
name()
768 <<
"\", tech: \"" << tech <<
"\" failed"
779 <<
"ref count: " << i <<
" < 0 when closing " << fa
780 <<
". This should never happen"
796 <<
"at least one close callback action failed"
811 <<
"," << caller <<
")"
818 {
return f.second->fd() ==
fd; } );
822 <<
"\" when calling reopen()"
839 m_log <<
MSG::ERROR <<
"no reopen(" << tech <<
",Fd) function registered"
849 }
catch (
const std::bad_function_call& err) {
851 <<
" on file descriptor " << fd <<
" with flags "
853 <<
" caught " << err.what() <<
endmsg;
857 <<
" on file descriptor " << fd <<
" with flags "
859 <<
" caught an unknown exception." <<
endmsg;
865 <<
"reopen of file with FD \"" << fd
866 <<
"\", name: \"" << fa->
name()
867 <<
"\", tech: \"" << tech
868 <<
"\", flags: \"" << flags <<
"\" failed"
883 <<
"at least one reopen callback action failed"
897 <<
"," << caller <<
")"
903 [&](fileMap::const_reference f) {
904 return f.second->fptr() == vp ; } );
907 <<
"unregistered file ptr \"" << vp
908 <<
"\" when calling reopen()"
922 m_log <<
MSG::ERROR <<
"no reopen(" << tech <<
",void*) function registered"
929 }
catch (
const std::bad_function_call& err) {
931 <<
" on file " << fa->
name() <<
" with flags "
933 <<
" caught " << err.what() <<
endmsg;
937 <<
" on file " << fa->
name() <<
" with flags "
939 <<
" caught an unknown exception." <<
endmsg;
945 <<
"reopen of file with ptr \"" << vp
946 <<
"\", name: \"" << fa->
name()
947 <<
"\", tech: \"" << tech
948 <<
"\", flags: \"" << flags <<
"\" failed"
963 <<
"at least one reopen callback action failed"
978 auto fitr =
m_files.equal_range(fname);
979 std::transform( fitr.first, fitr.second, std::back_inserter(fa), select2nd );
982 std::back_inserter(fa), [&](
const FileAttr* f ) {
return f->
name() ==
fname; } );
994 [&](fileMap::const_reference f ) {
return f.second->fd() ==
fd; } );
1017 [&](fileMap::const_reference f) {
return f.second->fptr() == vp; } );
1040 auto not_in_files = [&](
const std::string&
i) {
return std::none_of(
std::begin(files),
std::end(files),
1041 [&](
const std::string& j) {
return j==
i; } ); };
1050 return files.size();
1064 return files.size();
1078 [&](fileMap::const_reference f) {
return f.second->tech() == tech &&
1079 std::none_of(
std::begin(files),
std::end(files), [&](
const std::string& j) {
return j==f.first; } ); } );
1085 std::none_of(
std::begin(files),
std::end(files), [&](
const std::string& j) {
return j == f->
name(); } ) ; } );
1087 return files.size();
1099 auto matches_tech = [&](
const FileAttr* f) {
return f->
tech()==tech; } ;
1103 select2nd, matches_tech );
1109 return files.size();
1117 vector<string>& files,
bool op)
const {
1121 auto not_in_files = [&](
const std::string&
n) {
return std::none_of(
std::begin(files),
std::end(files),
1122 [&](
const std::string& f) {
return f==
n; } ); };
1123 auto matches_tech_and_flags = [&](
const FileAttr* f) {
return ( f->
tech() == tech || tech ==
UNKNOWN ) && f->
flags() == flags ; } ;
1127 [&](fileMap::const_reference f) {
return matches_tech_and_flags( f.second ) && not_in_files( f.first ); } );
1131 [&](
const FileAttr* f) {
return matches_tech_and_flags(f) && not_in_files(f->
name()); } );
1134 return files.size();
1141 vector<const Io::FileAttr*>& files,
bool op)
const {
1145 auto matches_tech_and_flags = [&](
const FileAttr* f) {
return ( f->
tech() == tech || tech ==
UNKNOWN )
1146 && f->
flags() == flags ; } ;
1150 matches_tech_and_flags );
1153 matches_tech_and_flags );
1156 return files.size();
1186 [&](
const std::pair<Fd,FileAttr*>& d) {
return d.second->tech()==tech; } );
1202 [&](
const std::pair<Fd,FileAttr*>& d) {
1203 return (d.second->tech() == tech || tech ==
UNKNOWN) &&
1204 ( d.second->flags() == flags );
1215 [&](fileMap::const_reference f) {
return f.second->fd() ==
fd; } );
1226 [&](fileMap::const_reference f) {
1227 return f.second->
fptr() == vp;
1229 return itr!=
m_files.end() ? itr->second->name() : s_empty;
1237 auto fitr =
m_files.equal_range(fname);
1238 auto itr = std::find_if( fitr.first, fitr.second, [](fileMap::const_reference f) {
1239 return f.second->fd() != -1;
1241 return itr!=fitr.second ? itr->second->fd() : -1 ;
1249 auto itr = std::find_if(
m_files.begin(),
m_files.end(),[&](fileMap::const_reference f) {
1252 return itr!=
m_files.end() ? itr->second->fd() : -1 ;
1259 auto fitr =
m_files.equal_range(fname);
1260 auto itr = std::find_if( fitr.first, fitr.second, [](fileMap::const_reference f) ->
bool {
1261 return f.second->fptr();
1263 return itr!=fitr.second ? itr->second->fptr() :
nullptr;
1271 auto itr = std::find_if(
m_files.begin(),
m_files.end(),[&](fileMap::const_reference f) {
1272 return f.second->
fd() ==
fd;
1274 return itr!=
m_files.end() ? itr->second->fptr() :
nullptr;
1286 for (
auto& itr :
m_files )
m_log << itr.second << endl;
1310 <<
"no handler for tech " << tech <<
" registered"
1323 auto fitr =
m_files.equal_range(fname);
1324 if (fitr.first == fitr.second) {
1326 <<
"no file \"" << fname <<
"\" registered. Cannot determine tech"
1331 auto itr = fitr.first;
1332 IoTech tech = itr->second->tech();
1335 while( itr != fitr.second ) {
1336 if ( itr->second->tech() != tech ) {
1338 <<
"multiple technologies registered for file \"" << fname
1339 <<
"\". Cannot determine handler" <<
endmsg;
1355 <<
"Listing registered handlers:" << endl;
1357 for (
const auto& itr :
m_handlers )
m_log <<
" " << itr.first << endl;
1375 const std::string& d) {
1380 <<
" for tech " << t << endmsg;
1382 m_actions[t][a].emplace_back(bf, (!d.empty()) ? d
1400 m_log <<
" --- Tech: ";
1402 m_log <<
"ALL ---" << endl;
1404 m_log << t <<
" ---" << endl;
1406 for (
const auto& iia : m ) {
1407 for (
const auto& it2 : iia.second ) {
1408 m_log <<
" " << iia.first <<
" "
1409 << it2.second << endl;
1429 if (itr !=
m_actions.end() && !itr->second.empty() ) {
1430 s1 =
execActs(fa, caller, a, itr->second);
1434 if (itr !=
m_actions.end() && !itr->second.empty() ) {
1435 s2 =
execActs(fa, caller, a, itr->second);
1448 auto mitr = m.find(a);
1450 if (mitr == m.end() || mitr->second.empty()) {
1456 <<
"executing " << mitr->second.size() <<
" " << a
1476 for (
const auto& itr : mitr->second ) {
1482 if ( (((itr.first))(fa,caller)).isFailure() ) {
1484 << itr.second <<
" on " << *fa
1485 <<
" failed during " << a <<
" action"
1508 ( (fold &
Io::WRITE) != 0 && (fnew & Io::WRITE) != 0) ||
1509 ( (fold &
Io::RDWR) != 0 && (fnew & Io::RDWR) != 0) ) ;
1533 set_bit(it2->second, a);
1548 m_log <<
" " << it2->first;
1550 m_log <<
" ALL" << endl;
std::vector< std::unique_ptr< FileAttr > > m_attr
StatusCode regHandler(FileHdlr) override
StatusCode getHandler(const IoTech &, FileHdlr &) const override
Io::Fd fd(const std::string &) const override
StatusCode initialize() override
The ISvcLocator is the interface implemented by the Service Factory in the Application Manager to loc...
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
StatusCode finalize() override
std::function< StatusCode(FILEMGR_CALLBACK_ARGS) > bfcn_action_t
const std::string & name() const
property name
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
constexpr struct select1st_t select1st
bfcn_reopen_t b_reopen_fcn
void suppressAction(const std::string &) override
bool isSuccess() const
Test for a status code of SUCCESS.
auto begin(reverse_wrapper< T > &w)
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
std::map< Io::Action, std::list< bfcn_desc_t > > actionMap
int getLastError(std::string &) const override
StatusCode deregHandler(const IoTech &) override
StatusCode execAction(Io::FileAttr *, const std::string &, const Io::Action &) const
std::map< Fd, FileAttr * > m_descriptors
StatusCode hasHandler(const IoTech &) const override
bool isFailure() const
Test for a status code of FAILURE.
bool accessMatch(const Io::IoFlags &, const Io::IoFlags &, bool strict=false) const
std::unique_ptr< RootFileHandler > m_rfh
virtual void listActions() const
const std::string & name() const
std::map< IoTech, FileHdlr > m_handlers
Main interface for the JobOptions service.
void handle(const Incident &) override
auto end(reverse_wrapper< T > &w)
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
BooleanProperty m_printSummary
bool PyHelper() setProperty(IInterface *p, char *name, char *value)
Io::close_t close(const Fd, const std::string &caller) override
std::unique_ptr< POSIXFileHandler > m_pfh
bfcn_reopenP_t b_reopenP_fcn
int getFileAttr(const std::string &, std::vector< const FileAttr * > &) const override
#define DECLARE_SERVICE_FACTORY(x)
const TYPE & value() const
explicit conversion
StatusCode regAction(Io::bfcn_action_t, const Io::Action &, const std::string &desc="") override
FileMgr(const std::string &name, ISvcLocator *svc)
BooleanProperty m_loadRootHandler
std::vector< FileAttr * > m_oldFiles
Property base class allowing Property* collections to be "homogeneous".
const std::string & fname(const Io::Fd &) const override
BooleanProperty m_loadPosixHandler
Base class used to extend a class implementing other interfaces.
virtual void listSuppression() const
bool match(const IoFlags &fa, bool strict=true) const
void * fptr(const std::string &) const override
StringProperty m_ssl_cert
Base class for all Incidents (computing events).
void setLevel(int level)
Update outputlevel.
int getFiles(std::vector< std::string > &, bool onlyOpen=true) const override
void listFiles() const override
StringProperty m_ssl_proxy
void listHandlers() const override
int getFd(std::vector< Fd > &) const override
StatusCode finalize() override
StatusCode initialize() override
std::map< IoTech, actionMap > m_actions