diff --git a/.gitignore b/.gitignore index 91143dc..65bf486 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ **/*.rs.bk Cargo.lock .vscode/ +.zed/ diff --git a/Cargo.toml b/Cargo.toml index 5b0705c..2120a9a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,8 +21,12 @@ current_thread_id = [] nightly = ["current_thread_id"] [dependencies] +cfg-if = "1.0.0" futures-core = { version = "0.3", optional = true } +[target.'cfg(loom)'.dependencies] +loom = "0.7" + [dev-dependencies] futures-executor = "0.3" futures-util = "0.3" @@ -31,3 +35,6 @@ futures-util = "0.3" all-features = true # Needed to add "Available on crate feature `futures` only." messages to docs rustdoc-args = ["--cfg", "docsrs"] + +[lints.rust] +unexpected_cfgs = { level = "warn", check-cfg = ['cfg(loom)'] } diff --git a/src/lib.rs b/src/lib.rs index 97eb464..4bbd63e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -82,40 +82,42 @@ //! [`Stream`]: futures_core::Stream // To build docs locally use `RUSTDOCFLAGS="--cfg docsrs" cargo doc --open --all-features` #![cfg_attr(docsrs, feature(doc_cfg))] -#![cfg_attr(feature = "current_thread_id", feature(current_thread_id))] +#![cfg_attr( + all(not(loom), feature = "current_thread_id"), + feature(current_thread_id) +)] #![warn(missing_docs)] #[cfg(feature = "futures")] #[cfg_attr(docsrs, doc(cfg(feature = "futures")))] mod futures; -#[cfg(feature = "current_thread_id")] -use std::thread::current_id; use std::{ fmt, mem::{self, ManuallyDrop}, pin::Pin, - thread::{self, ThreadId}, }; -#[cfg(not(feature = "current_thread_id"))] -mod imp { - use std::{ - cell::Cell, - thread::{self, ThreadId}, - }; - thread_local! { - static THREAD_ID: Cell = Cell::new(thread::current().id()); - } +cfg_if::cfg_if! { + if #[cfg(any(loom, not(feature = "current_thread_id")))] { + #[cfg(loom)] + use loom::{thread_local, cell::Cell, thread::{self, ThreadId}}; + #[cfg(not(loom))] + use std::{thread_local, cell::Cell, thread::{self, ThreadId}}; - pub fn current_id() -> ThreadId { - THREAD_ID.get() + thread_local! { + static THREAD_ID: Cell = Cell::new(thread::current().id()); + } + + /// Get the current [`ThreadId`]. + pub(crate) fn current_id() -> ThreadId { + THREAD_ID.with(|id| id.get()) + } + } else { + use std::thread::{self, current_id, ThreadId}; } } -#[cfg(not(feature = "current_thread_id"))] -use imp::current_id; - /// A wrapper which allows you to move around non-[`Send`]-types between /// threads, as long as you access the contained value only from within the /// original thread and make sure that it is dropped from within the original