Skip to content

Commit 432904d

Browse files
committed
feat(bind): add BindTable::get
1 parent e423225 commit 432904d

File tree

1 file changed

+67
-3
lines changed

1 file changed

+67
-3
lines changed

src/r3_core/src/bind.rs

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ use core::{cell::UnsafeCell, marker::PhantomData, mem::MaybeUninit};
171171
use crate::{
172172
closure::Closure,
173173
hunk::Hunk,
174-
kernel::{self, cfg, raw, raw_cfg, StartupHook},
174+
kernel::{self, cfg, prelude::*, raw, raw_cfg, StartupHook},
175175
utils::{refcell::RefCell, ComptimeVec, ConstAllocator, Init, PhantomInvariant, ZeroInit},
176176
};
177177

@@ -818,23 +818,87 @@ impl<'pool, const LEN: usize, System, T> const UnzipBind for Bind<'pool, System,
818818
// ----------------------------------------------------------------------------
819819

820820
/// Represents a permission to dereference [`BindRef`][].
821+
///
822+
/// # Example
823+
///
824+
/// ```rust
825+
/// #![feature(const_fn_fn_ptr_basics)]
826+
/// #![feature(const_fn_trait_bound)]
827+
/// #![feature(const_trait_impl)]
828+
/// #![feature(const_mut_refs)]
829+
/// use r3_core::{
830+
/// bind::{Bind, BindRef, BindTable},
831+
/// kernel::{cfg::Cfg, traits, StaticTask},
832+
/// prelude::*,
833+
/// };
834+
///
835+
/// const fn configure_app<C>(cfg: &mut Cfg<C>)
836+
/// where
837+
/// C: ~const traits::CfgBase +
838+
/// ~const traits::CfgTask,
839+
/// C::System: traits::KernelBase + traits::KernelStatic,
840+
/// {
841+
/// let foo = Bind::define().init(|| {
842+
/// // `BindTable::get()` will fail because some bindings might not
843+
/// // be initialized at this point
844+
/// assert!(BindTable::<C::System>::get().is_err());
845+
///
846+
/// 42
847+
/// }).finish(cfg).as_ref();
848+
///
849+
/// StaticTask::define()
850+
/// .start(move || {
851+
/// // Task code can get `BindTable` because tasks can only
852+
/// // run after the boot phase is complete
853+
/// let bt = BindTable::get().unwrap();
854+
/// assert_eq!(bt[foo], 42);
855+
/// })
856+
/// .priority(2)
857+
/// .active(true)
858+
/// .finish(cfg);
859+
/// }
860+
/// ```
821861
pub struct BindTable<System> {
822862
_phantom: PhantomInvariant<System>,
823863
}
824864

865+
/// Error type for [`BindTable::get`][].
866+
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)]
867+
pub enum GetBindTableError {
868+
/// [The boot phase][] is not complete.
869+
///
870+
/// [the boot phase]: crate#threads
871+
BadContext,
872+
}
873+
825874
impl<System> BindTable<System>
826875
where
827876
System: raw::KernelBase + cfg::KernelStatic,
828877
{
829-
// TODO: pub fn get() -> Result<Self> {}
878+
/// Get a reference to `BindTable` if [the boot phase][] is complete.
879+
///
880+
/// Returns `Err(BadContext)` if the boot phase hasn't completed yet, and
881+
/// therefore it's unsafe to dereference [`BindRef`]s.
882+
///
883+
/// [the boot phase]: crate#threads
884+
#[inline]
885+
pub fn get() -> Result<&'static Self, GetBindTableError> {
886+
if System::is_boot_complete() {
887+
Ok(&Self {
888+
_phantom: Init::INIT,
889+
})
890+
} else {
891+
Err(GetBindTableError::BadContext)
892+
}
893+
}
830894

831895
/// Get a reference to `BindTable` without checking if it's safe to do so
832896
/// in the current context.
833897
///
834898
/// # Safety
835899
///
836900
/// The returned reference may be used to borrow binding contents that are
837-
/// uninitialized or being mutably borrowed somewhere else.
901+
/// uninitialized or being mutably borrowed by a binding initializer.
838902
#[inline]
839903
pub const unsafe fn get_unchecked() -> &'static Self {
840904
&Self {

0 commit comments

Comments
 (0)