@@ -45,6 +45,7 @@ use option::{Option, None, Some};
45
45
use owned:: Box ;
46
46
use ptr:: RawPtr ;
47
47
use sync:: atomics:: { AtomicPtr , Release , Acquire , AcqRel , Relaxed } ;
48
+ use ty:: Unsafe ;
48
49
49
50
/// A result of the `pop` function.
50
51
pub enum PopResult < T > {
@@ -69,7 +70,7 @@ struct Node<T> {
69
70
/// popper at a time (many pushers are allowed).
70
71
pub struct Queue < T > {
71
72
head : AtomicPtr < Node < T > > ,
72
- tail : * mut Node < T > ,
73
+ tail : Unsafe < * mut Node < T > > ,
73
74
}
74
75
75
76
impl < T > Node < T > {
@@ -88,12 +89,12 @@ impl<T: Send> Queue<T> {
88
89
let stub = unsafe { Node :: new ( None ) } ;
89
90
Queue {
90
91
head : AtomicPtr :: new ( stub) ,
91
- tail : stub,
92
+ tail : Unsafe :: new ( stub) ,
92
93
}
93
94
}
94
95
95
96
/// Pushes a new value onto this queue.
96
- pub fn push ( & mut self , t : T ) {
97
+ pub fn push ( & self , t : T ) {
97
98
unsafe {
98
99
let n = Node :: new ( Some ( t) ) ;
99
100
let prev = self . head . swap ( n, AcqRel ) ;
@@ -111,13 +112,13 @@ impl<T: Send> Queue<T> {
111
112
///
112
113
/// This inconsistent state means that this queue does indeed have data, but
113
114
/// it does not currently have access to it at this time.
114
- pub fn pop ( & mut self ) -> PopResult < T > {
115
+ pub fn pop ( & self ) -> PopResult < T > {
115
116
unsafe {
116
- let tail = self . tail ;
117
+ let tail = * self . tail . get ( ) ;
117
118
let next = ( * tail) . next . load ( Acquire ) ;
118
119
119
120
if !next. is_null ( ) {
120
- self . tail = next;
121
+ * self . tail . get ( ) = next;
121
122
assert ! ( ( * tail) . value. is_none( ) ) ;
122
123
assert ! ( ( * next) . value. is_some( ) ) ;
123
124
let ret = ( * next) . value . take_unwrap ( ) ;
@@ -131,7 +132,7 @@ impl<T: Send> Queue<T> {
131
132
132
133
/// Attempts to pop data from this queue, but doesn't attempt too hard. This
133
134
/// will canonicalize inconsistent states to a `None` value.
134
- pub fn casual_pop ( & mut self ) -> Option < T > {
135
+ pub fn casual_pop ( & self ) -> Option < T > {
135
136
match self . pop ( ) {
136
137
Data ( t) => Some ( t) ,
137
138
Empty | Inconsistent => None ,
@@ -143,7 +144,7 @@ impl<T: Send> Queue<T> {
143
144
impl < T : Send > Drop for Queue < T > {
144
145
fn drop ( & mut self ) {
145
146
unsafe {
146
- let mut cur = self . tail ;
147
+ let mut cur = * self . tail . get ( ) ;
147
148
while !cur. is_null ( ) {
148
149
let next = ( * cur) . next . load ( Relaxed ) ;
149
150
let _: Box < Node < T > > = mem:: transmute ( cur) ;
0 commit comments