Name Description Size Coverage
half_lock.rs The half-lock structure We need a way to protect the structure with configured hooks ‒ a signal may happen in arbitrary thread and needs to read them while another thread might be manipulating the structure. Under ordinary circumstances we would be happy to just use `Mutex<HashMap<c_int, _>>`. However, as we use it in the signal handler, we are severely limited in what we can or can't use. So we choose to implement kind of spin-look thing with atomics. In the reader it is always simply locked and then unlocked, making sure it doesn't disappear while in use. The writer has a separate mutex (that prevents other writers; this is used outside of the signal handler), makes a copy of the data and swaps an atomic pointer to the data structure. But it waits until everything is unlocked (no signal handler has the old data) for dropping the old instance. There's a generation trick to make sure that new signal locks another instance. The downside is, this is an active spin lock at the writer end. However, we assume than: * Signals are one time setup before we actually have threads. We just need to make *sure* we are safe even if this is not true. * Signals are rare, happening at the same time as the write even rarer. * Signals are short, as there is mostly nothing allowed inside them anyway. * Our tool box is severely limited. Therefore this is hopefully reasonable trade-off. # Atomic orderings The whole code uses SeqCst conservatively. Atomics are not used because of performance here and are the minor price around signals anyway. But the comments state which orderings should be enough in practice in case someone wants to get inspired (but do make your own check through them anyway). 9022 -
lib.rs Backend of the [signal-hook] crate. The [signal-hook] crate tries to provide an API to the unix signals, which are a global resource. Therefore, it is desirable an application contains just one version of the crate which manages this global resource. But that makes it impossible to make breaking changes in the API. Therefore, this crate provides very minimal and low level API to the signals that is unlikely to have to change, while there may be multiple versions of the [signal-hook] that all use this low-level API to provide different versions of the high level APIs. It is also possible some other crates might want to build a completely different API. This split allows these crates to still reuse the same low-level routines in this crate instead of going to the (much more dangerous) unix calls. # What this crate provides The only thing this crate does is multiplexing the signals. An application or library can add or remove callbacks and have multiple callbacks for the same signal. It handles dispatching the callbacks and managing them in a way that uses only the [async-signal-safe] functions inside the signal handler. Note that the callbacks are still run inside the signal handler, so it is up to the caller to ensure they are also [async-signal-safe]. # What this is for This is a building block for other libraries creating reasonable abstractions on top of signals. The [signal-hook] is the generally preferred way if you need to handle signals in your application and provides several safe patterns of doing so. # Rust version compatibility Currently builds on 1.26.0 an newer and this is very unlikely to change. However, tests require dependencies that don't build there, so tests need newer Rust version (they are run on stable). Note that this ancient version of rustc no longer compiles current versions of `libc`. If you want to use rustc this old, you need to force your dependency resolution to pick old enough version of `libc` (`0.2.156` was found to work, but newer ones may too). # Portability This crate includes a limited support for Windows, based on `signal`/`raise` in the CRT. There are differences in both API and behavior: - Due to lack of `siginfo_t`, we don't provide `register_sigaction` or `register_unchecked`. - Due to lack of signal blocking, there's a race condition. After the call to `signal`, there's a moment where we miss a signal. That means when you register a handler, there may be a signal which invokes neither the default handler or the handler you register. - Handlers registered by `signal` in Windows are cleared on first signal. To match behavior in other platforms, we re-register the handler each time the handler is called, but there's a moment where we miss a handler. That means when you receive two signals in a row, there may be a signal which invokes the default handler, nevertheless you certainly have registered the handler. [signal-hook]: https://docs.rs/signal-hook [async-signal-safe]: http://www.man7.org/linux/man-pages/man7/signal-safety.7.html 34447 -
vec_map.rs 4704 -