Is there a race condition in the register function as well? After getting the current Vacant entry, and before inserting a new Waiting value, could another task also insert its own Waiting value, given that the "check for vacancy then register intent" logic doesn't seem to be atomic?
Is this right, or could someone please explain how that part works? Maybe it's a fail-safe scenario which leads to doing the work twice or more, rather than exactly once?
Great article and writeup. We will be including this piece in our upcoming newsletter issue.
Thanks for putting this into writing.
Is there a race condition in the register function as well? After getting the current Vacant entry, and before inserting a new Waiting value, could another task also insert its own Waiting value, given that the "check for vacancy then register intent" logic doesn't seem to be atomic?
Is this right, or could someone please explain how that part works? Maybe it's a fail-safe scenario which leads to doing the work twice or more, rather than exactly once?
My understanding is that DashMap's `entry` acquires the lock (https://github.com/xacrimon/dashmap/blob/366ce7e7872866a06de66eb95002fa6cf2c117a7/src/lib.rs#L1145-L1168) on the relevant shard for the lifetime of the entry.
```
pub fn register(&self, key: K) -> bool {
let entry = self.items.entry(key); // Lock acquired, stored in `entry`
match entry {
Entry::Occupied(_) => false, // Lock still held
Entry::Vacant(entry) => {
entry.insert(...); // Lock still held during insert
true
}
}
} // `entry` dropped here, lock released
```
So no-one else would be able to insert Waiting value to items (DashMap)
Nice article.
I actually just noticed this `pin!` call looked superfluous and removed it! https://github.com/astral-sh/uv/pull/17502
Good catch!