Skip to content

Commit 3d4596a

Browse files
authored
Merge pull request SSheldon#8 from madsmtm/id-fix-send-sync
Fix `Send` and `Sync` implementations on `Id` and `WeakId`
2 parents d9cb5c2 + 684eac4 commit 3d4596a

File tree

1 file changed

+26
-5
lines changed

1 file changed

+26
-5
lines changed

objc_id/src/id.rs

+26-5
Original file line numberDiff line numberDiff line change
@@ -104,11 +104,30 @@ where
104104
}
105105
}
106106

107-
unsafe impl<T, O> Sync for Id<T, O> where T: Sync {}
107+
/// The `Send` implementation requires `T: Sync` because `Id<T, Shared>` give
108+
/// access to `&T`.
109+
///
110+
/// Additiontally, it requires `T: Send` because if `T: !Send`, you could
111+
/// clone a `Id<T, Shared>`, send it to another thread, and drop the clone
112+
/// last, making `dealloc` get called on the other thread, and violate
113+
/// `T: !Send`.
114+
unsafe impl<T: Sync + Send> Send for Id<T, Shared> {}
115+
116+
/// The `Sync` implementation requires `T: Sync` because `&Id<T, Shared>` give
117+
/// access to `&T`.
118+
///
119+
/// Additiontally, it requires `T: Send`, because if `T: !Send`, you could
120+
/// clone a `&Id<T, Shared>` from another thread, and drop the clone last,
121+
/// making `dealloc` get called on the other thread, and violate `T: !Send`.
122+
unsafe impl<T: Sync + Send> Sync for Id<T, Shared> {}
108123

109-
unsafe impl<T> Send for Id<T, Owned> where T: Send {}
124+
/// `Id<T, Owned>` are `Send` if `T` is `Send` because they give the same
125+
/// access as having a T directly.
126+
unsafe impl<T: Send> Send for Id<T, Owned> {}
110127

111-
unsafe impl<T> Send for Id<T, Shared> where T: Sync {}
128+
/// `Id<T, Owned>` are `Sync` if `T` is `Sync` because they give the same
129+
/// access as having a `T` directly.
130+
unsafe impl<T: Sync> Sync for Id<T, Owned> {}
112131

113132
impl<T, O> Deref for Id<T, O> {
114133
type Target = T;
@@ -196,9 +215,11 @@ where
196215
}
197216
}
198217

199-
unsafe impl<T> Sync for WeakId<T> where T: Sync {}
218+
/// This implementation follows the same reasoning as `Id<T, Shared>`.
219+
unsafe impl<T: Sync + Send> Sync for WeakId<T> {}
200220

201-
unsafe impl<T> Send for WeakId<T> where T: Sync {}
221+
/// This implementation follows the same reasoning as `Id<T, Shared>`.
222+
unsafe impl<T: Sync + Send> Send for WeakId<T> {}
202223

203224
#[cfg(test)]
204225
mod tests {

0 commit comments

Comments
 (0)