MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / suspend

Method suspend

crates/wasmtime/src/runtime/component/concurrent.rs:1951–2006  ·  view source on GitHub ↗

Suspend the current fiber, storing the reason in `ConcurrentState::suspend_reason` to indicate the conditions under which it should be resumed. See the `SuspendReason` documentation for details.

(&mut self, reason: SuspendReason)

Source from the content-addressed store, hash-verified

1949 ///
1950 /// See the `SuspendReason` documentation for details.
1951 fn suspend(&mut self, reason: SuspendReason) -> Result<()> {
1952 log::trace!("suspend fiber: {reason:?}");
1953
1954 // If we're yielding or waiting on behalf of a guest thread, we'll need to
1955 // pop the call context which manages resource borrows before suspending
1956 // and then push it again once we've resumed.
1957 let task = match &reason {
1958 SuspendReason::Yielding { thread, .. }
1959 | SuspendReason::Waiting { thread, .. }
1960 | SuspendReason::ExplicitlySuspending { thread, .. } => Some(thread.task),
1961 SuspendReason::NeedWork => None,
1962 };
1963
1964 let old_guest_thread = if task.is_some() {
1965 self.concurrent_state_mut().current_thread
1966 } else {
1967 CurrentThread::None
1968 };
1969
1970 // We should not have reached here unless either there's no current
1971 // task, or the current task is permitted to block. In addition, we
1972 // special-case `thread.switch-to` and waiting for a subtask to go from
1973 // `starting` to `started`, both of which we consider non-blocking
1974 // operations despite requiring a suspend.
1975 debug_assert!(
1976 matches!(
1977 reason,
1978 SuspendReason::ExplicitlySuspending {
1979 skip_may_block_check: true,
1980 ..
1981 } | SuspendReason::Waiting {
1982 skip_may_block_check: true,
1983 ..
1984 } | SuspendReason::Yielding {
1985 skip_may_block_check: true,
1986 ..
1987 }
1988 ) || old_guest_thread
1989 .guest()
1990 .map(|thread| self.concurrent_state_mut().may_block(thread.task))
1991 .transpose()?
1992 .unwrap_or(true)
1993 );
1994
1995 let suspend_reason = &mut self.concurrent_state_mut().suspend_reason;
1996 assert!(suspend_reason.is_none());
1997 *suspend_reason = Some(reason);
1998
1999 self.with_blocking(|_, cx| cx.suspend(StoreFiberYield::ReleaseStore))?;
2000
2001 if task.is_some() {
2002 self.set_thread(old_guest_thread)?;
2003 }
2004
2005 Ok(())
2006 }
2007
2008 fn wait_for_event(&mut self, waitable: Waitable) -> Result<()> {

Callers 7

poll_and_blockFunction · 0.45
run_on_workerMethod · 0.45
wait_for_eventMethod · 0.45
start_callMethod · 0.45
suspension_intrinsicMethod · 0.45
waitable_checkMethod · 0.45
subtask_cancelMethod · 0.45

Calls 5

OkFunction · 0.85
concurrent_state_mutMethod · 0.80
with_blockingMethod · 0.80
set_threadMethod · 0.80
is_someMethod · 0.45

Tested by

no test coverage detected