1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36
/// Turns any type that implements `Send` into one that also implements `Sync` by only allowing /// mutable access if the inner type is not `Sync`. /// /// This is commonly useful with collections like `ResourceSet`, because it allows you to only /// require a `Send` bound for data you only intend to access mutably. pub struct MakeSync<T>(T); impl<T> MakeSync<T> { pub fn new(t: T) -> Self { MakeSync(t) } pub fn into_inner(self) -> T { self.0 } pub fn get_mut(&mut self) -> &mut T { &mut self.0 } } impl<T: Sync> MakeSync<T> { pub fn get(&self) -> &T { &self.0 } } // Safe because if `T` is `!Sync` then *ONLY* mutable access is allowed to the inner type, and // therefore any access of the inner type is unique and cannot cause data races. // // If you send a `&MakeSync<T>` to another thread for some T: !Sync, then the reference you send is // completely inert, you cannot access the inner T at all. // // Note that we rely on the automatic implementation of `Send` for `MakeSync<T>` which requires `T` // to be `Send` in order to send a `&mut MakeSync<T>` to another thread. unsafe impl<T> Sync for MakeSync<T> {}