Main Page
Related Pages
Modules
Namespaces
Classes
Files
Examples
File List
File Members
cetlib
cetlib
assert_only_one_thread.h
Go to the documentation of this file.
1
#ifndef cetlib_assert_only_one_thread_h
2
#define cetlib_assert_only_one_thread_h
3
// vim: set sw=2 expandtab :
4
5
// ===================================================================
6
// CET_ASSERT_ONLY_ONE_THREAD()
7
//
8
// This macro is a utility that can be called wherever it is expected
9
// for only one thread to be accessing a particular block of code.
10
//
11
// It has similar semantics to the standard 'assert' macro:
12
//
13
// - It is disabled if NDEBUG is defined
14
// - If more than one thread is accessing that block of code at one
15
// time, std::abort is called.
16
// - It is encouraged to be used whenever single-threaded execution
17
// of a code block is a pre-condition.
18
//
19
// If the std::abort() is called, file, line-number, and function-name
20
// information will be provided.
21
// ===================================================================
22
23
#include <atomic>
24
#include <cstdlib>
25
#include <iostream>
26
#include <string>
27
28
namespace
cet::detail
{
29
30
class
ThreadCounter
{
31
public
:
32
explicit
ThreadCounter
(
char
const
*
filename
,
33
unsigned
const
linenum,
34
char
const
* funcname)
35
:
filename_
{filename},
linenum_
{linenum},
funcname_
{funcname}
36
{}
37
38
class
Sentry
{
39
public
:
40
~Sentry
() noexcept { --
tc_
.
counter_
; }
41
Sentry
(
ThreadCounter
& tc,
bool
const
terminate =
true
) :
tc_
{tc}
42
{
43
if
(++
tc_
.
counter_
== 1u) {
44
return
;
45
}
46
std::cerr <<
"Failed assert--more than one thread accessing location:\n"
47
<<
" "
<<
tc_
.
filename_
<<
':'
<<
tc_
.
linenum_
<<
'\n'
48
<<
" function: "
<<
tc_
.
funcname_
<<
'\n'
;
49
if
(terminate) {
50
std::abort();
51
}
52
}
53
54
private
:
55
ThreadCounter
&
tc_
;
56
};
57
58
private
:
59
std::string
const
filename_
;
60
unsigned
const
linenum_
;
61
std::string
const
funcname_
;
62
std::atomic<unsigned>
counter_
{0u};
63
};
64
65
}
// namespace cet::detail
66
67
#ifdef NDEBUG
68
#define CET_ASSERT_ONLY_ONE_THREAD()
69
#else // NDEBUG
70
#define CET_ASSERT_ONLY_ONE_THREAD() \
71
static cet::detail::ThreadCounter s_tc_{__FILE__, __LINE__, __func__}; \
72
cet::detail::ThreadCounter::Sentry sentry_tc_ { s_tc_ }
73
#endif // NDEBUG
74
75
#endif
/* cetlib_assert_only_one_thread_h */
76
77
// Local variables:
78
// mode: c++
79
// End:
cet::detail::ThreadCounter::Sentry::Sentry
Sentry(ThreadCounter &tc, bool const terminate=true)
Definition:
assert_only_one_thread.h:41
cet::detail::ThreadCounter::Sentry::tc_
ThreadCounter & tc_
Definition:
assert_only_one_thread.h:55
string
std::string string
Definition:
nybbler.cc:12
cet::detail::ThreadCounter::Sentry::~Sentry
~Sentry() noexcept
Definition:
assert_only_one_thread.h:40
cet::detail::ThreadCounter::funcname_
std::string const funcname_
Definition:
assert_only_one_thread.h:61
train.filename
string filename
Definition:
train.py:213
cet::detail
Definition:
assert_only_one_thread.h:28
cet::detail::ThreadCounter::filename_
std::string const filename_
Definition:
assert_only_one_thread.h:59
cet::detail::ThreadCounter::linenum_
unsigned const linenum_
Definition:
assert_only_one_thread.h:60
cet::detail::ThreadCounter::Sentry
Definition:
assert_only_one_thread.h:38
cet::detail::ThreadCounter::ThreadCounter
ThreadCounter(char const *filename, unsigned const linenum, char const *funcname)
Definition:
assert_only_one_thread.h:32
cet::detail::ThreadCounter::counter_
std::atomic< unsigned > counter_
Definition:
assert_only_one_thread.h:62
cet::detail::ThreadCounter
Definition:
assert_only_one_thread.h:30
Generated by
1.8.11