Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions library/std/src/sys/sync/rwlock/no_threads.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ impl RwLock {
#[inline]
pub fn read(&self) {
let m = self.mode.get();

// Check for overflow.
assert!(m == isize::MAX, "too many active read locks on RwLock");

if m >= 0 {
self.mode.set(m + 1);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's write this as m.checked_add(1).expect("rwlock overflowed read locks"), and same with below.

I would also move the subtraction in the unlock code to do the same. It's not as necessary, but I think it would be good to confirm we are in fact holding a read lock and should be cheap for this implementation.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

For RwLock::read_unlock, I used mem::replace, just like in RwLock::write_unlock,and checked if the old value is greater than 0 to see if it was read locked, asserting an error if it wasn't. I added an error msg for RwLock::write and RwLock::downgrade.

However, I do wonder if it's better if we use an assertion check to see if the lock is read/write locked, and then set the RwLock mode accordingly instead of mem::replace since we probably shouldn't mem::replace the mode value with 0 if in RwLock::read_unlock/RwLock::write_unlock if it was write locked/read locked.

} else {
Expand All @@ -28,6 +32,9 @@ impl RwLock {
pub fn try_read(&self) -> bool {
let m = self.mode.get();
if m >= 0 {
if m == isize::MAX {
return false;
}
self.mode.set(m + 1);
true
} else {
Expand Down
Loading