Skip to content

Commit 7fa33ca

Browse files
committed
Safety comments and using Vec::splice
1 parent a0a83bb commit 7fa33ca

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

rust/kernel/sync.rs

+9-2
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,19 @@ pub struct StaticInit<T> {
134134
inner: MaybeUninit<UnsafeCell<T>>,
135135
}
136136

137+
// SAFETY: Need to implement Send/Sync, because of the `UnsafeCell`. One can only get a `&T` from a
138+
// `StaticInit<T>`. Except when calling `init` which is unsafe and only done before other code can
139+
// access the `StaticInit<T>`.
137140
unsafe impl<T: Sync> Sync for StaticInit<T> {}
141+
// SAFETY: same as above.
138142
unsafe impl<T: Send> Send for StaticInit<T> {}
139143

140144
impl<T> StaticInit<T> {
141145
/// Creates a new `StaticInit` that is uninitialized.
142146
///
143147
/// # Safety
144148
///
145-
/// The caller calls `Self::init` exactly once before using this value.
149+
/// The caller calls `Self::init` exactly once before using this value in any way.
146150
pub const unsafe fn uninit() -> Self {
147151
Self {
148152
inner: MaybeUninit::uninit(),
@@ -154,11 +158,13 @@ impl<T> StaticInit<T> {
154158
/// # Safety
155159
///
156160
/// The caller calls this function exactly once and before any other function (even implicitly
157-
/// derefing) of `self` is called.
161+
/// derefing) of `self` is called. `self` stays pinned indefinetly.
158162
pub unsafe fn init<E>(&self, init: impl PinInit<T, E>)
159163
where
160164
E: Into<core::convert::Infallible>,
161165
{
166+
// SAFETY: This function has unique access to `self` because of the unsafety contract.
167+
// `self` is also pinned indefinetly and `inner` is structurally pinned.
162168
unsafe {
163169
let ptr = UnsafeCell::raw_get(self.inner.as_ptr());
164170
match init.__pinned_init(ptr).map_err(|e| e.into()) {
@@ -172,6 +178,7 @@ impl<T> StaticInit<T> {
172178
impl<T> core::ops::Deref for StaticInit<T> {
173179
type Target = T;
174180
fn deref(&self) -> &Self::Target {
181+
// SAFETY: self.inner has been initialized because of the contract of `Self::uninit()`
175182
unsafe { &*self.inner.assume_init_ref().get() }
176183
}
177184
}

0 commit comments

Comments
 (0)