Doc. No.: WG21/N2547
J16/08-0057
Revision of: WG21/N2459
J16/07-0329
Date: 2008-02-27
Reply to: Hans-J. Boehm
Phone: +1-650-857-3406
Email: Hans.Boehm@hp.com

N2547: Allow atomics use in signal handlers

The atomics operations library (N2427, accepted into the working paper at the Kona meeting) was designed to support several different applications:
  1. To communicate between threads in cases in which other synchronization mechanisms such as locks are less appropriate.
  2. To communicate between processes when other synchronization mechanisms do not support it suitably.
  3. To allow for communication with signal handlers.
In the last case, locks are generally not usable since the signal handler may have interrupted a thread holding a lock. Depending on whether the lock is reentrant, an attempt to acquire the lock in the handler would either result in deadlock, or in two logically distinct tasks acquiring the lock at the same time.

The first of the applications listed above is already supported by N2427. The second cannot really be addressed by the C++ standard. Here we propose to allow the use of atomics in signal handlers, to the extent that is under control of the C++ standard.

Our intent is to allow full use of atomic operations on atomic object x in a signal handler whenever atomic_is_lock_free(x) or x.is_lock_free() is true. For example, in a Posix environment, these operations are intended to be async-signal-safe. But that is clearly beyond the scope of this standard.

Proposed wording changes

The current working paper gives rules for signal handler actions in two places. We propose to change them as follows:

1.9p7:

When the processing of the abstract machine is interrupted by receipt of a signal, the values of objects with type other than volatile std::sig_atomic_t which are neither are unspecified, and the value of any object not of type volatile std::sig_atomic_t in either of these two categories that is modified by the handler becomes undefined.

18.8p6

The common subset of the C and C++ languages consists of all declarations, definitions, and expressions that may appear in a well formed C++ program and also in a conforming C program. A POF (plain old function) is a function that uses only features from this common subset, and that does not directly or indirectly use any function that is not a POF, except that it may use functions defined in clause 29[atomics] that are not member functions. All signal handlers shall have C linkage. A POF that could be used as a signal handler in a conforming C program does not produce undefined behavior when used as a signal handler in a C++ program. The behavior of any other function used as a signal handler in a C++ program is implementation-defined.

The second change is essentially a stopgap measure, which we expect to become redundant when atomics are accepted into the C standard. It is not clear that omitting the second change would cause real problems, though it seems a bit safer to include it.