Is there a synchronization primitive (in sync or async Rust) that blocks on an
Arc until it has just the single reference (and no weak references)? There are a few things that work similarly:
- You can build something like this with a condition variable (though only in the synchronous world, I guess
watch does something similar in tokio).
- You can create a MPSC channel, block on the receiver and wait until you read
Arc itself is not a synchronization primitive, it is a resource management construction. are you looking for counting semaphores? I think there's a
Semaphore in tokio. however, I don't think there's one in
Arc does (implicitly) establish synchronize-with relationships in some cases (due to atomic operations with corresponding memory orderings). For example, I believe that if
Arc::try_unwrap succeeds, it is guaranteed that any previous droppings of the
Arc clones in other threads happen-before the successful
try_unwrap call. So there is some synchronization of concurrent threads taking place.
… I don't think that is possible (with the existing
Arc) because that might make dropping the
Arc more slow (as the drop handler would need to unpark any waiting threads or wakeup any waiting tasks, respectively). Adding such a feature would be a performance regression, I guess.
(But I'm not sure on all this, so I'm happy if someone else could confirm this or correct me.)
What if there was some Arc-like object where we accept slower drops? I'm wondering about an API for DMAs. I thought something like this was mentioned and dismissed in withoutboats' post but I can't find it.
I think it's possible to implement something like this (but it wouldn't be compatible with APIs that take
Arcs). Not sure if something like this already exists, or which existing synchronization primitives could be used to emulate this.
I mean, it would be trivially possible to implement this using mutexes and condition variables (edit: or mutexes and notifies in the async case), but that might be pretty inefficient. There should be a better way.
If there's only one thread waiting for mut access (and if there's more than one the problem doesn't really make sense) you could store that thread's handle inside the Arc (alongside whatever data) and call unpark on it (after) any of the other threads drop it. The mut-interested thread then just loops doing get_mut with park on failure.
This is really slick; thanks!
Block for exclusive reference - it does sound like
RwLock problem. Why don't you use it?
I think I can and that would probably be easier, thanks.
This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.