tokio/util/
sync_wrapper.rs

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
6use std::any::Any;
7
8pub(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.
14unsafe 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.
18unsafe impl<T> Sync for SyncWrapper<T> {}
19
20impl<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
30impl 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}