Skip to content

Commit

Permalink
Make Debug impls useful
Browse files Browse the repository at this point in the history
  • Loading branch information
danieldg committed Apr 29, 2023
1 parent 61bfb7c commit 99bb245
Showing 1 changed file with 29 additions and 5 deletions.
34 changes: 29 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@
// 5. Inner::state transitions from QINIT_BIT to READY_BIT during QuickInitGuard's Drop
//
// If the init future fails (due to returning an error or a panic), then:
// 4. The UnsafeCell remains set to None
// 4. The UnsafeCell remains uninitialized
// 5. Inner::state transitions from QINIT_BIT to NEW during QuickInitGuard's Drop
//
// The fast path does not use Inner::queue at all, and only needs to check it once the cell
Expand Down Expand Up @@ -98,6 +98,7 @@ use alloc::{boxed::Box, vec, vec::Vec};
use core::{
cell::UnsafeCell,
convert::Infallible,
fmt,
future::Future,
marker::PhantomData,
mem::MaybeUninit,
Expand Down Expand Up @@ -182,7 +183,6 @@ fn with_lock<T, R>(mutex: &Mutex<T>, f: impl FnOnce(&mut T) -> R) -> R {
///
/// # }
/// ```
#[derive(Debug)]
pub struct OnceCell<T> {
value: UnsafeCell<MaybeUninit<T>>,
inner: Inner,
Expand All @@ -204,12 +204,24 @@ impl<T: UnwindSafe> UnwindSafe for OnceCell<T> {}
/// The queue pointer starts out as NULL. If contention is detected during the initialization of
/// the object, it is initialized to a Box<Queue>, and will remain pointing at that Queue until the
/// state has changed to ready with zero active QueueRefs.
#[derive(Debug)]
struct Inner {
state: AtomicUsize,
queue: AtomicPtr<Queue>,
}

impl fmt::Debug for Inner {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let state = self.state.load(Ordering::Relaxed);
let queue = self.queue.load(Ordering::Relaxed);
fmt.debug_struct("Inner")
.field("ready", &(state & READY_BIT != 0))
.field("quick_init", &(state & QINIT_BIT != 0))
.field("refcount", &(state & (QINIT_BIT - 1)))
.field("queue", &queue)
.finish()
}
}

/// Transient state during initialization
///
/// Unlike the sync OnceCell, this cannot be a linked list through stack frames, because Futures
Expand Down Expand Up @@ -715,6 +727,13 @@ impl<T> OnceCell<T> {
}
}

impl<T: fmt::Debug> fmt::Debug for OnceCell<T> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let value = self.get();
fmt.debug_struct("OnceCell").field("value", &value).field("inner", &self.inner).finish()
}
}

impl<T> Drop for OnceCell<T> {
fn drop(&mut self) {
let state = *self.inner.state.get_mut();
Expand All @@ -738,7 +757,6 @@ impl<T> From<T> for OnceCell<T> {
}
}

#[derive(Debug)]
enum LazyState<T, F> {
Running(F),
Ready(T),
Expand All @@ -765,7 +783,6 @@ enum LazyState<T, F> {
/// assert_eq!(shared.as_ref().get().await.id, 4);
/// # }
/// ```
#[derive(Debug)]
pub struct Lazy<T, F> {
value: UnsafeCell<LazyState<T, F>>,
inner: Inner,
Expand Down Expand Up @@ -929,3 +946,10 @@ impl<T, F> Lazy<T, F> {
}
}
}

impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
let value = self.try_get();
fmt.debug_struct("Lazy").field("value", &value).field("inner", &self.inner).finish()
}
}

0 comments on commit 99bb245

Please sign in to comment.