ATLAS Offline Software
Toggle main menu visibility
Loading...
Searching...
No Matches
Control
RootUtils
src
WithRootErrorHandler.cxx
Go to the documentation of this file.
1
/*
2
* Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration.
3
*/
10
11
12
#include "
RootUtils/WithRootErrorHandler.h
"
13
#include <vector>
14
#include <cstdlib>
15
#include <mutex>
16
#include <atomic>
17
18
19
namespace
{
20
21
23
using
Handler_t =
RootUtils::WithRootErrorHandler::Handler_t
;
24
thread_local
std::vector<Handler_t> rootErrorHandlers;
25
26
28
std::atomic<ErrorHandlerFunc_t> origHandler;
29
30
34
void
errorHandler
(
int
level,
35
Bool_t abort,
36
const
char
* location,
37
const
char
*
msg
)
38
{
39
// Execute all the handlers in our thread-local list from newest to oldest.
40
// Stop if one returns false.
41
for
(
int
i = rootErrorHandlers.size()-1; i >= 0; --i) {
42
if
(!rootErrorHandlers[i] (level, abort, location,
msg
))
return
;
43
}
44
// They all returned true. Call the previous handler.
45
origHandler.load() (
level
, abort, location,
msg
);
46
}
47
48
49
}
// anonymous namespace
50
51
52
namespace
RootUtils
{
53
54
65
WithRootErrorHandler::WithRootErrorHandler
(
Handler_t
errhand)
66
:
m_size
(rootErrorHandlers.
size
()+1)
67
{
68
// Install our handler the first time we're called.
69
// We used to do that when the library was loaded, via a global static,
70
// but then we ran to issues where the behavior could depend on library
71
// loading order, since other libraries (such as Gaudi) also try to install
72
// their own handler.
73
//
74
// By the time we're called, there may be multiple threads running,
75
// so it is in principle not safe to call SetErrorHandler.
76
// However, there shouldn't be anything else in Athena calling it,
77
// so in practice it should be ok. As an extra check, we abort if the
78
// handler we get back isn't what we set, indicating a potential race.
79
//
80
// See ATLASRECTS-7967.
81
static
std::once_flag flag;
82
std::call_once (flag, []() {
83
origHandler = ::SetErrorHandler (
errorHandler
);
84
if
(::GetErrorHandler() !=
errorHandler
) {
85
std::abort();
86
}
87
});
88
89
rootErrorHandlers.push_back (errhand);
90
}
91
92
98
WithRootErrorHandler::~WithRootErrorHandler
()
99
{
100
if
(
m_size
!= rootErrorHandlers.size()) std::abort();
101
rootErrorHandlers.pop_back();
102
}
103
104
105
}
// namespace RootUtils
errorHandler
static void errorHandler()
Definition
ITPConverter.cxx:11
size
size_t size() const
Number of registered mappings.
WithRootErrorHandler.h
Run a MT piece of code with an alternate root error handler.
RootUtils::WithRootErrorHandler::m_size
size_t m_size
For error checking.
Definition
WithRootErrorHandler.h:101
RootUtils::WithRootErrorHandler::~WithRootErrorHandler
~WithRootErrorHandler()
Destructor.
Definition
WithRootErrorHandler.cxx:98
RootUtils::WithRootErrorHandler::Handler_t
std::function< bool(int, Bool_t, const char *, const char *)> Handler_t
Type of handler to register.
Definition
WithRootErrorHandler.h:63
RootUtils::WithRootErrorHandler::WithRootErrorHandler
WithRootErrorHandler(Handler_t errhand)
Temporarily install a thread-local root error handler.
Definition
WithRootErrorHandler.cxx:65
RootUtils
Definition
ILogger.h:20
python.iconfTool.models.loaders.level
level
Definition
loaders.py:20
msg
MsgStream & msg
Definition
testRead.cxx:32
Generated on
for ATLAS Offline Software by
1.17.0