This page is a snapshot from the LWG issues list, see the Library Active Issues List for more information and the meaning of Ready status.

### 3756. Is the `std::atomic_flag` class signal-safe?

Section: 17.14.5 [support.signal], 33.5.10 [atomics.flag] Status: Ready Submitter: Ruslan Baratov Opened: 2022-08-18 Last modified: 2022-11-11

Priority: 3

View all issues with Ready status.

Discussion:

Following document number N4910 about signal-safe instructions 17.14.5 [support.signal] Signal handlers, and it's unclear whether `std::atomic_flag` is signal-safe.

Formally it doesn't fit any of the mentioned conditions:

- `f` is a non-static member function invoked on an object `A`, such that `A.is_lock_free()` yields `true`, or

  > (there is no `is_lock_free` method in `std::atomic_flag` class)

- `f` is a non-member function, and for every pointer-to-atomic argument `A` passed to `f`, `atomic_is_lock_free(A)` yields `true`

  > (`std::atomic_flag` object can't be passed to `atomic_is_lock_free` as 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:

> - `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

If the `std::atomic_flag` is not signal-safe, the following note could be added:

> [Note: Even though `atomic_flag` is 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)` and `is_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.

> 1. Modify 17.14.5 [support.signal] as indicated:

>    > -1- A call to the function `signal` synchronizes with any resulting invocation of the signal handler so installed.

>    > -2- A plain lock-free atomic operation is an invocation of a function `f` from 33.5 [atomics], such that:

>    > 1. (2.1) — `f` is the function `atomic_is_lock_free()`, or
>    > 2. (2.2) — `f` is the member function `is_lock_free()`, or
>    > 3. (2.?) — `f` is a non-static member function invoked on an `atomic_flag` object, or
>    > 4. (2.?) — `f` is a non-member function, and every pointer-to-atomic argument passed to `f` is `atomic_flag`, or
>    > 5. (2.3) — `f` is a non-static member function invoked on an object `A`, such that `A.is_lock_free()` yields `true`, or
>    > 6. (2.4) — `f` is a non-member function, and for every pointer-to-atomic argument `A` passed to `f`, `atomic_is_lock_free(A)` yields `true`.

>    > -3- An evaluation is signal-safe unless it includes one of the following:

>    > 1. (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 of `new` and `delete` expressions that rely on a library-provided memory allocator. — end note]

>    > 2. (3.2) — an access to an object with thread storage duration;
>    > 3. (3.3) — a `dynamic_cast` expression;
>    > 4. (3.4) — throwing of an exception;
>    > 5. (3.5) — control entering a try-block or function-try-block;
>    > 6. (3.6) — initialization of a variable with static storage duration requiring dynamic initialization (6.9.3.3 [basic.start.dynamic], 8.8 [stmt.dcl])206; or
>    > 7. (3.7) — waiting for the completion of the initialization of a variable with static storage duration (8.8 [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]

Proposed resolution:

This wording is relative to N4917.

1. Modify 17.14.5 [support.signal] as indicated:

   > -1- A call to the function `signal` synchronizes with any resulting invocation of the signal handler so installed.

   > -2- A plain lock-free atomic operation is an invocation of a function `f` from 33.5 [atomics], such that:

   > 1. (2.1) — `f` is the function `atomic_is_lock_free()`, or
   > 2. (2.2) — `f` is the member function `is_lock_free()`, or
   > 3. (2.?) — `f` is a non-static member function of class `atomic_flag`, or
   > 4. (2.?) — `f` is a non-member function, and the first parameter of `f` has type cv `atomic_flag*`, or
   > 5. (2.3) — `f` is a non-static member function invoked on an object `A`, such that `A.is_lock_free()` yields `true`, or
   > 6. (2.4) — `f` is a non-member function, and for every pointer-to-atomic argument `A` passed to `f`, `atomic_is_lock_free(A)` yields `true`.

   > -3- An evaluation is signal-safe unless it includes one of the following:

   > 1. (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 of `new` and `delete` expressions that rely on a library-provided memory allocator. — end note]

   > 2. (3.2) — an access to an object with thread storage duration;
   > 3. (3.3) — a `dynamic_cast` expression;
   > 4. (3.4) — throwing of an exception;
   > 5. (3.5) — control entering a try-block or function-try-block;
   > 6. (3.6) — initialization of a variable with static storage duration requiring dynamic initialization (6.9.3.3 [basic.start.dynamic], 8.8 [stmt.dcl])206; or
   > 7. (3.7) — waiting for the completion of the initialization of a variable with static storage duration (8.8 [stmt.dcl]).

   > A signal handler invocation has undefined behavior if it includes an evaluation that is not signal-safe.