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> {}
111