1 | //! This module contains a type that can make `Send + !Sync` types `Sync` by |
2 | //! disallowing all immutable access to the value. |
3 | //! |
4 | //! A similar primitive is provided in the `sync_wrapper` crate. |
5 | |
6 | use std::any::Any; |
7 | |
8 | pub(crate) struct SyncWrapper<T> { |
9 | value: T, |
10 | } |
11 | |
12 | // safety: The SyncWrapper being send allows you to send the inner value across |
13 | // thread boundaries. |
14 | unsafe impl<T: Send> Send for SyncWrapper<T> {} |
15 | |
16 | // safety: An immutable reference to a SyncWrapper is useless, so moving such an |
17 | // immutable reference across threads is safe. |
18 | unsafe impl<T> Sync for SyncWrapper<T> {} |
19 | |
20 | impl<T> SyncWrapper<T> { |
21 | pub(crate) fn new(value: T) -> Self { |
22 | Self { value } |
23 | } |
24 | |
25 | pub(crate) fn into_inner(self) -> T { |
26 | self.value |
27 | } |
28 | } |
29 | |
30 | impl SyncWrapper<Box<dyn Any + Send>> { |
31 | /// Attempt to downcast using `Any::downcast_ref()` to a type that is known to be `Sync`. |
32 | pub(crate) fn downcast_ref_sync<T: Any + Sync>(&self) -> Option<&T> { |
33 | // SAFETY: if the downcast fails, the inner value is not touched, |
34 | // so no thread-safety violation can occur. |
35 | self.value.downcast_ref() |
36 | } |
37 | } |
38 | |