pub fn block_on_sync<F: Future>(fut: F) -> Result<F::Output, NotBlockable>Expand description
Block the calling thread on fut, picking the mechanism that is sound for
the thread we are actually on.
This is the single owner of “sync call over async state” in this crate; the four caller contexts are not interchangeable and picking one mechanism for all of them is what makes such bridges panic:
- A background-facility worker —
Err(BackgroundWorker), checked first, because it is a property of the thread and holds whatever runtime is or is not entered on it. Seebackground::facility::on_facility_threadfor why parking one is unsound. - No runtime entered (a plain
std::thread, an iocsh thread) — park the thread. Nothing else runs here, so there is nothing to starve; the tasks that will wake us live on some other runtime’s threads. - Multi-thread runtime worker —
tokio::task::block_in_place, which hands this worker’s remaining tasks to a sibling before it is parked. - Current-thread runtime —
Err(CurrentThreadRuntime). Parking the only thread of that runtime halts every task on it, including the one that would wake us.
The two refusals are reported to the caller rather than panicked on (today) or deadlocked on (the worse alternative) — an illegal blocking bridge is a value the caller must handle, not a review item.