about summary refs log tree commit diff
path: root/src/libstd/sync/mpsc_queue.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/libstd/sync/mpsc_queue.rs')
-rw-r--r--src/libstd/sync/mpsc_queue.rs30
1 files changed, 16 insertions, 14 deletions
diff --git a/src/libstd/sync/mpsc_queue.rs b/src/libstd/sync/mpsc_queue.rs
index 4cdcd05e9b4..4db24e82d37 100644
--- a/src/libstd/sync/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc_queue.rs
@@ -45,6 +45,7 @@ use option::{Option, None, Some};
 use owned::Box;
 use ptr::RawPtr;
 use sync::atomics::{AtomicPtr, Release, Acquire, AcqRel, Relaxed};
+use ty::Unsafe;
 
 /// A result of the `pop` function.
 pub enum PopResult<T> {
@@ -69,7 +70,7 @@ struct Node<T> {
 /// popper at a time (many pushers are allowed).
 pub struct Queue<T> {
     head: AtomicPtr<Node<T>>,
-    tail: *mut Node<T>,
+    tail: Unsafe<*mut Node<T>>,
 }
 
 impl<T> Node<T> {
@@ -88,12 +89,12 @@ impl<T: Send> Queue<T> {
         let stub = unsafe { Node::new(None) };
         Queue {
             head: AtomicPtr::new(stub),
-            tail: stub,
+            tail: Unsafe::new(stub),
         }
     }
 
     /// Pushes a new value onto this queue.
-    pub fn push(&mut self, t: T) {
+    pub fn push(&self, t: T) {
         unsafe {
             let n = Node::new(Some(t));
             let prev = self.head.swap(n, AcqRel);
@@ -111,13 +112,13 @@ impl<T: Send> Queue<T> {
     ///
     /// This inconsistent state means that this queue does indeed have data, but
     /// it does not currently have access to it at this time.
-    pub fn pop(&mut self) -> PopResult<T> {
+    pub fn pop(&self) -> PopResult<T> {
         unsafe {
-            let tail = self.tail;
+            let tail = *self.tail.get();
             let next = (*tail).next.load(Acquire);
 
             if !next.is_null() {
-                self.tail = next;
+                *self.tail.get() = next;
                 assert!((*tail).value.is_none());
                 assert!((*next).value.is_some());
                 let ret = (*next).value.take_unwrap();
@@ -131,7 +132,7 @@ impl<T: Send> Queue<T> {
 
     /// Attempts to pop data from this queue, but doesn't attempt too hard. This
     /// will canonicalize inconsistent states to a `None` value.
-    pub fn casual_pop(&mut self) -> Option<T> {
+    pub fn casual_pop(&self) -> Option<T> {
         match self.pop() {
             Data(t) => Some(t),
             Empty | Inconsistent => None,
@@ -143,7 +144,7 @@ impl<T: Send> Queue<T> {
 impl<T: Send> Drop for Queue<T> {
     fn drop(&mut self) {
         unsafe {
-            let mut cur = self.tail;
+            let mut cur = *self.tail.get();
             while !cur.is_null() {
                 let next = (*cur).next.load(Relaxed);
                 let _: Box<Node<T>> = mem::transmute(cur);
@@ -157,13 +158,14 @@ impl<T: Send> Drop for Queue<T> {
 mod tests {
     use prelude::*;
 
+    use alloc::arc::Arc;
+
     use native;
     use super::{Queue, Data, Empty, Inconsistent};
-    use sync::arc::UnsafeArc;
 
     #[test]
     fn test_full() {
-        let mut q = Queue::new();
+        let q = Queue::new();
         q.push(box 1);
         q.push(box 2);
     }
@@ -172,20 +174,20 @@ mod tests {
     fn test() {
         let nthreads = 8u;
         let nmsgs = 1000u;
-        let mut q = Queue::new();
+        let q = Queue::new();
         match q.pop() {
             Empty => {}
             Inconsistent | Data(..) => fail!()
         }
         let (tx, rx) = channel();
-        let q = UnsafeArc::new(q);
+        let q = Arc::new(q);
 
         for _ in range(0, nthreads) {
             let tx = tx.clone();
             let q = q.clone();
             native::task::spawn(proc() {
                 for i in range(0, nmsgs) {
-                    unsafe { (*q.get()).push(i); }
+                    q.push(i);
                 }
                 tx.send(());
             });
@@ -193,7 +195,7 @@ mod tests {
 
         let mut i = 0u;
         while i < nthreads * nmsgs {
-            match unsafe { (*q.get()).pop() } {
+            match q.pop() {
                 Empty | Inconsistent => {},
                 Data(_) => { i += 1 }
             }