use crate::{WasiEnv, WasiError};
use tracing::instrument;
use wasmer::{AsStoreRef, FunctionEnvMut, MemoryView};
use wasmer_wasix_types::wasi::Errno;
#[instrument(level = "trace", skip(ctx), ret)]
pub fn context_destroy(
mut ctx: FunctionEnvMut<'_, WasiEnv>,
target_context_id: u64,
) -> Result<Errno, WasiError> {
WasiEnv::do_pending_operations(&mut ctx)?;
let env = ctx.data();
let memory: MemoryView<'_> = unsafe { env.memory_view(&ctx) };
let environment = match &env.context_switching_environment {
Some(c) => c,
None => {
tracing::warn!(
"The WASIX context-switching API is only available in a context-switching environment"
);
return Ok(Errno::Notsup);
}
};
let own_context_id = environment.active_context_id();
let main_context_id = environment.main_context_id();
if own_context_id == target_context_id {
tracing::trace!(
"Context {} tried to delete itself, which is not allowed",
target_context_id
);
return Ok(Errno::Inval);
}
if target_context_id == main_context_id {
tracing::trace!(
"Context {} tried to delete the main context, which is not allowed",
own_context_id
);
return Ok(Errno::Inval);
}
let removed_unblocker = environment.destroy_context(&target_context_id);
if !removed_unblocker {
tracing::trace!(
"Context {} tried to delete context {} but it is already removed",
own_context_id,
target_context_id
);
return Ok(Errno::Success);
};
Ok(Errno::Success)
}