diff --git a/tracing-core/src/callsite.rs b/tracing-core/src/callsite.rs index 87d084647b..d0fe1a3d6c 100644 --- a/tracing-core/src/callsite.rs +++ b/tracing-core/src/callsite.rs @@ -111,6 +111,7 @@ use crate::stdlib::{ }; use crate::{ dispatcher::Dispatch, + lazy::Lazy, metadata::{LevelFilter, Metadata}, subscriber::Interest, }; @@ -253,14 +254,7 @@ static CALLSITES: Callsites = Callsites { static DISPATCHERS: Dispatchers = Dispatchers::new(); -#[cfg(feature = "std")] -static LOCKED_CALLSITES: once_cell::sync::Lazy>> = - once_cell::sync::Lazy::new(Default::default); - -#[cfg(not(feature = "std"))] -crate::lazy_static! { - static ref LOCKED_CALLSITES: Mutex> = Mutex::new(Vec::new()); -} +static LOCKED_CALLSITES: Lazy>> = Lazy::new(Default::default); struct Callsites { list_head: AtomicPtr, @@ -514,8 +508,7 @@ mod private { #[cfg(feature = "std")] mod dispatchers { - use crate::dispatcher; - use once_cell::sync::Lazy; + use crate::{dispatcher, lazy::Lazy}; use std::sync::{ atomic::{AtomicBool, Ordering}, RwLock, RwLockReadGuard, RwLockWriteGuard, diff --git a/tracing-core/src/lazy.rs b/tracing-core/src/lazy.rs new file mode 100644 index 0000000000..4f004e6364 --- /dev/null +++ b/tracing-core/src/lazy.rs @@ -0,0 +1,76 @@ +#[cfg(feature = "std")] +pub(crate) use once_cell::sync::Lazy; + +#[cfg(not(feature = "std"))] +pub(crate) use self::spin::Lazy; + +#[cfg(not(feature = "std"))] +mod spin { + //! This is the `once_cell::sync::Lazy` type, but modified to use our + //! `spin::Once` type rather than `OnceCell`. This is used to replace + //! `once_cell::sync::Lazy` on `no-std` builds. + use crate::spin::Once; + use core::{cell::Cell, fmt, ops::Deref}; + + /// Re-implementation of `once_cell::sync::Lazy` on top of `spin::Once` + /// rather than `OnceCell`. + /// + /// This is used when the standard library is disabled. + pub(crate) struct Lazy T> { + cell: Once, + init: Cell>, + } + + impl fmt::Debug for Lazy { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("Lazy") + .field("cell", &self.cell) + .field("init", &"..") + .finish() + } + } + + // We never create a `&F` from a `&Lazy` so it is fine to not impl + // `Sync` for `F`. We do create a `&mut Option` in `force`, but this is + // properly synchronized, so it only happens once so it also does not + // contribute to this impl. + unsafe impl Sync for Lazy where Once: Sync {} + // auto-derived `Send` impl is OK. + + impl Lazy { + /// Creates a new lazy value with the given initializing function. + pub(crate) const fn new(init: F) -> Lazy { + Lazy { + cell: Once::new(), + init: Cell::new(Some(init)), + } + } + } + + impl T> Lazy { + /// Forces the evaluation of this lazy value and returns a reference to + /// the result. + /// + /// This is equivalent to the `Deref` impl, but is explicit. + pub(crate) fn force(this: &Lazy) -> &T { + this.cell.call_once(|| match this.init.take() { + Some(f) => f(), + None => panic!("Lazy instance has previously been poisoned"), + }) + } + } + + impl T> Deref for Lazy { + type Target = T; + fn deref(&self) -> &T { + Lazy::force(self) + } + } + + impl Default for Lazy { + /// Creates a new lazy value using `Default` as the initializing function. + fn default() -> Lazy { + Lazy::new(T::default) + } + } +} diff --git a/tracing-core/src/lazy_static/LICENSE b/tracing-core/src/lazy_static/LICENSE deleted file mode 100644 index 28e478827c..0000000000 --- a/tracing-core/src/lazy_static/LICENSE +++ /dev/null @@ -1,26 +0,0 @@ - -Copyright (c) 2010 The Rust Project Developers - -Permission is hereby granted, free of charge, to any -person obtaining a copy of this software and associated -documentation files (the "Software"), to deal in the -Software without restriction, including without -limitation the rights to use, copy, modify, merge, -publish, distribute, sublicense, and/or sell copies of -the Software, and to permit persons to whom the Software -is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice -shall be included in all copies or substantial portions -of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF -ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED -TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A -PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT -SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY -CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR -IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER -DEALINGS IN THE SOFTWARE. diff --git a/tracing-core/src/lazy_static/core_lazy.rs b/tracing-core/src/lazy_static/core_lazy.rs deleted file mode 100644 index c61d36202d..0000000000 --- a/tracing-core/src/lazy_static/core_lazy.rs +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright 2016 lazy-static.rs Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -use crate::spin::Once; - -pub(crate) struct Lazy(Once); - -impl Lazy { - pub(crate) const INIT: Self = Lazy(Once::INIT); - - #[inline(always)] - pub(crate) fn get(&'static self, builder: F) -> &T - where - F: FnOnce() -> T, - { - self.0.call_once(builder) - } -} - -#[macro_export] -#[doc(hidden)] -macro_rules! __lazy_static_create { - ($NAME:ident, $T:ty) => { - static $NAME: $crate::lazy_static::lazy::Lazy<$T> = $crate::lazy_static::lazy::Lazy::INIT; - }; -} diff --git a/tracing-core/src/lazy_static/mod.rs b/tracing-core/src/lazy_static/mod.rs deleted file mode 100644 index 78f0ae722b..0000000000 --- a/tracing-core/src/lazy_static/mod.rs +++ /dev/null @@ -1,89 +0,0 @@ -// Copyright 2016 lazy-static.rs Developers -// -// Licensed under the Apache License, Version 2.0, or the MIT license , at your option. This file may not be -// copied, modified, or distributed except according to those terms. - -/*! -A macro for declaring lazily evaluated statics. -Using this macro, it is possible to have `static`s that require code to be -executed at runtime in order to be initialized. -This includes anything requiring heap allocations, like vectors or hash maps, -as well as anything that requires function calls to be computed. -*/ - -#[path = "core_lazy.rs"] -pub(crate) mod lazy; - -#[doc(hidden)] -pub(crate) use core::ops::Deref as __Deref; - -#[macro_export] -#[doc(hidden)] -macro_rules! __lazy_static_internal { - // optional visibility restrictions are wrapped in `()` to allow for - // explicitly passing otherwise implicit information about private items - ($(#[$attr:meta])* ($($vis:tt)*) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { - $crate::__lazy_static_internal!(@MAKE TY, $(#[$attr])*, ($($vis)*), $N); - $crate::__lazy_static_internal!(@TAIL, $N : $T = $e); - $crate::lazy_static!($($t)*); - }; - (@TAIL, $N:ident : $T:ty = $e:expr) => { - impl $crate::lazy_static::__Deref for $N { - type Target = $T; - fn deref(&self) -> &$T { - #[inline(always)] - fn __static_ref_initialize() -> $T { $e } - - #[inline(always)] - fn __stability() -> &'static $T { - $crate::__lazy_static_create!(LAZY, $T); - LAZY.get(__static_ref_initialize) - } - __stability() - } - } - impl $crate::lazy_static::LazyStatic for $N { - fn initialize(lazy: &Self) { - let _ = &**lazy; - } - } - }; - // `vis` is wrapped in `()` to prevent parsing ambiguity - (@MAKE TY, $(#[$attr:meta])*, ($($vis:tt)*), $N:ident) => { - #[allow(missing_copy_implementations)] - #[allow(non_camel_case_types)] - #[allow(dead_code)] - $(#[$attr])* - $($vis)* struct $N {__private_field: ()} - #[doc(hidden)] - $($vis)* static $N: $N = $N {__private_field: ()}; - }; - () => () -} - -#[macro_export] -#[doc(hidden)] -macro_rules! lazy_static { - ($(#[$attr:meta])* static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { - // use `()` to explicitly forward the information about private items - $crate::__lazy_static_internal!($(#[$attr])* () static ref $N : $T = $e; $($t)*); - }; - ($(#[$attr:meta])* pub static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { - $crate::__lazy_static_internal!($(#[$attr])* (pub) static ref $N : $T = $e; $($t)*); - }; - ($(#[$attr:meta])* pub ($($vis:tt)+) static ref $N:ident : $T:ty = $e:expr; $($t:tt)*) => { - $crate::__lazy_static_internal!($(#[$attr])* (pub ($($vis)+)) static ref $N : $T = $e; $($t)*); - }; - () => () -} - -/// Support trait for enabling a few common operation on lazy static values. -/// -/// This is implemented by each defined lazy static, and -/// used by the free functions in this crate. -pub(crate) trait LazyStatic { - #[doc(hidden)] - fn initialize(lazy: &Self); -} diff --git a/tracing-core/src/lib.rs b/tracing-core/src/lib.rs index eceef7be22..c1f87b22f0 100644 --- a/tracing-core/src/lib.rs +++ b/tracing-core/src/lib.rs @@ -254,10 +254,7 @@ macro_rules! metadata { }; } -// Facade module: `no_std` uses spinlocks, `std` uses the mutexes in the standard library -#[cfg(not(feature = "std"))] -#[macro_use] -mod lazy_static; +pub(crate) mod lazy; // Trimmed-down vendored version of spin 0.5.2 (0387621) // Dependency of no_std lazy_static, not required in a std build diff --git a/tracing-core/src/stdlib.rs b/tracing-core/src/stdlib.rs index 4a1c17c2b8..741549519c 100644 --- a/tracing-core/src/stdlib.rs +++ b/tracing-core/src/stdlib.rs @@ -64,11 +64,11 @@ mod no_std { } impl Mutex { - pub(crate) fn new(data: T) -> Self { - Self { - inner: crate::spin::Mutex::new(data), - } - } + // pub(crate) fn new(data: T) -> Self { + // Self { + // inner: crate::spin::Mutex::new(data), + // } + // } pub(crate) fn lock(&self) -> Result, ()> { Ok(self.inner.lock())