mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-02 00:00:11 +02:00
tokio: use const Mutex::new for globals (#5061)
This commit is contained in:
@@ -17,9 +17,17 @@ const ADDR_OF_PROBE: &str = r#"
|
|||||||
}
|
}
|
||||||
"#;
|
"#;
|
||||||
|
|
||||||
|
const CONST_MUTEX_NEW_PROBE: &str = r#"
|
||||||
|
{
|
||||||
|
static MY_MUTEX: ::std::sync::Mutex<i32> = ::std::sync::Mutex::new(1);
|
||||||
|
*MY_MUTEX.lock().unwrap()
|
||||||
|
}
|
||||||
|
"#;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut enable_const_thread_local = false;
|
let mut enable_const_thread_local = false;
|
||||||
let mut enable_addr_of = false;
|
let mut enable_addr_of = false;
|
||||||
|
let mut enable_const_mutex_new = false;
|
||||||
|
|
||||||
match AutoCfg::new() {
|
match AutoCfg::new() {
|
||||||
Ok(ac) => {
|
Ok(ac) => {
|
||||||
@@ -57,6 +65,21 @@ fn main() {
|
|||||||
enable_addr_of = true;
|
enable_addr_of = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The `Mutex::new` method was made const in 1.63.
|
||||||
|
if ac.probe_rustc_version(1, 64) {
|
||||||
|
enable_const_mutex_new = true;
|
||||||
|
} else if ac.probe_rustc_version(1, 63) {
|
||||||
|
// This compiler claims to be 1.63, but there are some nightly
|
||||||
|
// compilers that claim to be 1.63 without supporting the
|
||||||
|
// feature. Explicitly probe to check if code using them
|
||||||
|
// compiles.
|
||||||
|
//
|
||||||
|
// The oldest nightly that supports the feature is 2022-06-20.
|
||||||
|
if ac.probe_expression(CONST_MUTEX_NEW_PROBE) {
|
||||||
|
enable_const_mutex_new = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@@ -86,6 +109,14 @@ fn main() {
|
|||||||
autocfg::emit("tokio_no_addr_of")
|
autocfg::emit("tokio_no_addr_of")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !enable_const_mutex_new {
|
||||||
|
// To disable this feature on compilers that support it, you can
|
||||||
|
// explicitly pass this flag with the following environment variable:
|
||||||
|
//
|
||||||
|
// RUSTFLAGS="--cfg tokio_no_const_mutex_new"
|
||||||
|
autocfg::emit("tokio_no_const_mutex_new")
|
||||||
|
}
|
||||||
|
|
||||||
let target = ::std::env::var("TARGET").unwrap_or_default();
|
let target = ::std::env::var("TARGET").unwrap_or_default();
|
||||||
|
|
||||||
// We emit cfgs instead of using `target_family = "wasm"` that requires Rust 1.54.
|
// We emit cfgs instead of using `target_family = "wasm"` that requires Rust 1.54.
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ impl<T> Mutex<T> {
|
|||||||
Mutex(sync::Mutex::new(t))
|
Mutex(sync::Mutex::new(t))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
#[cfg(not(tokio_no_const_mutex_new))]
|
||||||
|
pub(crate) const fn const_new(t: T) -> Mutex<T> {
|
||||||
|
Mutex(sync::Mutex::new(t))
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn lock(&self) -> MutexGuard<'_, T> {
|
pub(crate) fn lock(&self) -> MutexGuard<'_, T> {
|
||||||
match self.0.lock() {
|
match self.0.lock() {
|
||||||
|
|||||||
@@ -481,6 +481,36 @@ macro_rules! cfg_not_has_atomic_u64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! cfg_has_const_mutex_new {
|
||||||
|
($($item:item)*) => {
|
||||||
|
$(
|
||||||
|
#[cfg(all(
|
||||||
|
not(all(loom, test)),
|
||||||
|
any(
|
||||||
|
feature = "parking_lot",
|
||||||
|
not(tokio_no_const_mutex_new)
|
||||||
|
)
|
||||||
|
))]
|
||||||
|
$item
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
macro_rules! cfg_not_has_const_mutex_new {
|
||||||
|
($($item:item)*) => {
|
||||||
|
$(
|
||||||
|
#[cfg(not(all(
|
||||||
|
not(all(loom, test)),
|
||||||
|
any(
|
||||||
|
feature = "parking_lot",
|
||||||
|
not(tokio_no_const_mutex_new)
|
||||||
|
)
|
||||||
|
)))]
|
||||||
|
$item
|
||||||
|
)*
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
macro_rules! cfg_not_wasi {
|
macro_rules! cfg_not_wasi {
|
||||||
($($item:item)*) => {
|
($($item:item)*) => {
|
||||||
$(
|
$(
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ use crate::process::kill::Kill;
|
|||||||
use crate::process::SpawnedChild;
|
use crate::process::SpawnedChild;
|
||||||
use crate::signal::unix::driver::Handle as SignalHandle;
|
use crate::signal::unix::driver::Handle as SignalHandle;
|
||||||
use crate::signal::unix::{signal, Signal, SignalKind};
|
use crate::signal::unix::{signal, Signal, SignalKind};
|
||||||
use crate::util::once_cell::OnceCell;
|
|
||||||
|
|
||||||
use mio::event::Source;
|
use mio::event::Source;
|
||||||
use mio::unix::SourceFd;
|
use mio::unix::SourceFd;
|
||||||
@@ -64,10 +63,22 @@ impl Kill for StdChild {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_orphan_queue() -> &'static OrphanQueueImpl<StdChild> {
|
cfg_not_has_const_mutex_new! {
|
||||||
static ORPHAN_QUEUE: OnceCell<OrphanQueueImpl<StdChild>> = OnceCell::new();
|
fn get_orphan_queue() -> &'static OrphanQueueImpl<StdChild> {
|
||||||
|
use crate::util::once_cell::OnceCell;
|
||||||
|
|
||||||
ORPHAN_QUEUE.get(OrphanQueueImpl::new)
|
static ORPHAN_QUEUE: OnceCell<OrphanQueueImpl<StdChild>> = OnceCell::new();
|
||||||
|
|
||||||
|
ORPHAN_QUEUE.get(OrphanQueueImpl::new)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_has_const_mutex_new! {
|
||||||
|
fn get_orphan_queue() -> &'static OrphanQueueImpl<StdChild> {
|
||||||
|
static ORPHAN_QUEUE: OrphanQueueImpl<StdChild> = OrphanQueueImpl::new();
|
||||||
|
|
||||||
|
&ORPHAN_QUEUE
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) struct GlobalOrphanQueue;
|
pub(crate) struct GlobalOrphanQueue;
|
||||||
|
|||||||
@@ -43,10 +43,21 @@ pub(crate) struct OrphanQueueImpl<T> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<T> OrphanQueueImpl<T> {
|
impl<T> OrphanQueueImpl<T> {
|
||||||
pub(crate) fn new() -> Self {
|
cfg_not_has_const_mutex_new! {
|
||||||
Self {
|
pub(crate) fn new() -> Self {
|
||||||
sigchild: Mutex::new(None),
|
Self {
|
||||||
queue: Mutex::new(Vec::new()),
|
sigchild: Mutex::new(None),
|
||||||
|
queue: Mutex::new(Vec::new()),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cfg_has_const_mutex_new! {
|
||||||
|
pub(crate) const fn new() -> Self {
|
||||||
|
Self {
|
||||||
|
sigchild: Mutex::const_new(None),
|
||||||
|
queue: Mutex::const_new(Vec::new()),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -507,21 +507,35 @@ impl Id {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cfg_not_has_atomic_u64! {
|
cfg_not_has_atomic_u64! {
|
||||||
pub(crate) fn next() -> Self {
|
cfg_has_const_mutex_new! {
|
||||||
use crate::util::once_cell::OnceCell;
|
pub(crate) fn next() -> Self {
|
||||||
use crate::loom::sync::Mutex;
|
use crate::loom::sync::Mutex;
|
||||||
|
static NEXT_ID: Mutex<u64> = Mutex::const_new(1);
|
||||||
|
|
||||||
fn init_next_id() -> Mutex<u64> {
|
let mut lock = NEXT_ID.lock();
|
||||||
Mutex::new(1)
|
let id = *lock;
|
||||||
|
*lock += 1;
|
||||||
|
Self(id)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static NEXT_ID: OnceCell<Mutex<u64>> = OnceCell::new();
|
cfg_not_has_const_mutex_new! {
|
||||||
|
pub(crate) fn next() -> Self {
|
||||||
|
use crate::util::once_cell::OnceCell;
|
||||||
|
use crate::loom::sync::Mutex;
|
||||||
|
|
||||||
let next_id = NEXT_ID.get(init_next_id);
|
fn init_next_id() -> Mutex<u64> {
|
||||||
let mut lock = next_id.lock();
|
Mutex::new(1)
|
||||||
let id = *lock;
|
}
|
||||||
*lock += 1;
|
|
||||||
Self(id)
|
static NEXT_ID: OnceCell<Mutex<u64>> = OnceCell::new();
|
||||||
|
|
||||||
|
let next_id = NEXT_ID.get(init_next_id);
|
||||||
|
let mut lock = next_id.lock();
|
||||||
|
let id = *lock;
|
||||||
|
*lock += 1;
|
||||||
|
Self(id)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -6,14 +6,8 @@ cfg_io_driver! {
|
|||||||
#[cfg(feature = "rt")]
|
#[cfg(feature = "rt")]
|
||||||
pub(crate) mod atomic_cell;
|
pub(crate) mod atomic_cell;
|
||||||
|
|
||||||
cfg_has_atomic_u64! {
|
#[cfg(any(feature = "rt", feature = "signal", feature = "process"))]
|
||||||
#[cfg(any(feature = "signal", all(unix, feature = "process")))]
|
pub(crate) mod once_cell;
|
||||||
pub(crate) mod once_cell;
|
|
||||||
}
|
|
||||||
cfg_not_has_atomic_u64! {
|
|
||||||
#[cfg(any(feature = "rt", feature = "signal", all(unix, feature = "process")))]
|
|
||||||
pub(crate) mod once_cell;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(any(
|
#[cfg(any(
|
||||||
// io driver uses `WakeList` directly
|
// io driver uses `WakeList` directly
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
#![cfg_attr(loom, allow(dead_code))]
|
#![allow(dead_code)]
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::mem::MaybeUninit;
|
use std::mem::MaybeUninit;
|
||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
|
|||||||
Reference in New Issue
Block a user