X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=library%2Fstd%2Fsrc%2Fsys_common%2Flazy_box.rs;h=63c3316bdeb28b95b691ca914c9120e25488dc69;hb=c72a77e093556e0f1e600686adb8de4419fff4c9;hp=647c13d243724122f1a37cd0cc836b1d317b5c1b;hpb=625c929a9fecc7fbaf7142faaab787ba8125a62f;p=rust.git diff --git a/library/std/src/sys_common/lazy_box.rs b/library/std/src/sys_common/lazy_box.rs index 647c13d2437..63c3316bdeb 100644 --- a/library/std/src/sys_common/lazy_box.rs +++ b/library/std/src/sys_common/lazy_box.rs @@ -21,8 +21,21 @@ pub(crate) trait LazyInit { /// /// It might be called more than once per LazyBox, as multiple threads /// might race to initialize it concurrently, each constructing and initializing - /// their own box. (All but one of them will be destroyed right after.) + /// their own box. All but one of them will be passed to `cancel_init` right after. fn init() -> Box; + + /// Any surplus boxes from `init()` that lost the initialization race + /// are passed to this function for disposal. + /// + /// The default implementation calls destroy(). + fn cancel_init(x: Box) { + Self::destroy(x); + } + + /// This is called to destroy a used box. + /// + /// The default implementation just drops it. + fn destroy(_: Box) {} } impl LazyBox { @@ -45,7 +58,7 @@ fn initialize(&self) -> *mut T { Err(ptr) => { // Lost the race to another thread. // Drop the box we created, and use the one from the other thread instead. - drop(unsafe { Box::from_raw(new_ptr) }); + T::cancel_init(unsafe { Box::from_raw(new_ptr) }); ptr } } @@ -71,7 +84,7 @@ impl Drop for LazyBox { fn drop(&mut self) { let ptr = *self.ptr.get_mut(); if !ptr.is_null() { - drop(unsafe { Box::from_raw(ptr) }); + T::destroy(unsafe { Box::from_raw(ptr) }); } } }