Skip to content

Commit cc5a1aa

Browse files
authored
Rollup merge of #77722 - fusion-engineering-forks:safe-unsupported-locks, r=Mark-Simulacrum
Remove unsafety from sys/unsupported and add deny(unsafe_op_in_unsafe_fn). Replacing `UnsafeCell`s by a `Cell`s simplifies things and makes the mutex and rwlock implementations safe. Other than that, only unsafety in strlen() contained unsafe code. @rustbot modify labels: +F-unsafe-block-in-unsafe-fn +C-cleanup
2 parents 7de5fe7 + af414dc commit cc5a1aa

File tree

6 files changed

+34
-37
lines changed

6 files changed

+34
-37
lines changed

library/std/src/sys/unsupported/common.rs

+8-5
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,13 @@ pub fn hashmap_random_keys() -> (u64, u64) {
3939
pub enum Void {}
4040

4141
pub unsafe fn strlen(mut s: *const c_char) -> usize {
42-
let mut n = 0;
43-
while *s != 0 {
44-
n += 1;
45-
s = s.offset(1);
42+
// SAFETY: The caller must guarantee `s` points to a valid 0-terminated string.
43+
unsafe {
44+
let mut n = 0;
45+
while *s != 0 {
46+
n += 1;
47+
s = s.offset(1);
48+
}
49+
n
4650
}
47-
return n;
4851
}

library/std/src/sys/unsupported/mod.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
#![deny(unsafe_op_in_unsafe_fn)]
2+
13
pub mod alloc;
24
pub mod args;
35
pub mod cmath;

library/std/src/sys/unsupported/mutex.rs

+7-14
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
use crate::cell::UnsafeCell;
1+
use crate::cell::Cell;
22

33
pub struct Mutex {
4-
locked: UnsafeCell<bool>,
4+
// This platform has no threads, so we can use a Cell here.
5+
locked: Cell<bool>,
56
}
67

78
pub type MovableMutex = Mutex;
@@ -11,33 +12,25 @@ unsafe impl Sync for Mutex {} // no threads on this platform
1112

1213
impl Mutex {
1314
pub const fn new() -> Mutex {
14-
Mutex { locked: UnsafeCell::new(false) }
15+
Mutex { locked: Cell::new(false) }
1516
}
1617

1718
#[inline]
1819
pub unsafe fn init(&mut self) {}
1920

2021
#[inline]
2122
pub unsafe fn lock(&self) {
22-
let locked = self.locked.get();
23-
assert!(!*locked, "cannot recursively acquire mutex");
24-
*locked = true;
23+
assert_eq!(self.locked.replace(true), false, "cannot recursively acquire mutex");
2524
}
2625

2726
#[inline]
2827
pub unsafe fn unlock(&self) {
29-
*self.locked.get() = false;
28+
self.locked.set(false);
3029
}
3130

3231
#[inline]
3332
pub unsafe fn try_lock(&self) -> bool {
34-
let locked = self.locked.get();
35-
if *locked {
36-
false
37-
} else {
38-
*locked = true;
39-
true
40-
}
33+
self.locked.replace(true) == false
4134
}
4235

4336
#[inline]

library/std/src/sys/unsupported/rwlock.rs

+15-18
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,33 @@
1-
use crate::cell::UnsafeCell;
1+
use crate::cell::Cell;
22

33
pub struct RWLock {
4-
mode: UnsafeCell<isize>,
4+
// This platform has no threads, so we can use a Cell here.
5+
mode: Cell<isize>,
56
}
67

78
unsafe impl Send for RWLock {}
89
unsafe impl Sync for RWLock {} // no threads on this platform
910

1011
impl RWLock {
1112
pub const fn new() -> RWLock {
12-
RWLock { mode: UnsafeCell::new(0) }
13+
RWLock { mode: Cell::new(0) }
1314
}
1415

1516
#[inline]
1617
pub unsafe fn read(&self) {
17-
let mode = self.mode.get();
18-
if *mode >= 0 {
19-
*mode += 1;
18+
let m = self.mode.get();
19+
if m >= 0 {
20+
self.mode.set(m + 1);
2021
} else {
2122
rtabort!("rwlock locked for writing");
2223
}
2324
}
2425

2526
#[inline]
2627
pub unsafe fn try_read(&self) -> bool {
27-
let mode = self.mode.get();
28-
if *mode >= 0 {
29-
*mode += 1;
28+
let m = self.mode.get();
29+
if m >= 0 {
30+
self.mode.set(m + 1);
3031
true
3132
} else {
3233
false
@@ -35,19 +36,15 @@ impl RWLock {
3536

3637
#[inline]
3738
pub unsafe fn write(&self) {
38-
let mode = self.mode.get();
39-
if *mode == 0 {
40-
*mode = -1;
41-
} else {
39+
if self.mode.replace(-1) != 0 {
4240
rtabort!("rwlock locked for reading")
4341
}
4442
}
4543

4644
#[inline]
4745
pub unsafe fn try_write(&self) -> bool {
48-
let mode = self.mode.get();
49-
if *mode == 0 {
50-
*mode = -1;
46+
if self.mode.get() == 0 {
47+
self.mode.set(-1);
5148
true
5249
} else {
5350
false
@@ -56,12 +53,12 @@ impl RWLock {
5653

5754
#[inline]
5855
pub unsafe fn read_unlock(&self) {
59-
*self.mode.get() -= 1;
56+
self.mode.set(self.mode.get() - 1);
6057
}
6158

6259
#[inline]
6360
pub unsafe fn write_unlock(&self) {
64-
*self.mode.get() += 1;
61+
assert_eq!(self.mode.replace(0), -1);
6562
}
6663

6764
#[inline]

library/std/src/sys/wasi/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ pub mod thread_local_key;
5353
pub mod time;
5454

5555
#[path = "../unsupported/common.rs"]
56+
#[deny(unsafe_op_in_unsafe_fn)]
5657
#[allow(unused)]
5758
mod common;
5859
pub use common::*;

library/std/src/sys/wasm/mod.rs

+1
Original file line numberDiff line numberDiff line change
@@ -66,5 +66,6 @@ cfg_if::cfg_if! {
6666
}
6767

6868
#[path = "../unsupported/common.rs"]
69+
#[deny(unsafe_op_in_unsafe_fn)]
6970
mod common;
7071
pub use common::*;

0 commit comments

Comments
 (0)