According to the C++17 standard, [support.signal], the atomic object should satisfy the following requirements to be used in a signal handler:
- [...], or
f
is a non-static member function invoked on an objectA
, such thatA.is_lock_free()
yieldstrue
, orf
is a non-member function, and for every pointer-to-atomic argumentA
passed tof
,atomic_is_lock_free(A)
yieldstrue
.
std::atomic_flag
doesn't fit here formally (there is no is_lock_free
method and atomic_is_lock_free
can't be called with std::atomic_flag
object). Though intuitively, it's very close (it's atomic and lock-free). Does it mean that std::atomic_flag
can't be used in a signal handler, or it's just a C++ standard that needs clarification?
What you have pointed out is a defect in the standard that has been resolved in LWG 3756 Is the std::atomic_flag
class signal-safe?.
The new wording obviously allows for std::atomic_flag
to be used in signal handlers:
A plain lock-free atomic operation is an invocation of a function
f
from [atomics], such that:
- [...]
f
is a non-static member function of classatomic_flag
, orf
is a non-member function, and the first parameter off
has type cvatomic_flag*
, or- [...]
An evaluation is signal-safe unless it includes one of the following:
- a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe;
- [...]
It's probably safe to assume that std::atomic_flag
is signal-safe in any standard prior to C++23 too, given that it's intended to be, and basically satisfies the requirements, even if not technically.