|
11 | 11 | //! A concurrent queue that supports multiple producers and a
|
12 | 12 | //! single consumer.
|
13 | 13 |
|
14 |
| -use container::Container; |
15 | 14 | use kinds::Send;
|
16 | 15 | use vec::OwnedVector;
|
17 |
| -use cell::Cell; |
18 |
| -use option::*; |
19 |
| -use unstable::sync::{UnsafeArc, LittleLock}; |
| 16 | +use option::Option; |
20 | 17 | use clone::Clone;
|
| 18 | +use rt::mpsc_queue::Queue; |
21 | 19 |
|
22 | 20 | pub struct MessageQueue<T> {
|
23 |
| - priv state: UnsafeArc<State<T>> |
24 |
| -} |
25 |
| - |
26 |
| -struct State<T> { |
27 |
| - count: uint, |
28 |
| - queue: ~[T], |
29 |
| - lock: LittleLock |
| 21 | + priv queue: Queue<T> |
30 | 22 | }
|
31 | 23 |
|
32 | 24 | impl<T: Send> MessageQueue<T> {
|
33 | 25 | pub fn new() -> MessageQueue<T> {
|
34 | 26 | MessageQueue {
|
35 |
| - state: UnsafeArc::new(State { |
36 |
| - count: 0, |
37 |
| - queue: ~[], |
38 |
| - lock: LittleLock::new() |
39 |
| - }) |
| 27 | + queue: Queue::new() |
40 | 28 | }
|
41 | 29 | }
|
42 | 30 |
|
| 31 | + #[inline] |
43 | 32 | pub fn push(&mut self, value: T) {
|
44 |
| - unsafe { |
45 |
| - let value = Cell::new(value); |
46 |
| - let state = self.state.get(); |
47 |
| - do (*state).lock.lock { |
48 |
| - (*state).count += 1; |
49 |
| - (*state).queue.push(value.take()); |
50 |
| - } |
51 |
| - } |
| 33 | + self.queue.push(value) |
52 | 34 | }
|
53 | 35 |
|
| 36 | + #[inline] |
54 | 37 | pub fn pop(&mut self) -> Option<T> {
|
55 |
| - unsafe { |
56 |
| - let state = self.state.get(); |
57 |
| - do (*state).lock.lock { |
58 |
| - if !(*state).queue.is_empty() { |
59 |
| - (*state).count += 1; |
60 |
| - Some((*state).queue.shift()) |
61 |
| - } else { |
62 |
| - None |
63 |
| - } |
64 |
| - } |
65 |
| - } |
| 38 | + self.queue.pop() |
66 | 39 | }
|
67 | 40 |
|
68 | 41 | /// A pop that may sometimes miss enqueued elements, but is much faster
|
69 | 42 | /// to give up without doing any synchronization
|
| 43 | + #[inline] |
70 | 44 | pub fn casual_pop(&mut self) -> Option<T> {
|
71 |
| - unsafe { |
72 |
| - let state = self.state.get(); |
73 |
| - // NB: Unsynchronized check |
74 |
| - if (*state).count == 0 { return None; } |
75 |
| - do (*state).lock.lock { |
76 |
| - if !(*state).queue.is_empty() { |
77 |
| - (*state).count += 1; |
78 |
| - Some((*state).queue.shift()) |
79 |
| - } else { |
80 |
| - None |
81 |
| - } |
82 |
| - } |
83 |
| - } |
| 45 | + self.queue.pop() |
84 | 46 | }
|
85 | 47 | }
|
86 | 48 |
|
87 | 49 | impl<T: Send> Clone for MessageQueue<T> {
|
88 | 50 | fn clone(&self) -> MessageQueue<T> {
|
89 | 51 | MessageQueue {
|
90 |
| - state: self.state.clone() |
| 52 | + queue: self.queue.clone() |
91 | 53 | }
|
92 | 54 | }
|
93 | 55 | }
|
0 commit comments