mirror of
https://github.com/tokio-rs/tracing.git
synced 2025-10-02 07:20:35 +00:00
core: remove vendored lazy_static
on no-std (#2173)
Currently, `no_std` targets use a vendored version of `lazy_static` that uses the `spin` crate's `Once` type, while the `std` target uses the `once_cell` crate's `Lazy` type. This is unfortunate, as the `lazy_static` macro has a different interface from the `Lazy` cell type. This increases the amount of code that differs based on whether or not `std` is enabled. This branch removes the vendored `lazy_static` macro and replaces it with a reimplementation of `once_cell::sync::Lazy` that uses `spin::Once` rather than `once_cell::sync::OnceCell` as the inner "once type". Now, all code can be written against a `Lazy` struct with the same interface, regardless of whether or not `std` is enabled. Signed-off-by: Eliza Weisman <eliza@buoyant.io>
This commit is contained in:
parent
67cfb5f352
commit
f7966bde76
@ -111,6 +111,7 @@ use crate::stdlib::{
|
|||||||
};
|
};
|
||||||
use crate::{
|
use crate::{
|
||||||
dispatcher::Dispatch,
|
dispatcher::Dispatch,
|
||||||
|
lazy::Lazy,
|
||||||
metadata::{LevelFilter, Metadata},
|
metadata::{LevelFilter, Metadata},
|
||||||
subscriber::Interest,
|
subscriber::Interest,
|
||||||
};
|
};
|
||||||
@ -253,14 +254,7 @@ static CALLSITES: Callsites = Callsites {
|
|||||||
|
|
||||||
static DISPATCHERS: Dispatchers = Dispatchers::new();
|
static DISPATCHERS: Dispatchers = Dispatchers::new();
|
||||||
|
|
||||||
#[cfg(feature = "std")]
|
static LOCKED_CALLSITES: Lazy<Mutex<Vec<&'static dyn Callsite>>> = Lazy::new(Default::default);
|
||||||
static LOCKED_CALLSITES: once_cell::sync::Lazy<Mutex<Vec<&'static dyn Callsite>>> =
|
|
||||||
once_cell::sync::Lazy::new(Default::default);
|
|
||||||
|
|
||||||
#[cfg(not(feature = "std"))]
|
|
||||||
crate::lazy_static! {
|
|
||||||
static ref LOCKED_CALLSITES: Mutex<Vec<&'static dyn Callsite>> = Mutex::new(Vec::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Callsites {
|
struct Callsites {
|
||||||
list_head: AtomicPtr<DefaultCallsite>,
|
list_head: AtomicPtr<DefaultCallsite>,
|
||||||
@ -514,8 +508,7 @@ mod private {
|
|||||||
|
|
||||||
#[cfg(feature = "std")]
|
#[cfg(feature = "std")]
|
||||||
mod dispatchers {
|
mod dispatchers {
|
||||||
use crate::dispatcher;
|
use crate::{dispatcher, lazy::Lazy};
|
||||||
use once_cell::sync::Lazy;
|
|
||||||
use std::sync::{
|
use std::sync::{
|
||||||
atomic::{AtomicBool, Ordering},
|
atomic::{AtomicBool, Ordering},
|
||||||
RwLock, RwLockReadGuard, RwLockWriteGuard,
|
RwLock, RwLockReadGuard, RwLockWriteGuard,
|
||||||
|
76
tracing-core/src/lazy.rs
Normal file
76
tracing-core/src/lazy.rs
Normal file
@ -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, F = fn() -> T> {
|
||||||
|
cell: Once<T>,
|
||||||
|
init: Cell<Option<F>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: fmt::Debug, F> fmt::Debug for Lazy<T, F> {
|
||||||
|
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<T, F>` so it is fine to not impl
|
||||||
|
// `Sync` for `F`. We do create a `&mut Option<F>` in `force`, but this is
|
||||||
|
// properly synchronized, so it only happens once so it also does not
|
||||||
|
// contribute to this impl.
|
||||||
|
unsafe impl<T, F: Send> Sync for Lazy<T, F> where Once<T>: Sync {}
|
||||||
|
// auto-derived `Send` impl is OK.
|
||||||
|
|
||||||
|
impl<T, F> Lazy<T, F> {
|
||||||
|
/// Creates a new lazy value with the given initializing function.
|
||||||
|
pub(crate) const fn new(init: F) -> Lazy<T, F> {
|
||||||
|
Lazy {
|
||||||
|
cell: Once::new(),
|
||||||
|
init: Cell::new(Some(init)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, F: FnOnce() -> T> Lazy<T, F> {
|
||||||
|
/// 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, F>) -> &T {
|
||||||
|
this.cell.call_once(|| match this.init.take() {
|
||||||
|
Some(f) => f(),
|
||||||
|
None => panic!("Lazy instance has previously been poisoned"),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T, F: FnOnce() -> T> Deref for Lazy<T, F> {
|
||||||
|
type Target = T;
|
||||||
|
fn deref(&self) -> &T {
|
||||||
|
Lazy::force(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default> Default for Lazy<T> {
|
||||||
|
/// Creates a new lazy value using `Default` as the initializing function.
|
||||||
|
fn default() -> Lazy<T> {
|
||||||
|
Lazy::new(T::default)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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.
|
|
@ -1,30 +0,0 @@
|
|||||||
// Copyright 2016 lazy-static.rs Developers
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
|
||||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
|
||||||
// http://opensource.org/licenses/MIT>, 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<T: Sync>(Once<T>);
|
|
||||||
|
|
||||||
impl<T: Sync> Lazy<T> {
|
|
||||||
pub(crate) const INIT: Self = Lazy(Once::INIT);
|
|
||||||
|
|
||||||
#[inline(always)]
|
|
||||||
pub(crate) fn get<F>(&'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;
|
|
||||||
};
|
|
||||||
}
|
|
@ -1,89 +0,0 @@
|
|||||||
// Copyright 2016 lazy-static.rs Developers
|
|
||||||
//
|
|
||||||
// Licensed under the Apache License, Version 2.0, <LICENSE-APACHE or
|
|
||||||
// http://apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
|
|
||||||
// http://opensource.org/licenses/MIT>, 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);
|
|
||||||
}
|
|
@ -254,10 +254,7 @@ macro_rules! metadata {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Facade module: `no_std` uses spinlocks, `std` uses the mutexes in the standard library
|
pub(crate) mod lazy;
|
||||||
#[cfg(not(feature = "std"))]
|
|
||||||
#[macro_use]
|
|
||||||
mod lazy_static;
|
|
||||||
|
|
||||||
// Trimmed-down vendored version of spin 0.5.2 (0387621)
|
// Trimmed-down vendored version of spin 0.5.2 (0387621)
|
||||||
// Dependency of no_std lazy_static, not required in a std build
|
// Dependency of no_std lazy_static, not required in a std build
|
||||||
|
@ -64,11 +64,11 @@ mod no_std {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> Mutex<T> {
|
impl<T> Mutex<T> {
|
||||||
pub(crate) fn new(data: T) -> Self {
|
// pub(crate) fn new(data: T) -> Self {
|
||||||
Self {
|
// Self {
|
||||||
inner: crate::spin::Mutex::new(data),
|
// inner: crate::spin::Mutex::new(data),
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
pub(crate) fn lock(&self) -> Result<MutexGuard<'_, T>, ()> {
|
pub(crate) fn lock(&self) -> Result<MutexGuard<'_, T>, ()> {
|
||||||
Ok(self.inner.lock())
|
Ok(self.inner.lock())
|
||||||
|
Loading…
x
Reference in New Issue
Block a user