wasmer_wasix/syscalls/wasix/
thread_join.rs

1use std::task::Waker;
2
3use super::*;
4use crate::syscalls::*;
5
6/// ### `thread_join()`
7/// Joins this thread with another thread, blocking this
8/// one until the other finishes
9///
10/// ## Parameters
11///
12/// * `tid` - Handle of the thread to wait on
13//#[instrument(level = "trace", skip_all, fields(%join_tid), ret)]
14pub fn thread_join<M: MemorySize + 'static>(
15    mut ctx: FunctionEnvMut<'_, WasiEnv>,
16    join_tid: Tid,
17) -> Result<Errno, WasiError> {
18    WasiEnv::do_pending_operations(&mut ctx)?;
19
20    thread_join_internal::<M>(ctx, join_tid)
21}
22
23pub(super) fn thread_join_internal<M: MemorySize + 'static>(
24    mut ctx: FunctionEnvMut<'_, WasiEnv>,
25    join_tid: Tid,
26) -> Result<Errno, WasiError> {
27    if let Some(_child_exit_code) = unsafe { handle_rewind::<M, i32>(&mut ctx) } {
28        return Ok(Errno::Success);
29    }
30
31    ctx = wasi_try_ok!(maybe_snapshot::<M>(ctx)?);
32
33    let env = ctx.data();
34    let tid: WasiThreadId = join_tid.into();
35    let other_thread = env.process.get_thread(&tid);
36    if let Some(other_thread) = other_thread {
37        let res = __asyncify_with_deep_sleep::<M, _, _>(ctx, async move {
38            other_thread
39                .join()
40                .await
41                .map_err(|err| err.as_exit_code().unwrap_or(ExitCode::from(Errno::Unknown)))
42                .unwrap_or_else(|a| a)
43                .raw()
44        })?;
45        Ok(Errno::Success)
46    } else {
47        Ok(Errno::Success)
48    }
49}