35
35
36
36
use std:: cast;
37
37
use std:: sync:: atomics;
38
+ use std:: ty:: Unsafe ;
38
39
39
40
// NB: all links are done as AtomicUint instead of AtomicPtr to allow for static
40
41
// initialization.
@@ -50,22 +51,22 @@ pub struct DummyNode {
50
51
51
52
pub struct Queue < T > {
52
53
head : atomics:: AtomicUint ,
53
- tail : * mut Node < T > ,
54
+ tail : Unsafe < * mut Node < T > > ,
54
55
stub : DummyNode ,
55
56
}
56
57
57
58
impl < T : Send > Queue < T > {
58
59
pub fn new ( ) -> Queue < T > {
59
60
Queue {
60
61
head : atomics:: AtomicUint :: new ( 0 ) ,
61
- tail : 0 as * mut Node < T > ,
62
+ tail : Unsafe :: new ( 0 as * mut Node < T > ) ,
62
63
stub : DummyNode {
63
64
next : atomics:: AtomicUint :: new ( 0 ) ,
64
65
} ,
65
66
}
66
67
}
67
68
68
- pub unsafe fn push ( & mut self , node : * mut Node < T > ) {
69
+ pub unsafe fn push ( & self , node : * mut Node < T > ) {
69
70
( * node) . next . store ( 0 , atomics:: Release ) ;
70
71
let prev = self . head . swap ( node as uint , atomics:: AcqRel ) ;
71
72
@@ -93,8 +94,8 @@ impl<T: Send> Queue<T> {
93
94
/// Right now consumers of this queue must be ready for this fact. Just
94
95
/// because `pop` returns `None` does not mean that there is not data
95
96
/// on the queue.
96
- pub unsafe fn pop ( & mut self ) -> Option < * mut Node < T > > {
97
- let tail = self . tail ;
97
+ pub unsafe fn pop ( & self ) -> Option < * mut Node < T > > {
98
+ let tail = * self . tail . get ( ) ;
98
99
let mut tail = if !tail. is_null ( ) { tail} else {
99
100
cast:: transmute ( & self . stub )
100
101
} ;
@@ -103,12 +104,12 @@ impl<T: Send> Queue<T> {
103
104
if next. is_null ( ) {
104
105
return None ;
105
106
}
106
- self . tail = next;
107
+ * self . tail . get ( ) = next;
107
108
tail = next;
108
109
next = ( * next) . next ( atomics:: Relaxed ) ;
109
110
}
110
111
if !next. is_null ( ) {
111
- self . tail = next;
112
+ * self . tail . get ( ) = next;
112
113
return Some ( tail) ;
113
114
}
114
115
let head = self . head . load ( atomics:: Acquire ) as * mut Node < T > ;
@@ -119,7 +120,7 @@ impl<T: Send> Queue<T> {
119
120
self . push ( stub) ;
120
121
next = ( * tail) . next ( atomics:: Relaxed ) ;
121
122
if !next. is_null ( ) {
122
- self . tail = next;
123
+ * self . tail . get ( ) = next;
123
124
return Some ( tail) ;
124
125
}
125
126
return None
@@ -133,7 +134,7 @@ impl<T: Send> Node<T> {
133
134
next : atomics:: AtomicUint :: new ( 0 ) ,
134
135
}
135
136
}
136
- pub unsafe fn next ( & mut self , ord : atomics:: Ordering ) -> * mut Node < T > {
137
+ pub unsafe fn next ( & self , ord : atomics:: Ordering ) -> * mut Node < T > {
137
138
cast:: transmute :: < uint , * mut Node < T > > ( self . next . load ( ord) )
138
139
}
139
140
}
0 commit comments