-
Notifications
You must be signed in to change notification settings - Fork 13.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RwLock::read() should be reentrant so its behavior will be the same as borrow checker #114770
Comments
RwLock::read() is indeed re-entrantable multiple reads. See https://doc.rust-lang.org/std/sync/struct.RwLock.html#examples |
I did not noticed the example on |
I guess it is copied from https://doc.rust-lang.org/std/sync/struct.Mutex.html#panics and forgot to change. |
This is a deadlock, as the write attempt is ordered before the second read attempt, so the read will block on its completion; but the write attempt is blocked on the release of the first read-lock, which will not occur since thread 1 is blocked. The choice of writer-preference was made as it simplifies implementations and leads to much better write latency when having many readers and few writers (this should be very common). Also, at least on Windows, |
The second lock on the Thread 1 don't need to acquire the lock again because the current thread already hold on the lock. It should be simply to return a reference to the value without trying to acquire the lock. |
It needs to increase the read lock count to ensure it doesn't get unlocked before all read lock guards are gone. And on Windows this read lock count increasing will block waiting on any writers as SRWLOCK is writer preferring. |
That means we'd need to keep track of which threads have read-locked the rwlock, instead of just the total number of readers. That's not something we track today. We'd need to keep a lot of additional data to do that, resulting in a lot of overhead. |
Could you elaborate what additional data that need to keep? AFAIK it should be only one TLS field that need to be added to |
Accessing a thread local variable is a significant amount of overhead compared to just a single atomic operation to lock/unlock. Also, creating a new thread local variable for every RwLock can also be a significant amount of overhead, depending on the TLS implementation. |
Let's say I have the following code:
If someone call
bar
it may cause a panic inbaz
because theitems
is already locked bybar
. The above code will be working ifitems
is not putting behindRwLock
but I will not be able to push the item intoitems
. If I lock theFoo
instead of its field it will solve this problem but it will cumbersome to work withFoo
if most of it fields is immutable.The text was updated successfully, but these errors were encountered: