From 0d5eac6dcaffb12098ffd314ba929c01e88c61e8 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 15 Jun 2021 12:34:40 +0200 Subject: [PATCH 1/2] Correct Send and Sync implementations on Id See comments in the code for reasoning. The impl for `Id` is the same as `Arc` and the impl for `Id` is the same as `Box`. --- src/id.rs | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/src/id.rs b/src/id.rs index b679f3b..203cd45 100644 --- a/src/id.rs +++ b/src/id.rs @@ -80,11 +80,30 @@ impl Clone for Id where T: Message { } } -unsafe impl Sync for Id where T: Sync { } - -unsafe impl Send for Id where T: Send { } - -unsafe impl Send for Id where T: Sync { } +/// The `Send` implementation requires `T: Sync` because `Id` give +/// access to `&T`. +/// +/// Additiontally, it requires `T: Send` because if `T: !Send`, you could +/// clone a `Id`, send it to another thread, and drop the clone +/// last, making `dealloc` get called on the other thread, and violate +/// `T: !Send`. +unsafe impl Send for Id {} + +/// The `Sync` implementation requires `T: Sync` because `&Id` give +/// access to `&T`. +/// +/// Additiontally, it requires `T: Send`, because if `T: !Send`, you could +/// clone a `&Id` from another thread, and drop the clone last, +/// making `dealloc` get called on the other thread, and violate `T: !Send`. +unsafe impl Sync for Id {} + +/// `Id` are `Send` if `T` is `Send` because they give the same +/// access as having a T directly. +unsafe impl Send for Id {} + +/// `Id` are `Sync` if `T` is `Sync` because they give the same +/// access as having a `T` directly. +unsafe impl Sync for Id {} impl Deref for Id { type Target = T; From 8833c22ea3f7e199756721f11cceb090aaa992f7 Mon Sep 17 00:00:00 2001 From: Mads Marquart Date: Tue, 15 Jun 2021 12:42:55 +0200 Subject: [PATCH 2/2] Correct Send and Sync implementations on WeakId The implementations follow the same reasoning as `Id`, since you can upgrade `WeakId` to `Id`. --- src/id.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/id.rs b/src/id.rs index 203cd45..f6eee1c 100644 --- a/src/id.rs +++ b/src/id.rs @@ -180,9 +180,11 @@ impl WeakId where T: Message { } } -unsafe impl Sync for WeakId where T: Sync { } +/// This implementation follows the same reasoning as `Id`. +unsafe impl Sync for WeakId {} -unsafe impl Send for WeakId where T: Sync { } +/// This implementation follows the same reasoning as `Id`. +unsafe impl Send for WeakId {} #[cfg(test)] mod tests {