mvdnes / spin-rs

Spin-based synchronization primitives
MIT License
471 stars 87 forks source link

Does Once require the inner type to be Sync for Send? #48

Closed boomshroom closed 6 years ago

boomshroom commented 6 years ago

I'm trying to make a type that can initialize once, but get modified later. Since Once doesn't have any methods to get a mutable reference to the inner value, I had to wrap it in a RefCell. Since I'm handling the syncronisation elsewhere, I only need the type to implement Send. I can understand needing Send and Sync to implement Sync, but does the inner type really need Sync in order to implement Send? Alternatively, since I have a mutable reference to the Once value, it would be nice to have a get_mut like method that requires a mutable/unique reference.

Ericson2314 commented 6 years ago

Are you putting the RefCell inside the Once or the Once inside the RefCell?

Ericson2314 commented 6 years ago

If you mean

MyOtherSyncronization<RefCell<Once<T>>

You probably don't want Once because you don't need the syncronization it provides.

Once itself does hand off & to concurrent readers, so it needs Sync just like RwLock as it says in the comment. Your case is special since & isn't being handed out so liberally. The solution with Once would be a wrapper type with an unsafe impl.

boomshroom commented 6 years ago

What I have is &Mutex<Trait> and struct Value(Once<RefCell<InnerValue>>) with impl Trait for Value. Really what I want is mutable access to the inner value after having mutable access to the Once itself.

Ericson2314 commented 6 years ago

@boomshroom ah ok yes that is reasonable. Sorry I forgot about the get_mut when responding to your OP.

mvdnes commented 6 years ago

We added it because RwLock had it too. However, in stdlib it was removed in https://github.com/rust-lang/rust/commit/fbf6885fd3ebc28a94007ab032ef1c9f135a0b69#diff-0dfca49424f912822edb26b8d93ae2ac.

It seems this would apply here too. Can someone confirm this?

Ericson2314 commented 6 years ago

Ah ok that makes sense. Putting the lock in an arc or static will require the sync bound so the end requirements are the same.

Put another way, RwLock puts no less onerous reqirments on T than plane T alone, unlike say Mutex where we can discharge a Sync with Send.

Ericson2314 commented 6 years ago

Maybe find original PR? But good with me!