What shall Sync mean across an .await?

I’d be not too sure if it is impossible to create concurrent access with “safe” code. I’m thinking about copying a reference out of the future into thread-local storage or something, but that doesn’t really work with the lifetimes. Maybe it is safe in some sense... hmm...

This is an interesting idea. It just inspired me to do a wrapper type about which I’m curious if it is:

(a) safe, and

(b) already implemented in some crate.

This wrapper would, I believe, remove the need of using unsafe directly, if you wrap the problematic fields inside the Stream. Or you could even have the whole stream be contained inside such a wrapper (and then perhaps wrapped again for the Stream instance... or even make the wrapper #[fundamental] or something):

(playground)

#[repr(transparent)]
pub struct SyncWrapper<T: ?Sized> (T);

impl<T> SyncWrapper<T> {
    pub fn new(t: T) -> SyncWrapper<T> { SyncWrapper(t) }
    pub fn into_inner(self) -> T { self.0 }
}

impl<T: ?Sized> SyncWrapper<T> {
    pub fn get_mut(&mut self) -> &mut T { &mut self.0 }
}

// reason for safety: an immutable reference to SyncWrapper<T> is worthless,
// hence it’s safe to share such a reference between threads
unsafe impl<T: ?Sized> Sync for SyncWrapper<T> {}
2 Likes