Issue 3756: Is the std::atomic_flag class signal-safe? (original) (raw)
This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of C++23 status.
3756. Is the std::atomic_flag class signal-safe?
Section: 17.14.5 [support.signal], 32.5.10 [atomics.flag] Status: C++23 Submitter: Ruslan Baratov Opened: 2022-08-18 Last modified: 2023-11-22
Priority: 3
View all issues with C++23 status.
Discussion:
Following document number N4910 about signal-safe instructions 17.14.5 [support.signal] Signal handlers, and it's unclear whetherstd::atomic_flag is signal-safe.
Formally it doesn't fit any of the mentioned conditions:
fis a non-static member function invoked on an objectA, such thatA.is_lock_free()yieldstrue, or(there is no
is_lock_freemethod instd::atomic_flagclass)fis a non-member function, and for every pointer-to-atomic argumentApassed tof,atomic_is_lock_free(A)yieldstrue(
std::atomic_flagobject can't be passed toatomic_is_lock_freeas argument)
However, std::atomic_flag seem to fit well here, it's atomic, and it's always lock-free.
The suggestion is as follows: If std::atomic_flag is signal-safe, then it should be explicitly mentioned in 17.14.5 [support.signal], e.g., the following lines should be added:
fis a non-static member function invoked on anatomic_flagobject, orfis a non-member function, and every pointer-to-atomic argument passed tofisatomic_flag, or
If the std::atomic_flag is not signal-safe, the following note could be added:
[Note: Even though
atomic_flagis atomic and lock-free, it's not signal-safe. — _end note_]
[2022-09-23; Reflector poll]
Set priority to 3 after reflector poll. Send to SG1.
Another way to fix this is to add is_always_lock_free (=true) andis_lock_free() { return true; } to atomic_flag.
[Kona 2022-11-10; SG1 yields a recommendation]
Poll: Adopt the proposed resolution for LWG3756
"f is a non-static member function invoked on an atomic_flag object, or"
"f is a non-member function, and every pointer-to- atomic argument passed to f is atomic_flag, or"
SF F N A SA 11 3 0 0 0
Unanimous consent
Previous resolution [SUPERSEDED]:
This wording is relative to N4917.
- Modify 17.14.5 [support.signal] as indicated:
-1- A call to the function
signalsynchronizes with any resulting invocation of the signal handler so installed.-2- A plain lock-free atomic operation is an invocation of a function
ffrom 32.5 [atomics], such that:
- (2.1) —
fis the functionatomic_is_lock_free(), or- (2.2) —
fis the member functionis_lock_free(), or- (2.?) —
fis a non-static member function invoked on anatomic_flagobject, or- (2.?) —
fis a non-member function, and every pointer-to-atomic argument passed tofisatomic_flag, or- (2.3) —
fis a non-static member function invoked on an objectA, such thatA.is_lock_free()yieldstrue, or- (2.4) —
fis a non-member function, and for every pointer-to-atomic argumentApassed tof,atomic_is_lock_free(A)yieldstrue.-3- An evaluation is signal-safe unless it includes one of the following:
- (3.1) — a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe;
[Note 1: This implicitly excludes the use ofnewanddeleteexpressions that rely on a library-provided memory allocator. — _end note_]- (3.2) — an access to an object with thread storage duration;
- (3.3) — a
dynamic_castexpression;- (3.4) — throwing of an exception;
- (3.5) — control entering a try-block or function-try-block;
- (3.6) — initialization of a variable with static storage duration requiring dynamic initialization (6.10.3.3 [basic.start.dynamic], 8.10 [stmt.dcl])206; or
- (3.7) — waiting for the completion of the initialization of a variable with static storage duration (8.10 [stmt.dcl]).
A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.
[2022-11-11; Jonathan provides improved wording]
[Kona 2022-11-11; Move to Ready]
[2023-02-13 Approved at February 2023 meeting in Issaquah. Status changed: Voting → WP.]
Proposed resolution:
This wording is relative to N4917.
- Modify 17.14.5 [support.signal] as indicated:
-1- A call to the function
signalsynchronizes with any resulting invocation of the signal handler so installed.-2- A plain lock-free atomic operation is an invocation of a function
ffrom 32.5 [atomics], such that:- (2.1) —
fis the functionatomic_is_lock_free(), or - (2.2) —
fis the member functionis_lock_free(), or - (2.?) —
fis a non-static member function of classatomic_flag, or - (2.?) —
fis a non-member function, and the first parameter offhas type cvatomic_flag*, or - (2.3) —
fis a non-static member function invoked on an objectA, such thatA.is_lock_free()yieldstrue, or - (2.4) —
fis a non-member function, and for every pointer-to-atomic argumentApassed tof,atomic_is_lock_free(A)yieldstrue.
-3- An evaluation is signal-safe unless it includes one of the following:
- (3.1) — a call to any standard library function, except for plain lock-free atomic operations and functions explicitly identified as signal-safe;
[Note 1: This implicitly excludes the use ofnewanddeleteexpressions that rely on a library-provided memory allocator. — _end note_] - (3.2) — an access to an object with thread storage duration;
- (3.3) — a
dynamic_castexpression; - (3.4) — throwing of an exception;
- (3.5) — control entering a try-block or function-try-block;
- (3.6) — initialization of a variable with static storage duration requiring dynamic initialization (6.10.3.3 [basic.start.dynamic], 8.10 [stmt.dcl])206; or
- (3.7) — waiting for the completion of the initialization of a variable with static storage duration (8.10 [stmt.dcl]).
A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.
- (2.1) —