|
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