From e75ca93d30e6d2f7a165882d46d8b55fa3e8cb78 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Mon, 5 Jun 2023 14:09:43 -0700 Subject: [PATCH] rt: `EnterGuard` should not be `Send` (#5766) Removes `Send` from `EnterGuard` (returned by `Handle::enter()`. The guard type changes a thread-local variable on drop. If the guard is moved to a different thread, it would modify the wrong thread-local. This is a **breaking change** but it fixes a bug and prevents incorrect user behavior. If user code breaks because of this, it is because they (most likely) have a bug in their code. --- tokio/src/runtime/context.rs | 4 ++++ tokio/src/util/markers.rs | 4 ++++ tokio/src/util/mod.rs | 2 ++ tokio/tests/async_send_sync.rs | 2 +- 4 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 tokio/src/util/markers.rs diff --git a/tokio/src/runtime/context.rs b/tokio/src/runtime/context.rs index c0d3be325..388171d01 100644 --- a/tokio/src/runtime/context.rs +++ b/tokio/src/runtime/context.rs @@ -159,6 +159,9 @@ cfg_rt! { pub(crate) struct SetCurrentGuard { old_handle: Option, old_seed: RngSeed, + // Should not be `Send` since it must be *dropped* on the same thread as + // created, but there is no issue with sync access. + _p: PhantomData, } /// Guard tracking that a caller has entered a runtime context. @@ -308,6 +311,7 @@ cfg_rt! { SetCurrentGuard { old_handle, old_seed, + _p: PhantomData, } } } diff --git a/tokio/src/util/markers.rs b/tokio/src/util/markers.rs new file mode 100644 index 000000000..1da09da94 --- /dev/null +++ b/tokio/src/util/markers.rs @@ -0,0 +1,4 @@ +/// Marker for types that are `Sync` but not `Send` +pub(crate) struct SyncNotSend(*mut ()); + +unsafe impl Sync for SyncNotSend {} diff --git a/tokio/src/util/mod.rs b/tokio/src/util/mod.rs index b1afc5716..6a7d4b103 100644 --- a/tokio/src/util/mod.rs +++ b/tokio/src/util/mod.rs @@ -79,3 +79,5 @@ pub(crate) mod error; #[cfg(feature = "io-util")] pub(crate) mod memchr; + +pub(crate) mod markers; diff --git a/tokio/tests/async_send_sync.rs b/tokio/tests/async_send_sync.rs index 0c2c34a07..32c03a54b 100644 --- a/tokio/tests/async_send_sync.rs +++ b/tokio/tests/async_send_sync.rs @@ -532,7 +532,7 @@ async_assert_fn!(tokio::task::unconstrained(BoxFutureSend<()>): Send & !Sync & U async_assert_fn!(tokio::task::unconstrained(BoxFutureSync<()>): Send & Sync & Unpin); assert_value!(tokio::runtime::Builder: Send & Sync & Unpin); -assert_value!(tokio::runtime::EnterGuard<'_>: Send & Sync & Unpin); +assert_value!(tokio::runtime::EnterGuard<'_>: !Send & Sync & Unpin); assert_value!(tokio::runtime::Handle: Send & Sync & Unpin); assert_value!(tokio::runtime::Runtime: Send & Sync & Unpin);