Patch add lazy init (#236)

* 修正并发安全问题
This commit is contained in:
login 2023-04-08 23:53:53 +08:00 committed by GitHub
parent 766127209e
commit 5c9a63df83
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -25,12 +25,7 @@ use core::sync::atomic::{AtomicBool, Ordering};
use super::spinlock::SpinLock; use super::spinlock::SpinLock;
/// A wrapper around a value that is initialized lazily. /// A wrapper around a value that is initialized lazily.
/// The value is initialized the first time it is accessed. pub struct Lazy<T> {
/// This is useful for initializing values that are expensive to initialize.
/// The value is initialized using the provided closure.
/// The closure is only called once, and the result is cached.
/// The value is not initialized if it is never accessed.
pub struct Lazy<T: Sync> {
/// The lock that is used to ensure that only one thread calls the init function at the same time. /// The lock that is used to ensure that only one thread calls the init function at the same time.
init_lock: SpinLock<()>, init_lock: SpinLock<()>,
/// The value that is initialized lazily. /// The value that is initialized lazily.
@ -39,7 +34,7 @@ pub struct Lazy<T: Sync> {
initialized: AtomicBool, initialized: AtomicBool,
} }
impl<T: Sync> Lazy<T> { impl<T> Lazy<T> {
/// Creates a new `Lazy` value that will be initialized with the /// Creates a new `Lazy` value that will be initialized with the
/// result of the closure `init`. /// result of the closure `init`.
pub const fn new() -> Lazy<T> { pub const fn new() -> Lazy<T> {
@ -122,7 +117,7 @@ impl<T: Sync> Lazy<T> {
} }
} }
impl<T: Sync> Deref for Lazy<T> { impl<T> Deref for Lazy<T> {
type Target = T; type Target = T;
#[inline(always)] #[inline(always)]
@ -131,14 +126,14 @@ impl<T: Sync> Deref for Lazy<T> {
} }
} }
impl<T: Sync> DerefMut for Lazy<T> { impl<T> DerefMut for Lazy<T> {
#[inline(always)] #[inline(always)]
fn deref_mut(&mut self) -> &mut T { fn deref_mut(&mut self) -> &mut T {
return self.get_mut(); return self.get_mut();
} }
} }
impl<T: Sync + Debug> Debug for Lazy<T> { impl<T: Debug> Debug for Lazy<T> {
fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
if let Some(value) = self.try_get() { if let Some(value) = self.try_get() {
return write!(f, "Lazy({:?})", value); return write!(f, "Lazy({:?})", value);
@ -148,7 +143,7 @@ impl<T: Sync + Debug> Debug for Lazy<T> {
} }
} }
impl<T: Sync> Drop for Lazy<T> { impl<T> Drop for Lazy<T> {
fn drop(&mut self) { fn drop(&mut self) {
if self.initialized() { if self.initialized() {
unsafe { unsafe {
@ -157,3 +152,6 @@ impl<T: Sync> Drop for Lazy<T> {
} }
} }
} }
unsafe impl<T: Send + Sync> Sync for Lazy<T> {}
unsafe impl<T: Send> Send for Lazy<T> {}