17#define ON_DEBUG if ( msgLevel( MSG::DEBUG ) )
18#define ON_VERBOSE if ( msgLevel( MSG::VERBOSE ) )
29 static const std::string s_empty =
"";
31 constexpr struct to_name_t {
32 std::string operator()(
const FileAttr* f )
const {
return f->
name(); }
33 std::string operator()(
const std::pair<std::string, FileAttr*>& f )
const {
return f.first; }
36 const auto select1st = [](
auto&& x ) ->
decltype(
auto ) {
return std::get<0>( std::forward<
decltype( x )>( x ) ); };
38 const auto select2nd = [](
auto&& x ) ->
decltype(
auto ) {
return std::get<1>( std::forward<
decltype( x )>( x ) ); };
40 template <
typename InputIterator,
typename OutputIterator,
typename UnaryOperation,
typename UnaryPredicate>
41 OutputIterator transform_if( InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op,
42 UnaryPredicate pred ) {
43 while ( first != last ) {
44 if ( pred( *first ) ) *result++ = op( *first );
50 template <
typename InputIterator,
typename OutputIterator,
typename UnaryOperation,
typename UnaryPredicate>
51 OutputIterator transform_copy_if( InputIterator first, InputIterator last, OutputIterator result, UnaryOperation op,
52 UnaryPredicate pred ) {
53 while ( first != last ) {
54 auto t = op( *first );
55 if ( pred( t ) ) *result++ = std::move( t );
77 debug() <<
"Failed to initialize the base class (Service)" <<
endmsg;
91 auto& rfh =
m_rfh.value();
95 void*& ptr ) ->
Io::open_t {
return rfh.openRootFile( n, f, desc,
fd, ptr ); },
96 [&rfh](
void* ptr ) ->
Io::close_t {
return rfh.closeRootFile( ptr ); },
99 if (
regHandler( hdlr ).isFailure() ) {
error() <<
"unable to register ROOT file handler with FileMgr" <<
endmsg; }
109 auto& pfh =
m_pfh.value();
113 void*& ptr ) ->
Io::open_t {
return pfh.openPOSIXFile( n, f, desc,
fd, ptr ); },
117 if (
regHandler( hdlp ).isFailure() ) {
error() <<
"unable to register ROOT file handler with FileMgr" <<
endmsg; }
138 log <<
"At finalize, the following files remained open:\n";
139 for (
const auto& itr :
m_files ) log << *( itr.second ) <<
'\n';
151 for (
const auto& itr :
m_files ) {
152 ofs << itr.second->name() <<
" " << itr.second->tech() <<
" " << itr.second->desc() <<
" "
153 << itr.second->iflags() <<
'\n';
157 for (
const auto& it2 :
m_oldFiles ) fs.insert( *it2 );
158 for (
const auto& it3 : fs ) {
159 ofs << it3.name() <<
" " << it3.tech() <<
" " << it3.desc() <<
" " << it3.iflags()
160 << ( it3.isShared() ?
" SHARED" :
"" ) <<
'\n';
191 warning() <<
"Handler for IoTech " << tech <<
" already registered. Ignoring." <<
endmsg;
196 error() <<
"open handler for tech " << tech <<
" is NULL" <<
endmsg;
201 error() <<
"no close handler for tech " << tech <<
" registered" <<
endmsg;
206 error() <<
"no reopen handler for tech " << tech <<
" registered" <<
endmsg;
211 debug() <<
"Successfully registered handler for tech \"" << tech <<
"\"" <<
endmsg;
225 error() <<
"Can't de-register tech " << tech <<
" as it hasn't been registered!" <<
endmsg;
243 Fd&
fd,
void*& ptr,
const std::string& desc,
bool sh ) {
245 return open( tech, caller,
fname, desc, flags,
fd, ptr, sh );
250 Fd&
fd,
const std::string& desc,
bool sh ) {
253 return open( tech, caller,
fname, desc, flags,
fd, dummy, sh );
258 void*& ptr,
const std::string& desc,
bool sh ) {
261 return open( tech, caller,
fname, desc, flags, dummy, ptr, sh );
267 const IoFlags& flags,
Fd&
fd,
void*& ptr,
bool shared ) {
285 verbose() <<
"open(" << tech <<
"," << caller <<
",\"" <<
fname <<
"\",\"" << desc <<
"\"," << flags
286 << ( shared ?
",shared" :
",unshared" ) <<
")" <<
endmsg;
290 if (
getHandler( tech, fh ).isFailure() )
return r;
297 std::find_if( fitr.first, fitr.second, [&]( fileMap::const_reference i ) { return i.second->tech() != tech; } );
298 if ( itr != fitr.second ) {
299 error() <<
"when calling open on " <<
fname <<
" with tech " << tech <<
", file already opened with different tech "
300 << itr->second->tech() <<
endmsg;
309 bool shareable(
true );
311 for (
auto itr = fitr.first; itr != fitr.second; ++itr ) {
314 if ( !fa->
isShared() ) shareable =
false;
317 if ( shareable && fa->
flags().
match( flags,
false ) ) {
320 debug() <<
" found shared file: " << *fa <<
endmsg;
340 }
catch (
const std::bad_function_call&
err ) {
341 error() <<
"when calling open handler for " << tech <<
" on file " <<
fname <<
" caught " <<
err.what() <<
endmsg;
344 error() <<
"when calling open handler for " << tech <<
" on file " <<
fname <<
" caught an unknown exception."
350 warning() <<
"open of file \"" <<
fname <<
"\", tech: \"" << tech <<
"\", flags: \"" << flags
351 <<
"\" requested by " << caller <<
" failed. return code: " << r <<
endmsg;
368 if (
fd == -1 && ptr == 0 ) {
369 warning() <<
"when opening " << *fa <<
" both File Descriptor"
370 <<
" and File Ptr are invalid" <<
endmsg;
374 for (
auto itr = fitr.first; itr != fitr.second; ++itr ) {
377 }
else if ( *fa == *( itr->second ) ) {
378 warning() <<
"open call for file \"" <<
fname <<
"\" returned a pre-existing file with identical"
379 <<
" FileAttributes: " << *fa <<
endmsg;
382 warning() <<
"open call for file \"" <<
fname <<
"\" returned a pre-existing file with different"
383 <<
" FileAttributes -\n"
384 <<
"old: " << *( itr->second ) <<
'\n'
385 <<
"new: " << *fa <<
endmsg;
394 warning() <<
"at least one open callback action failed" <<
endmsg;
415 auto itr = std::find_if( std::begin(
m_files ), std::end(
m_files ),
416 [&]( fileMap::const_reference i ) {
return i.second->fd() ==
fd; } );
418 if ( itr == std::end(
m_files ) ) {
419 error() <<
"unknown file descriptor \"" <<
fd <<
"\" when calling close()" <<
endmsg;
423 IoTech tech = itr->second->tech();
427 if (
getHandler( tech, fh ).isFailure() ) {
return r; }
430 error() <<
"no close(" << tech <<
",Fd) function registered" <<
endmsg;
438 int i = std::count_if( fitr.first, fitr.second, [&]( fileMap::const_reference f ) { return f.second->fd() == fd; } );
446 debug() <<
"closing file " << fa->
name() <<
" opened " << i <<
" times with Fd " <<
fd <<
endmsg;
451 }
else if ( i == 1 || ( i > 1 && !fa->
isShared() ) ) {
457 }
catch (
const std::bad_function_call&
err ) {
458 error() <<
"when calling close handler for " << tech <<
" on file descriptor " <<
fd <<
" caught " <<
err.what()
463 error() <<
"when calling close handler for " << tech <<
" on file descriptor " <<
fd
464 <<
" caught an unknown exception." <<
endmsg;
470 warning() <<
"close of file with FD \"" <<
fd <<
"\", name: \"" << fa->
name() <<
"\", tech: \"" << tech
480 }
else if ( i <= 0 ) {
482 error() <<
"ref count < 0 when closing " << fa <<
". This should never happen" <<
endmsg;
494 warning() <<
"at least one close callback action failed" <<
endmsg;
514 auto itr = std::find_if( std::begin(
m_files ), std::end(
m_files ),
515 [&]( fileMap::const_reference i ) {
return i.second->fptr() == vp; } );
518 error() <<
"unknown file ptr \"" << vp <<
"\" when calling close()" <<
endmsg;
522 IoTech tech = itr->second->tech();
526 if (
getHandler( tech, fh ).isFailure() ) {
return r; }
528 error() <<
"no close(" << tech <<
",void*) function registered" <<
endmsg;
535 pair<fileMap::const_iterator, fileMap::const_iterator> fitr =
m_files.equal_range( fa->
name() );
538 std::count_if( fitr.first, fitr.second, [&]( fileMap::const_reference f ) { return f.second->fptr() == vp; } );
546 debug() <<
"closing file " << fa->
name() <<
" opened " << i <<
" times with fptr " << vp <<
endmsg;
551 }
else if ( i == 1 || ( i > 1 && !fa->
isShared() ) ) {
557 }
catch (
const std::bad_function_call&
err ) {
558 error() <<
"when calling close handler for " << tech <<
" on file " << fa->
name() <<
" caught " <<
err.what()
563 error() <<
"when calling close handler for " << tech <<
" on file " << fa->
name()
564 <<
" caught an unknown exception." <<
endmsg;
570 warning() <<
"close of file with ptr \"" << vp <<
"\", name: \"" << fa->
name() <<
"\", tech: \"" << tech
580 error() <<
"ref count: " << i <<
" < 0 when closing " << fa <<
". This should never happen" <<
endmsg;
592 warning() <<
"at least one close callback action failed" <<
endmsg;
603 verbose() <<
"reopen(" <<
fd <<
"," << flags <<
"," << caller <<
")" <<
endmsg;
607 auto itr = std::find_if( std::begin(
m_files ), std::end(
m_files ),
608 [&]( fileMap::const_reference f ) {
return f.second->fd() ==
fd; } );
611 error() <<
"unregistered FD \"" <<
fd <<
"\" when calling reopen()" <<
endmsg;
620 if (
getHandler( tech, fh ).isFailure() ) {
return r; }
625 error() <<
"no reopen(" << tech <<
",Fd) function registered" <<
endmsg;
633 }
catch (
const std::bad_function_call&
err ) {
634 error() <<
"when calling reopen handler for " << tech <<
" on file descriptor " <<
fd <<
" with flags " << flags
638 error() <<
"when calling reopen handler for " << tech <<
" on file descriptor " <<
fd <<
" with flags " << flags
639 <<
" caught an unknown exception." <<
endmsg;
644 warning() <<
"reopen of file with FD \"" <<
fd <<
"\", name: \"" << fa->
name() <<
"\", tech: \"" << tech
645 <<
"\", flags: \"" << flags <<
"\" failed" <<
endmsg;
657 warning() <<
"at least one reopen callback action failed" <<
endmsg;
667 verbose() <<
"reopen(" << vp <<
"," << flags <<
"," << caller <<
")" <<
endmsg;
671 auto itr = std::find_if( std::begin(
m_files ), std::end(
m_files ),
672 [&]( fileMap::const_reference f ) {
return f.second->fptr() == vp; } );
674 error() <<
"unregistered file ptr \"" << vp <<
"\" when calling reopen()" <<
endmsg;
682 if (
getHandler( tech, fh ).isFailure() ) {
return r; }
685 error() <<
"no reopen(" << tech <<
",void*) function registered" <<
endmsg;
691 }
catch (
const std::bad_function_call&
err ) {
692 error() <<
"when calling reopen handler for " << tech <<
" on file " << fa->
name() <<
" with flags " << flags
696 error() <<
"when calling reopen handler for " << tech <<
" on file " << fa->
name() <<
" with flags " << flags
697 <<
" caught an unknown exception." <<
endmsg;
702 warning() <<
"reopen of file with ptr \"" << vp <<
"\", name: \"" << fa->
name() <<
"\", tech: \"" << tech
703 <<
"\", flags: \"" << flags <<
"\" failed" <<
endmsg;
715 warning() <<
"at least one reopen callback action failed" <<
endmsg;
728 std::transform( fitr.first, fitr.second, std::back_inserter( fa ), select2nd );
740 auto i = std::find_if( std::begin(
m_files ), std::end(
m_files ),
741 [&]( fileMap::const_reference f ) {
return f.second->fd() ==
fd; } );
742 if ( i != std::end(
m_files ) ) {
748 [&](
const FileAttr* f ) {
return f->fd() ==
fd; } );
761 auto i = std::find_if( std::begin(
m_files ), std::end(
m_files ),
762 [&]( fileMap::const_reference f ) {
return f.second->fptr() == vp; } );
763 if ( i != std::end(
m_files ) ) {
769 [&](
const FileAttr* f ) {
return f->fptr() == vp; } );
783 auto not_in_files = [&](
const std::string& i ) {
784 return std::none_of( std::begin( files ), std::end( files ), [&](
const std::string& j ) {
return j == i; } );
786 transform_copy_if( std::begin(
m_files ), std::end(
m_files ), std::back_inserter( files ), to_name, not_in_files );
788 transform_copy_if( std::begin(
m_oldFiles ), std::end(
m_oldFiles ), std::back_inserter( files ), to_name,
799 std::transform( std::begin(
m_files ), std::end(
m_files ), std::back_inserter( files ), select2nd );
800 if ( !op ) { std::copy( std::begin(
m_oldFiles ), std::end(
m_oldFiles ), std::back_inserter( files ) ); }
811 transform_if( std::begin(
m_files ), std::end(
m_files ), std::back_inserter( files ), to_name,
812 [&]( fileMap::const_reference f ) {
813 return f.second->tech() == tech &&
814 std::none_of( std::begin( files ), std::end( files ),
815 [&](
const std::string& j ) {
return j == f.first; } );
819 transform_if( std::begin(
m_oldFiles ), std::end(
m_oldFiles ), std::back_inserter( files ), to_name,
821 return f->
tech() == tech && std::none_of( std::begin( files ), std::end( files ),
822 [&](
const std::string& j ) {
return j == f->
name(); } );
834 auto matches_tech = [&](
const FileAttr* f ) {
return f->tech() == tech; };
837 transform_copy_if( std::begin(
m_files ), std::end(
m_files ), std::back_inserter( files ), select2nd, matches_tech );
839 std::copy_if( std::begin(
m_oldFiles ), std::end(
m_oldFiles ), std::back_inserter( files ), matches_tech );
851 auto not_in_files = [&](
const std::string& n ) {
852 return std::none_of( std::begin( files ), std::end( files ), [&](
const std::string& f ) {
return f == n; } );
854 auto matches_tech_and_flags = [&](
const FileAttr* f ) {
855 return ( f->tech() == tech || tech ==
UNKNOWN ) && f->flags() == flags;
859 std::begin(
m_files ), std::end(
m_files ), std::back_inserter( files ), to_name,
860 [&]( fileMap::const_reference f ) {
return matches_tech_and_flags( f.second ) && not_in_files( f.first ); } );
862 transform_if( std::begin(
m_oldFiles ), std::end(
m_oldFiles ), std::back_inserter( files ), to_name,
863 [&](
const FileAttr* f ) {
return matches_tech_and_flags( f ) && not_in_files( f->
name() ); } );
874 auto matches_tech_and_flags = [&](
const FileAttr* f ) {
875 return ( f->tech() == tech || tech ==
UNKNOWN ) && f->flags() == flags;
878 transform_copy_if( std::begin(
m_files ), std::end(
m_files ), std::back_inserter( files ), select2nd,
879 matches_tech_and_flags );
882 matches_tech_and_flags );
910 [&](
const std::pair<Fd, FileAttr*>& d ) {
return d.second->tech() == tech; } );
923 [&](
const std::pair<Fd, FileAttr*>& d ) {
924 return ( d.second->tech() == tech || tech == UNKNOWN ) && ( d.second->flags() == flags );
933 auto itr = std::find_if( std::begin(
m_files ), std::end(
m_files ),
934 [&]( fileMap::const_reference f ) {
return f.second->fd() ==
fd; } );
935 return ( itr != std::end(
m_files ) ) ? itr->second->name() : s_empty;
943 [&]( fileMap::const_reference f ) { return f.second->fptr() == vp; } );
944 return itr !=
m_files.end() ? itr->second->name() : s_empty;
952 auto itr = std::find_if( fitr.first, fitr.second, []( fileMap::const_reference f ) { return f.second->fd() != -1; } );
953 return itr != fitr.second ? itr->second->fd() : -1;
961 [&]( fileMap::const_reference f ) { return f.second->fptr() == fptr; } );
962 return itr !=
m_files.end() ? itr->second->fd() : -1;
970 std::find_if( fitr.first, fitr.second, []( fileMap::const_reference f ) ->
bool { return f.second->fptr(); } );
971 return itr != fitr.second ? itr->second->fptr() :
nullptr;
979 [&]( fileMap::const_reference f ) { return f.second->fd() == fd; } );
980 return itr !=
m_files.end() ? itr->second->fptr() :
nullptr;
989 for (
auto& itr :
m_files )
info() << itr.second <<
'\n';
1009 error() <<
"no handler for tech " << tech <<
" registered" <<
endmsg;
1021 if ( fitr.first == fitr.second ) {
1022 error() <<
"no file \"" <<
fname <<
"\" registered. Cannot determine tech" <<
endmsg;
1026 auto itr = fitr.first;
1027 IoTech tech = itr->second->tech();
1030 while ( itr != fitr.second ) {
1031 if ( itr->second->tech() != tech ) {
1032 error() <<
"multiple technologies registered for file \"" <<
fname <<
"\". Cannot determine handler" <<
endmsg;
1045 info() <<
"Listing registered handlers:\n";
1047 for (
const auto& itr :
m_handlers )
info() <<
" " << itr.first <<
'\n';
1074 info() <<
"listing registered actions\n";
1081 info() <<
" --- Tech: ";
1083 info() <<
"ALL ---\n";
1085 info() << t <<
" ---\n";
1087 for (
const auto& iia : m ) {
1088 for (
const auto& it2 : iia.second ) {
info() <<
" " << iia.first <<
" " << it2.second <<
'\n'; }
1105 if ( itr !=
m_actions.end() && !itr->second.empty() ) { s1 =
execActs( fa, caller, a, itr->second ); }
1108 if ( itr !=
m_actions.end() && !itr->second.empty() ) { s2 =
execActs( fa, caller, a, itr->second ); }
1118 auto mitr = m.find( a );
1122 debug() <<
"executing " << mitr->second.size() <<
" " << a <<
" actions on " << *fa <<
" from " << caller <<
endmsg;
1130 debug() <<
" --> suppressing callback action for " << a <<
endmsg;
1135 for (
const auto& itr : mitr->second ) {
1140 if ( ( ( ( itr.first ) )( fa, caller ) ).isFailure() ) {
1141 warning() <<
"execution of " << itr.second <<
" on " << *fa <<
" failed during " << a <<
" action" <<
endmsg;
1153 verbose() <<
"accessMatch old: " << fold <<
" new: " << fnew <<
endmsg;
1173 info() <<
"listing suppressed file actions\n";
1175 for (
const auto& sup :
m_supMap ) {
1176 info() <<
" " << sup.first;
1180 for (
unsigned i = 0; i != sup.second.size(); ++i ) {
MsgStream & endmsg(MsgStream &s)
MsgStream Modifier: endmsg. Calls the output method of the MsgStream.
#define DECLARE_COMPONENT(type)
MsgStream & error() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & verbose() const
shortcut for the method msgStream(MSG::VERBOSE)
MsgStream & warning() const
shortcut for the method msgStream(MSG::WARNING)
const SmartIF< IMessageSvc > & msgSvc() const
The standard message service.
MsgStream & err() const
shortcut for the method msgStream(MSG::ERROR)
MsgStream & debug() const
shortcut for the method msgStream(MSG::DEBUG)
MsgStream & info() const
shortcut for the method msgStream(MSG::INFO)
MSG::Level msgLevel() const
std::vector< std::unique_ptr< FileAttr > > m_attr
Io::reopen_t reopen(const Fd, const IoFlags &, const std::string &caller) override
Gaudi::Property< std::string > m_logfile
void suppressAction(const std::string &) override
Gaudi::Property< bool > m_printSummary
StatusCode initialize() override
StatusCode deregHandler(const IoTech &) override
std::vector< FileAttr * > m_oldFiles
StatusCode execAction(Io::FileAttr *, const std::string &, const Io::Action &) const
Gaudi::Property< std::string > m_ssl_cert
virtual void listActions() const
std::optional< RootFileHandler > m_rfh
StatusCode regHandler(FileHdlr) override
StatusCode execActs(Io::FileAttr *, const std::string &, const Io::Action &, const actionMap &m) const
std::map< IoTech, actionMap > m_actions
Gaudi::Property< bool > m_loadPosixHandler
void listHandlers() const override
virtual void listSuppression() const
StatusCode regAction(Io::bfcn_action_t, const Io::Action &, const std::string &desc="") override
std::map< Io::Action, std::list< bfcn_desc_t > > actionMap
std::map< Fd, FileAttr * > m_descriptors
bool accessMatch(const Io::IoFlags &, const Io::IoFlags &, bool strict=false) const
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
Gaudi::Property< std::string > m_ssl_proxy
Gaudi::Property< bool > m_loadRootHandler
Io::Fd fd(const std::string &) const override
int getFd(std::vector< Fd > &) const override
Io::close_t close(const Fd, const std::string &caller) override
const std::string & fname(const Io::Fd &) const override
void handle(const Incident &) override
std::map< IoTech, FileHdlr > m_handlers
StatusCode hasHandler(const IoTech &) const override
std::optional< POSIXFileHandler > m_pfh
void * fptr(const std::string &) const override
void listFiles() const override
std::map< std::string, Io::Action_bitmap > m_supMap
int getFileAttr(const std::string &, std::vector< const FileAttr * > &) const override
int getFiles(std::vector< std::string > &, bool onlyOpen=true) const override
int getLastError(std::string &) const override
StatusCode finalize() override
StatusCode getHandler(const IoTech &, FileHdlr &) const override
virtual void setOutputLevel(int new_level)=0
Set new global output level threshold.
Base class for all Incidents (computing events).
const std::string & name() const
bool match(const IoFlags &fa, bool strict=true) const
StatusCode finalize() override
Gaudi::Property< int > m_outputLevel
flag indicating whether ToolHandle tools have been added to m_tools
StatusCode initialize() override
This class is used for returning status codes from appropriate routines.
const StatusCode & ignore() const
Allow discarding a StatusCode without warning.
constexpr static const auto SUCCESS
constexpr static const auto FAILURE
std::function< StatusCode(FILEMGR_CALLBACK_ARGS)> bfcn_action_t
GAUDI_API const std::string typeinfoName(const std::type_info &)
Get platform independent information about the class type.
bfcn_reopen_t b_reopen_fcn
bfcn_closeP_t b_closeP_fcn
bfcn_reopenP_t b_reopenP_fcn