|
WG14 threadsafe signals
|

Go to the source code of this file.
Classes | |
| union | stdc_siginfo_value |
| User defined value. More... | |
| struct | stdc_siginfo |
| A platform independent subset of siginfo_t. More... | |
Typedefs | |
| typedef int | stdc_siginfo_error_code_t |
| Typedef to a system specific error code type. | |
| typedef struct __siginfo | stdc_siginfo_siginfo_t |
| A placeholder type for an OS specific siginfo_t * (POSIX) or PEXCEPTION_RECORD (Windows). | |
| typedef ucontext_t | stdc_siginfo_context_t |
| A placeholder type for an OS specific ucontext_t (POSIX) or PCONTEXT (Windows). | |
Enumerations | |
| enum | sig_decision_t { sig_decision_next_decider , sig_decision_resume_execution , sig_decision_call_recovery } |
| The decision taken by the decider function. More... | |
Functions | |
| union stdc_siginfo_value | sig_func_t (union stdc_siginfo_value) |
| The type of the guarded function. | |
| union stdc_siginfo_value | sig_recover_t (const struct stdc_siginfo *) |
| The type of the function called to recover from a signal being raised in a guarded section. | |
| enum sig_decision_t | sig_decide_t (struct stdc_siginfo *) |
| The type of the function called when a signal is raised. Returns a decision of how to handle the signal. | |
| int | sigfillset_synchronous (sigset_t *set) |
| THREADSAFE ASYNC-SIGNAL-SAFE Fills the set of synchronous signals for this platform. | |
| int | sigfillset_asynchronous_nondebug (sigset_t *set) |
| THREADSAFE ASYNC-SIGNAL-SAFE Fills the set of non-debug asynchronous signals for this platform. | |
| int | sigfillset_asynchronous_debug (sigset_t *set) |
| THREADSAFE ASYNC-SIGNAL-SAFE Fille the set of debug asynchronous signals for this platform. | |
| union stdc_siginfo_value | sigguarded (const sigset_t *signals, sig_func_t guarded, sig_recover_t recovery, sig_decide_t decider, union stdc_siginfo_value value) |
| THREADSAFE USUALLY ASYNC-SIGNAL-SAFE Installs a thread-local signal guard for the calling thread, and calls the guarded function guarded. | |
| void | sigdecider_abandon (struct stdc_siginfo *rsi) |
| THREADSAFE ASYNC-SIGNAL-SAFE Lets the decider machinery know you won't be returning into it. Can be called from within sigguarded()'s decider functions or global deciders. You must NOT call this from within a recovery. | |
| void | sigdecider_abandon_resume (struct stdc_siginfo *rsi) |
| THREADSAFE ASYNC-SIGNAL-SAFE Undoes a prior call of sigdecider_abandon(). Do not call except from the same decider function previously abandoned. | |
| bool | stdc_raise (int signo, stdc_siginfo_siginfo_t *raw_info, stdc_siginfo_context_t *raw_context) |
| THREADSAFE USUALLY ASYNC-SIGNAL-SAFE Call OUR currently installed signal decider for a signal (POSIX), or raise a Win32 structured exception (Windows), returning false if we have no decider installed for that signal. | |
| void * | siginstall (const sigset_t *guarded) |
| THREADSAFE Installs, and potentially enables, the global signal handlers for the signals specified by guarded. Each signal installed is threadsafe reference counted, so this is safe to call from multiple threads or instantiate multiple times. | |
| int | siguninstall (void *i) |
| THREADSAFE Uninstall a previously installed signal guard. | |
| int | siguninstall_system (int version) |
| THREADSAFE Uninstall a previously system installed signal guard. | |
| void * | signal_decider_create (const sigset_t *guarded, bool callfirst, sig_decide_t decider, union stdc_siginfo_value value) |
| THREADSAFE NOT REENTRANT Create a global signal continuation decider. Threadsafe with respect to other calls of this function, but not reentrant i.e. modifying the global signal continuation decider registry whilst inside a global signal continuation decider is racy, and in any case definitely not async signal handler safe. Called after all thread local handling is exhausted. Note that what you can safely do in the decider function is extremely limited, only async signal safe functions may be called. | |
| int | signal_decider_destroy (void *decider) |
| THREADSAFE NOT REENTRANT Destroy a global signal continuation decider. Threadsafe with respect to other calls of this function, but not reentrant i.e. do not call whilst inside a global signal continuation decider. Passing a handle that has already been destroyed is undefined behaviour: this reference implementation deliberately does not guard against it (plans/analysis.md DEDE). | |
| #define sigfence | ( | ... | ) |
A compiler-only memory barrier, including for local variables in the argument list. Any variable in the argument list MUST be a lvalue.
Definition at line 329 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_BARRIER | ( | ) |
Definition at line 232 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_CALL_OVERLOAD | ( | name, | |
| ... ) |
Definition at line 153 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_COUNT_ARGS_MAX8 | ( | ... | ) |
Definition at line 145 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_ESCAPE | ( | a, | |
| i ) |
Definition at line 235 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_EXPAND_ARGS | ( | args | ) |
Definition at line 115 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_GLUE | ( | x, | |
| y ) |
Definition at line 111 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_0 | ( | ) |
Definition at line 241 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_1 | ( | a | ) |
Definition at line 242 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_2 | ( | a, | |
| b ) |
Definition at line 249 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_3 | ( | a, | |
| b, | |||
| c ) |
Definition at line 257 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_4 | ( | a, | |
| b, | |||
| c, | |||
| d ) |
Definition at line 266 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_5 | ( | a, | |
| b, | |||
| c, | |||
| d, | |||
| e ) |
Definition at line 276 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_6 | ( | a, | |
| b, | |||
| c, | |||
| d, | |||
| e, | |||
| f ) |
Definition at line 287 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_7 | ( | a, | |
| b, | |||
| c, | |||
| d, | |||
| e, | |||
| f, | |||
| g ) |
Definition at line 299 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_IMPL_8 | ( | a, | |
| b, | |||
| c, | |||
| d, | |||
| e, | |||
| f, | |||
| g, | |||
| h ) |
Definition at line 312 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_OVERLOAD_MACRO | ( | name, | |
| count ) |
Definition at line 151 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_OVERLOAD_MACRO1 | ( | name, | |
| count ) |
Definition at line 149 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_OVERLOAD_MACRO2 | ( | name, | |
| count ) |
Definition at line 148 of file thrd_signal_handle.h.
| #define WG14_SIGNALS_SIGFENCE_RETURN_ARG_COUNT | ( | _1_, | |
| _2_, | |||
| _3_, | |||
| _4_, | |||
| _5_, | |||
| _6_, | |||
| _7_, | |||
| _8_, | |||
| count, | |||
| ... ) |
Definition at line 112 of file thrd_signal_handle.h.
| typedef ucontext_t stdc_siginfo_context_t |
A placeholder type for an OS specific ucontext_t (POSIX) or PCONTEXT (Windows).
Definition at line 394 of file thrd_signal_handle.h.
| typedef int stdc_siginfo_error_code_t |
Typedef to a system specific error code type.
Definition at line 368 of file thrd_signal_handle.h.
| typedef struct __siginfo stdc_siginfo_siginfo_t |
A placeholder type for an OS specific siginfo_t * (POSIX) or PEXCEPTION_RECORD (Windows).
Definition at line 386 of file thrd_signal_handle.h.
| enum sig_decision_t |
The decision taken by the decider function.
| Enumerator | |
|---|---|
| sig_decision_next_decider | We have decided to do nothing. |
| sig_decision_resume_execution | We have fixed the cause of the signal, please resume execution. |
| sig_decision_call_recovery | Thread local signal deciders only: reset the stack and local state to entry to sigguarded(), and call the recovery function. |
Definition at line 448 of file thrd_signal_handle.h.
| enum sig_decision_t sig_decide_t | ( | struct stdc_siginfo * | ) |
The type of the function called when a signal is raised. Returns a decision of how to handle the signal.
| union stdc_siginfo_value sig_func_t | ( | union stdc_siginfo_value | ) |
The type of the guarded function.
| union stdc_siginfo_value sig_recover_t | ( | const struct stdc_siginfo * | ) |
The type of the function called to recover from a signal being raised in a guarded section.
|
extern |
THREADSAFE ASYNC-SIGNAL-SAFE Lets the decider machinery know you won't be returning into it. Can be called from within sigguarded()'s decider functions or global deciders. You must NOT call this from within a recovery.
If called within a local decider, it MUST be the topmost sigguarded() for the current thread, and it will effectively abandon the current sigguarded().
| rsi | The siginfo passed to the decider function. |
|
extern |
THREADSAFE ASYNC-SIGNAL-SAFE Undoes a prior call of sigdecider_abandon(). Do not call except from the same decider function previously abandoned.
| rsi | The siginfo passed to the decider function. |
|
extern |
THREADSAFE ASYNC-SIGNAL-SAFE Fille the set of debug asynchronous signals for this platform.
Debug asynchronous signals are those which are delivered by the system to notify the process about some event which defaults to resulting in a core dump. This set can include platform-specific additions, however at least these POSIX signals are within this set:
SIGQUIT SIGTRAP SIGXCPU SIGXFSZ
|
extern |
THREADSAFE ASYNC-SIGNAL-SAFE Fills the set of non-debug asynchronous signals for this platform.
Non-debug asynchronous signals are those which are delivered by the system to notify the process about some event which does not default to resulting in a core dump. This set can include platform-specific additions, however at least these POSIX signals are within this set:
SIGALRM SIGCHLD SIGCONT SIGHUP SIGINT SIGKILL SIGSTOP SIGTERM SIGTSTP SIGTTIN SIGTTOU SIGUSR1 SIGUSR2 SIGPOLL SIGPROF SIGURG SIGVTALRM
|
extern |
THREADSAFE ASYNC-SIGNAL-SAFE Fills the set of synchronous signals for this platform.
Synchronous signals are those which can be raised by a thread in the course of its execution. This set can include platform-specific additions, however at least these POSIX signals are within this set:
SIGABRT SIGBUS SIGFPE SIGILL SIGPIPE SIGSEGV SIGSYS
|
extern |
THREADSAFE USUALLY ASYNC-SIGNAL-SAFE Installs a thread-local signal guard for the calling thread, and calls the guarded function guarded.
| signals | The set of signals to guard against. |
| guarded | A function whose execution is to be guarded against signal raises. |
| recovery | A function to be called if a signal is raised. |
| decider | A function to be called to decide whether to recover from the signal and continue the execution of the guarded routine, or to abort and call the recovery routine. |
| value | A value to supply to the guarded routine. |
By "usually async signal safe" we mean that if any function from this library has been called from the called from the calling thread, this is async signal safe. If you need to set up this library for a calling thread without doing anything else, calling stdc_raise(0, nullptr, nullptr), this will ensure the calling thread's thread local state is set up and return immediately doing nothing else.
If you will never return from decider, you must call sigdecider_abandon() to let the runtime clean up its state. If after abandonment you realise that you actually shall return, you can call sigdecider_abandon_resume() to undo the abandonment.
|
extern |
THREADSAFE Installs, and potentially enables, the global signal handlers for the signals specified by guarded. Each signal installed is threadsafe reference counted, so this is safe to call from multiple threads or instantiate multiple times.
If guarded is null, all the standard POSIX signals are used.
Any existing global signal handlers are replaced with a filtering signal handler, which checks if the current kernel thread has installed a signal guard, and if so executes the guard. If no signal guard has been installed for the current kernel thread, global signal continuation handlers are executed. If none claims the signal, the previously installed signal handler is called.
After the new signal handlers have been installed, the guarded signals are globally enabled for all threads of execution. Be aware that the handlers are installed with SA_NODEFER to avoid the need to perform an expensive syscall when a signal is handled. However this may also produce surprise e.g. infinite loops.
|
extern |
THREADSAFE NOT REENTRANT Create a global signal continuation decider. Threadsafe with respect to other calls of this function, but not reentrant i.e. modifying the global signal continuation decider registry whilst inside a global signal continuation decider is racy, and in any case definitely not async signal handler safe. Called after all thread local handling is exhausted. Note that what you can safely do in the decider function is extremely limited, only async signal safe functions may be called.
| guarded | The set of signals to be guarded against. |
| callfirst | True if this decider should be called before any other. Otherwise call order is in the order of addition. |
| decider | A decider function, which must return true if execution is to resume, false if the next decider function should be called. |
| value | A user supplied value to set in the raised_signal_info passed to the decider callback. |
|
extern |
THREADSAFE NOT REENTRANT Destroy a global signal continuation decider. Threadsafe with respect to other calls of this function, but not reentrant i.e. do not call whilst inside a global signal continuation decider. Passing a handle that has already been destroyed is undefined behaviour: this reference implementation deliberately does not guard against it (plans/analysis.md DEDE).
|
extern |
THREADSAFE Uninstall a previously installed signal guard.
|
extern |
THREADSAFE Uninstall a previously system installed signal guard.
|
extern |
THREADSAFE USUALLY ASYNC-SIGNAL-SAFE Call OUR currently installed signal decider for a signal (POSIX), or raise a Win32 structured exception (Windows), returning false if we have no decider installed for that signal.
Note that on POSIX, we fetch OUR currently installed signal decider and call it directly. This allows us to supply custom raw_info and raw_context. Each decider in our chain will be invoked in turn until we reach whatever the signal handler was when this library was first initialised, and we hand off to that handler. If that handler was defaulted and the default handling is not to ignore, we reset the handler installation and execute pthread_kill(pthread_self(), signo) in order to invoke the default handling.
It is important to note that this call does not raise signals itself except in that final handling step as just described. Therefore, if your code overwrites the signal handlers installed by this library with a custom handler, and you wish to pass on signal handling to this library, this is the right API to call to do that.
On Windows, Win32 structured exceptions are capable of being used directly and so we do on that platform always call RaiseException().
By "usually async signal safe" we mean that if any function from this library has been called from the called from the calling thread, this is async signal safe. If you need to set up this library for a calling thread without doing anything else, specify zero for signo, this will ensure the calling thread's thread local state is set up and return immediately doing nothing else. The call returns false both when no decider claims the signal and when the per-thread setup fails; on setup failure errno is set (e.g. ENOMEM) so a caller of the setup form (signo == 0) can detect that setup actually failed (plans/analysis.md 3.7).