[core] add Exclusive
to sync by guswynn · Pull Request #97629 · rust-lang/rust (original) (raw)
(discussed here: https://rust-lang.zulipchat.com/#narrow/stream/219381-t-libs/topic/Adding.20.60SyncWrapper.60.20to.20std)
Exclusive
is a wrapper that exclusively allows mutable access to the inner value if you have exclusive access to the wrapper. It acts like a compile time mutex, and hold an unconditional Sync
implementation.
Justification for inclusion into std
- This wrapper unblocks actual problems:
- The example that I hit was a vector of
futures::future::BoxFuture
's causing a central struct in a script to be non-Sync
. To work around it, you either write really difficult code, or wrap the futures in a needless mutex.
- The example that I hit was a vector of
- Easy to maintain: this struct is as simple as a wrapper can get, and its
Sync
implementation has very clear reasoning - Fills a gap:
&/&mut
are toRwLock
asExclusive
is toMutex
Public Api
// core::sync #[derive(Default)] struct Exclusive<T: ?Sized> { ... }
impl<T: ?Sized> Sync for Exclusive {}
impl Exclusive { pub const fn new(t: T) -> Self; pub const fn into_inner(self) -> T; }
impl<T: ?Sized> Exclusive { pub const fn get_mut(&mut self) -> &mut T; pub const fn get_pin_mut(Pin<&mut self>) -> Pin<&mut T>; pub const fn from_mut(&mut T) -> &mut Exclusive; pub const fn from_pin_mut(Pin<&mut T>) -> Pin<&mut Exclusive>; }
impl<T: Future> Future for Exclusive { ... }
impl From for Exclusive { ... } impl<T: ?Sized> Debug for Exclusive { ... }
Naming
This is a big bikeshed, but I felt that Exclusive
captured its general purpose quite well.
Stability and location
As this is so simple, it can be in core
. I feel that it can be stabilized quite soon after it is merged, if the libs teams feels its reasonable to add. Also, I don't really know how unstable feature work in std/core's codebases, so I might need help fixing them
Tips for review
The docs probably are the thing that needs to be reviewed! I tried my best, but I'm sure people have more experience than me writing docs for Core
Implementation:
The API is mostly pulled from https://docs.rs/sync_wrapper/latest/sync_wrapper/struct.SyncWrapper.html (which is apache 2.0 licenesed), and the implementation is trivial:
- its an unsafe justification for pinning
- its an unsafe justification for the
Sync
impl (mostly reasoned about by @danielhenrymantilla here: Remove the T : Send bound for SyncWrapper to be Sync Actyx/sync_wrapper#2) - and forwarding impls, starting with derivable ones and
Future