Signal semantics for Rust

⚓ Rust    📅 2026-04-20    👤 surdeus    👁️ 3      

surdeus

Info

This post is auto-generated from RSS feed The Rust Programming Language Forum - Latest topics. Source: Signal semantics for Rust

Hello everyone!

Some operating systems have a concept of asynchronous signals -- an external events that can interrupt the control flow of a thread and cause it to execute a special function, called a signal handler. A control flow can be redirected into a signal handler from any point at which the signal is not blocked, which makes installing signal handlers very unsafe and requires caution while implementing a signal handler. C and C++ standards, as well as POSIX, specify what a signal is and what semantics they have, and what a signal handler can safely do.

I wonder, are there signal semantics in Rust? Specifically, regarding:

  • What functions from the standard library can be called from a signal handler? The Rust standard library is separated into three parts: core (language features), alloc (high-level interface to the memory allocator) and std (interaction with the operating system). As far as I understand, alloc and std shouldn't (generally) be assumed to be async-signal-safe. I wonder, which parts of core are safe for signal handlers and which are not? As far as I understand, panicking is not async-signal-safe because a panic handler may be async-signal-unsafe. I wonder, what about other parts, and specifically the formatting system (core::fmt)?
  • Allowed interactions with global objects. C and C++ allow signal handlers to only interact with global lock-free atomics and volatile sig_atomic_t objects. As far as I understand, the latter is a workaround for standards before C11 and C++11 (because such standards do not describe what an actual atomic variable is) and is thread-unsafe (it's still data race and undefined behavior if a signal handler from one thread assigns a global volatile sig_atomic_t and the other thread reads it at the same time). The proper way is to use atomics (core::sync::atomic). In Rust, there is no such thing as "non-lock-free atomics" (if there is no hardware support for atomic operations on certain type, then C or C++ compiler may emulate it with locking, while this is not allowed in Rust -- if there is no support for atomic operations on a certain integer type, then the corresponding atomic type is not provided)
  • I also wonder about libc implementations that provide async-signal-safe thread-local variables (such as musl). Can Rust thread_local! variable be accessed from a signal handler if it's built with musl? What happens if a signal arrives while a thread-local Cell is in the process of being modified?

2 posts - 2 participants

Read full topic

🏷️ Rust_feed