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)] 44 pub(crate) struct SyncWrapper<T>(T); 45 46 impl<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 /// ``` new(value: T) -> Self56 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 /// ``` get_mut(&mut self) -> &mut T80 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)] into_inner(self) -> T103 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 110 unsafe impl<T: Send> Sync for SyncWrapper<T> {} 111