Rollup merge of #154526 - asder8215:no_threads_read_overflow, r=Mark-Simulacrum

Panic/return false on overflow in no_threads read/try_read impl

As per discussion with Mark in rust-lang/rust#153555, it's possible for `no_threads` impl of `RwLock` to trigger a silent overflow on `RwLock::read`/`RwLock::try_read` if we try to acquire more than `isize::MAX` read locks. This PR adds an explicit panic/return false when our read lock counter is at `isize::MAX` for `RwLock::read`/`RwLock::try_read`; the message is similar to that of sys/sync/rwlock/futex.rs [here](https://github.com/rust-lang/rust/blob/fb27476aaf1012f1f6ace6306f9b990e0d989c31/library/std/src/sys/sync/rwlock/futex.rs#L143).
This commit is contained in:
Jonathan Brouwer
2026-04-04 17:19:12 +02:00
committed by GitHub
+10 -4
View File
@@ -18,7 +18,7 @@ pub const fn new() -> RwLock {
pub fn read(&self) {
let m = self.mode.get();
if m >= 0 {
self.mode.set(m + 1);
self.mode.set(m.checked_add(1).expect("rwlock overflowed read locks"));
} else {
rtabort!("rwlock locked for writing");
}
@@ -28,6 +28,9 @@ pub fn read(&self) {
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 {
@@ -56,16 +59,19 @@ pub fn try_write(&self) -> bool {
#[inline]
pub unsafe fn read_unlock(&self) {
self.mode.set(self.mode.get() - 1);
assert!(
self.mode.replace(self.mode.get() - 1) > 0,
"rwlock has not been locked for reading"
);
}
#[inline]
pub unsafe fn write_unlock(&self) {
assert_eq!(self.mode.replace(0), -1);
assert_eq!(self.mode.replace(0), -1, "rwlock has not been locked for writing");
}
#[inline]
pub unsafe fn downgrade(&self) {
assert_eq!(self.mode.replace(1), -1);
assert_eq!(self.mode.replace(1), -1, "rwlock has not been locked for writing");
}
}