Skip to content

Commit 8ec744d

Browse files
committed
Improve the SAFETY: comments and use the Arc::{into/from}_raw functions
1 parent bbcd3b2 commit 8ec744d

File tree

3 files changed

+12
-15
lines changed

3 files changed

+12
-15
lines changed

src/libstd/sync/mpsc/blocking.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
//! Generic support for building blocking abstractions.
22
3-
use crate::mem;
43
use crate::sync::atomic::{AtomicBool, Ordering};
54
use crate::sync::Arc;
65
use crate::thread::{self, Thread};
@@ -47,9 +46,7 @@ impl SignalToken {
4746
/// flag.
4847
#[inline]
4948
pub unsafe fn cast_to_usize(self) -> usize {
50-
// SAFETY: this ok because of the internal represention of Arc, which
51-
// is a pointer and phantom data (so the size of a pointer -> a usize).
52-
unsafe { mem::transmute(self.inner) }
49+
Arc::into_raw(self.inner) as usize
5350
}
5451

5552
/// Converts from an unsafe usize value. Useful for retrieving a pipe's state
@@ -58,7 +55,10 @@ impl SignalToken {
5855
pub unsafe fn cast_from_usize(signal_ptr: usize) -> SignalToken {
5956
// SAFETY: this ok because of the internal represention of Arc, which
6057
// is a pointer and phantom data (so the size of a pointer -> a usize).
61-
SignalToken { inner: unsafe { mem::transmute(signal_ptr) } }
58+
//
59+
// NOTE: The call to `from_raw` is used in conjuction with the call to
60+
// `into_raw` made in the `SignalToken::cast_to_usize` method.
61+
SignalToken { inner: unsafe { Arc::from_raw(signal_ptr as *const _) } }
6262
}
6363
}
6464

src/libstd/sync/mpsc/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -651,7 +651,7 @@ trait UnsafeFlavor<T> {
651651
// SAFETY: We are sure the inner value will never be NUL when this is
652652
// called, the invariants of the module make it so.
653653
//
654-
// It is also ensured that no other (mutable) reference will be handed
654+
// The caller ensures that no other (mutable) reference will be handed
655655
// out while the one returned here is in action.
656656
unsafe { &mut *self.inner_unsafe().get() }
657657
}

src/libstd/sync/mpsc/spsc_queue.rs

+6-9
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ impl<T, ProducerAddition, ConsumerAddition> Queue<T, ProducerAddition, ConsumerA
9999
) -> Self {
100100
let n1 = Node::new();
101101
let n2 = Node::new();
102-
// SAFETY: At this point we know the pointer is not NUL since it was
103-
// build just above.
102+
// SAFETY: At this point we know the pointer is valid: it was built
103+
// just above.
104104
unsafe { (*n1).next.store(n2, Ordering::Relaxed) }
105105
Queue {
106106
consumer: CacheAligned::new(Consumer {
@@ -135,13 +135,10 @@ impl<T, ProducerAddition, ConsumerAddition> Queue<T, ProducerAddition, ConsumerA
135135
}
136136

137137
unsafe fn alloc(&self) -> *mut Node<T> {
138-
// First try to see if we can consume the 'first' node for our uses.
139-
// SAFEY: Since `self` is a valid reference, accessing its inner values
140-
// can be considered safe (without checking for NUL pointers).
141-
//
142-
// Dereferencing of `ret` are safe too because the pointer comes from
143-
// `self` once again.
138+
// SAFEY: ??? Explain why the pointers are safe to dereference and why
139+
// returning a mutable pointer is ok. ???
144140
unsafe {
141+
// First try to see if we can consume the 'first' node for our uses.
145142
if *self.producer.first.get() != *self.producer.tail_copy.get() {
146143
let ret = *self.producer.first.get();
147144
*self.producer.0.first.get() = (*ret).next.load(Ordering::Relaxed);
@@ -322,7 +319,7 @@ mod tests {
322319
}
323320

324321
unsafe fn stress_bound(bound: usize) {
325-
let q = Arc::new(Queue::with_additions(bound, (), ()));
322+
let q = Arc::new(unsafe { Queue::with_additions(bound, (), ()) });
326323

327324
let (tx, rx) = channel();
328325
let q2 = q.clone();

0 commit comments

Comments
 (0)