sel4/
invocation_context.rs

1//
2// Copyright 2023, Colias Group, LLC
3//
4// SPDX-License-Identifier: MIT
5//
6
7use core::cell::RefCell;
8
9use crate::IpcBuffer;
10
11/// A strategy for discovering the current thread's IPC buffer.
12pub trait InvocationContext {
13    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T;
14}
15
16/// The absence of a strategy for discovering the current thread's IPC buffer.
17#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, Hash)]
18pub struct NoInvocationContext;
19
20impl NoInvocationContext {
21    pub const fn new() -> Self {
22        Self
23    }
24}
25
26impl InvocationContext for &mut IpcBuffer {
27    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T {
28        f(self)
29    }
30}
31
32impl<U: InvocationContext> InvocationContext for &mut U {
33    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T {
34        U::with_context(self, f)
35    }
36}
37
38impl<U: InvocationContext> InvocationContext for &RefCell<U> {
39    fn with_context<T>(&mut self, f: impl FnOnce(&mut IpcBuffer) -> T) -> T {
40        U::with_context(&mut self.borrow_mut(), f)
41    }
42}
43
44cfg_if::cfg_if! {
45    if #[cfg(feature = "state")] {
46        type NoExplicitInvocationContextInternal = crate::ImplicitInvocationContext;
47    } else {
48        type NoExplicitInvocationContextInternal = NoInvocationContext;
49    }
50}
51
52/// The default strategy for discovering the current thread's IPC buffer.
53///
54/// When the `"state"` feature is enabled, [`NoExplicitInvocationContext`] is an alias for
55/// [`ImplicitInvocationContext`](crate::ImplicitInvocationContext), which uses the [`IpcBuffer`]
56/// set by [`set_ipc_buffer`](crate::set_ipc_buffer). Otherwise, it is an alias for
57/// [`NoInvocationContext`](crate::NoInvocationContext), which does not implement
58/// [`InvocationContext`].
59pub type NoExplicitInvocationContext = NoExplicitInvocationContextInternal;