hyper/common/
sync_wrapper.rs

1/*
2 * This is a copy of the sync_wrapper crate.
3 */
4
5/// A mutual exclusion primitive that relies on static type information only
6///
7/// In some cases synchronization can be proven statically: whenever you hold an exclusive `&mut`
8/// reference, the Rust type system ensures that no other part of the program can hold another
9/// reference to the data. Therefore it is safe to access it even if the current thread obtained
10/// this reference via a channel. Whenever this is the case, the overhead of allocating and locking
11/// a [`Mutex`] can be avoided by using this static version.
12///
13/// One example where this is often applicable is [`Future`], which requires an exclusive reference
14/// for its [`poll`] method: While a given `Future` implementation may not be safe to access by
15/// multiple threads concurrently, the executor can only run the `Future` on one thread at any
16/// given time, making it [`Sync`] in practice as long as the implementation is `Send`. You can
17/// therefore use the sync wrapper to prove that your data structure is `Sync` even though it
18/// contains such a `Future`.
19///
20/// # Example
21///
22/// ```ignore
23/// use hyper::common::sync_wrapper::SyncWrapper;
24/// use std::future::Future;
25///
26/// struct MyThing {
27///     future: SyncWrapper<Box<dyn Future<Output = String> + Send>>,
28/// }
29///
30/// impl MyThing {
31///     // all accesses to `self.future` now require an exclusive reference or ownership
32/// }
33///
34/// fn assert_sync<T: Sync>() {}
35///
36/// assert_sync::<MyThing>();
37/// ```
38///
39/// [`Mutex`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html
40/// [`Future`]: https://doc.rust-lang.org/std/future/trait.Future.html
41/// [`poll`]: https://doc.rust-lang.org/std/future/trait.Future.html#method.poll
42/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
43#[repr(transparent)]
44pub(crate) struct SyncWrapper<T>(T);
45
46impl<T> SyncWrapper<T> {
47    /// Creates a new SyncWrapper containing the given value.
48    ///
49    /// # Examples
50    ///
51    /// ```ignore
52    /// use hyper::common::sync_wrapper::SyncWrapper;
53    ///
54    /// let wrapped = SyncWrapper::new(42);
55    /// ```
56    pub(crate) fn new(value: T) -> Self {
57        Self(value)
58    }
59
60    /// Acquires a reference to the protected value.
61    ///
62    /// This is safe because it requires an exclusive reference to the wrapper. Therefore this method
63    /// neither panics nor does it return an error. This is in contrast to [`Mutex::get_mut`] which
64    /// returns an error if another thread panicked while holding the lock. It is not recommended
65    /// to send an exclusive reference to a potentially damaged value to another thread for further
66    /// processing.
67    ///
68    /// [`Mutex::get_mut`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html#method.get_mut
69    ///
70    /// # Examples
71    ///
72    /// ```ignore
73    /// use hyper::common::sync_wrapper::SyncWrapper;
74    ///
75    /// let mut wrapped = SyncWrapper::new(42);
76    /// let value = wrapped.get_mut();
77    /// *value = 0;
78    /// assert_eq!(*wrapped.get_mut(), 0);
79    /// ```
80    pub(crate) fn get_mut(&mut self) -> &mut T {
81        &mut self.0
82    }
83
84    /// Consumes this wrapper, returning the underlying data.
85    ///
86    /// This is safe because it requires ownership of the wrapper, aherefore this method will neither
87    /// panic nor does it return an error. This is in contrast to [`Mutex::into_inner`] which
88    /// returns an error if another thread panicked while holding the lock. It is not recommended
89    /// to send an exclusive reference to a potentially damaged value to another thread for further
90    /// processing.
91    ///
92    /// [`Mutex::into_inner`]: https://doc.rust-lang.org/std/sync/struct.Mutex.html#method.into_inner
93    ///
94    /// # Examples
95    ///
96    /// ```ignore
97    /// use hyper::common::sync_wrapper::SyncWrapper;
98    ///
99    /// let mut wrapped = SyncWrapper::new(42);
100    /// assert_eq!(wrapped.into_inner(), 42);
101    /// ```
102    #[allow(dead_code)]
103    pub(crate) fn into_inner(self) -> T {
104        self.0
105    }
106}
107
108// this is safe because the only operations permitted on this data structure require exclusive
109// access or ownership
110unsafe impl<T: Send> Sync for SyncWrapper<T> {}