Struct panic_control::Context
[−]
[src]
pub struct Context<P> { /* fields omitted */ }
The launch pad for a thread checked for the expected panic type.
The generic type Context
serves as the type system's anchor for the
expected type of the panic value, which is given as the type parameter.
It can be constructed from an std::thread::Builder
providing
a customized thread configuration.
The method spawn()
is used to spawn a new thread similarly to
how the function std::thread::spawn()
works. See the documentation
of the spawn()
method for detailed description and examples.
Examples
The example below demonstrates how to construct a Context
from a
configured std::thread::Builder
using the implementation of
the standard trait From
.
use panic_control::Context; use std::thread; #[derive(Debug, PartialEq, Eq)] struct ExpectedToken; let thread_builder = thread::Builder::new() .name("My panicky thread".into()) .stack_size(65 * 1024); let ctx = Context::<ExpectedToken>::from(thread_builder); let h = ctx.spawn(|| { // ... }); h.join().unwrap();
Methods
impl<P: Any> Context<P>
[src]
fn new() -> Context<P>
[src]
Constructs a context with the default thread configuration.
The type parameter can be specified explicitly:
let ctx = Context::<Expected>::new();
fn spawn<T, F>(self, f: F) -> CheckedJoinHandle<T, P> where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
[src]
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
Spawns a new thread taking ownership of the Context
, and
returns the CheckedJoinHandle
for the thread. Other than the
return value, and panicking on an OS failure to create a thread,
this method behaves exactly like the spawn()
method of std::thread::Builder
does, and if the Context
was constructed from a std::thread::Builder
, its
thread configuration will be applied.
Panics
Panics if the underlying call to std::thread::Builder::spawn()
returns an Err
value. Any panics that function can cause apply
as well.
Examples
The example below uses some kludges to work around a compiler quirk:
let ctx = Context::<Expected>::new(); #[allow(unreachable_code)] let h = ctx.spawn(|| { panic!(Expected(42)); () }); let outcome = h.join().unwrap(); assert_eq!(outcome, Outcome::Panicked(Expected(42)));
Note that without the unreachable return expression, the compiler
will have no information to infer the unspecified first type
parameter of Outcome
, so it will settle on a default type that
is subject to future change. In preparation to get the never_type
feature stabilized in the compiler, code like this is
denied by a lint:
let ctx = Context::<Expected>::new(); let h = ctx.spawn(|| { panic!(Expected(42)); }); let outcome = h.join().unwrap(); assert_eq!(outcome, Outcome::Panicked(Expected(42)));
A way to avoid the future incompatibility without resorting
to warning overrides is to match the Outcome
value without
touching the sensitive parts:
let ctx = Context::<Expected>::new(); let h = ctx.spawn(|| { panic!(Expected(42)); }); let outcome = h.join().unwrap(); match outcome { Outcome::Panicked(Expected(n)) => assert_eq!(n, 42), _ => panic!("join() returned an unexpected Outcome value") }
fn spawn_quiet<T, F>(self, f: F) -> CheckedJoinHandle<T, P> where
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
[src]
F: FnOnce() -> T,
F: Send + 'static,
T: Send + 'static,
Like spawn()
, but disables the panic hook
if the spawned thread panics.
The process-global panic hook, either installed with
std::panic::set_hook()
or the standard library default,
gets augmented with a filter that disables invocation of the
hook closure if the spawned thread panics.
This function can be used in any order together with other functions and methods of this crate that modify the panic hook.
Caveats
Note that the suppression can apply to the default panic hook
that is normally used to report assertion failures and other
unexpected panics on the standard error stream.
The only remaining way to observe the panic is by checking
the result of join()
for the spawned thread.
Other code within the program that modifies the panic hook,
concurrently to, or after, a call to this function, may cause
the suppression not to work as intended. See the documentation
on the function disable_hook_in_current_thread()
for possible
pitfalls.
Examples
let ctx = Context::<Expected>::new(); let h = ctx.spawn_quiet(|| { assert!(false, "I'm panicking, \ but you can only learn about it through join()"); }); let res = h.join(); assert!(res.is_err());