Expand description
Scoped goroutines — safe short-lived borrows.
scope is the goroutine equivalent of std::thread::scope: every
goroutine spawned through the Scope handle is guaranteed to finish
before scope returns, so the closures may safely borrow data from the
calling goroutine’s stack frame without a 'static bound.
§How the lifetime safety works
The two lifetime parameters on Scope<'scope, 'env> encode the
invariant:
'env— the lifetime of data that goroutines are allowed to borrow (e.g. a&Vec<i32>from the surrounding function).'scope— the lifetime of theScopereference itself; it lasts exactly as long as the closure passed toscoperuns.- The bound
'env: 'scopeensures that borrowed data outlives the scope.
Inside Scope::go the closure’s 'scope lifetime is erased to
'static (via transmute) so it can be handed to the scheduler. This is
sound because scope blocks (via WaitGroup::wait) until every spawned
goroutine has called wg.done(), which happens only after the closure
returns or panics — so no goroutine can outlive 'scope.
§Panic behaviour
go-lib goroutines are scheduled M:N across OS threads. Rust’s panic
unwinding relies on C++ exception-handling (EH) machinery whose landing
pads are registered per-OS-thread. Calling std::panic::resume_unwind
after a goroutine has been parked and resumed (potentially on a different
OS thread) would silently bypass the inner landing pad and reach the outer
goroutine_entry catch — crashing.
Therefore:
ScopedJoinHandle::joinreturnsstd::thread::Result<R>rather thanR, so the caller decides how to handle a scoped goroutine’s panic without crossing any scheduling boundary.- If the outer scope closure itself panics,
scopecatches it, waits for all goroutines, and then re-raises it withstd::panic::panic_any— which starts a fresh panic on the current OS thread, always finding the correct landing pad.
§Example
go_lib::run(|| {
let data = vec![1_i64, 2, 3, 4, 5];
let sum = go_lib::scope(|s| {
let h1 = s.go(|| data[..3].iter().sum::<i64>());
let h2 = s.go(|| data[3..].iter().sum::<i64>());
h1.join().unwrap() + h2.join().unwrap()
});
assert_eq!(sum, 15);
});Structs§
- Scope
- A scope for spawning goroutines with bounded lifetimes.
- Scoped
Join Handle - A handle to a goroutine spawned inside a
Scope.
Functions§
- scope
- Run a closure that can spawn short-lived goroutines borrowing local data.