diff options
| author | bors <bors@rust-lang.org> | 2013-08-24 16:46:24 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-08-24 16:46:24 -0700 |
| commit | 8c25b7f0e8c01d3946e7e7e6912e225b30b60f89 (patch) | |
| tree | a7c03648b5fc6184a9b6870fb3dbf2152673ab07 /src/libstd/rt/message_queue.rs | |
| parent | e311a1ee02af4309394f0b3195c4b6abfcf770a2 (diff) | |
| parent | bbe347cee79df9cb68ee490ba957e515e3da70a1 (diff) | |
| download | rust-8c25b7f0e8c01d3946e7e7e6912e225b30b60f89.tar.gz rust-8c25b7f0e8c01d3946e7e7e6912e225b30b60f89.zip | |
auto merge of #8740 : brson/rust/rt-opt, r=thestinger
See #8599
Diffstat (limited to 'src/libstd/rt/message_queue.rs')
| -rw-r--r-- | src/libstd/rt/message_queue.rs | 53 |
1 files changed, 43 insertions, 10 deletions
diff --git a/src/libstd/rt/message_queue.rs b/src/libstd/rt/message_queue.rs index 8518ddaeae1..2bbcaff6d28 100644 --- a/src/libstd/rt/message_queue.rs +++ b/src/libstd/rt/message_queue.rs @@ -16,33 +16,66 @@ use kinds::Send; use vec::OwnedVector; use cell::Cell; use option::*; -use unstable::sync::Exclusive; +use unstable::sync::{UnsafeAtomicRcBox, LittleLock}; use clone::Clone; pub struct MessageQueue<T> { - // XXX: Another mystery bug fixed by boxing this lock - priv queue: ~Exclusive<~[T]> + priv state: UnsafeAtomicRcBox<State<T>> +} + +struct State<T> { + count: uint, + queue: ~[T], + lock: LittleLock } impl<T: Send> MessageQueue<T> { pub fn new() -> MessageQueue<T> { MessageQueue { - queue: ~Exclusive::new(~[]) + state: UnsafeAtomicRcBox::new(State { + count: 0, + queue: ~[], + lock: LittleLock::new() + }) } } pub fn push(&mut self, value: T) { unsafe { let value = Cell::new(value); - self.queue.with(|q| q.push(value.take()) ); + let state = self.state.get(); + do (*state).lock.lock { + (*state).count += 1; + (*state).queue.push(value.take()); + } } } pub fn pop(&mut self) -> Option<T> { unsafe { - do self.queue.with |q| { - if !q.is_empty() { - Some(q.shift()) + let state = self.state.get(); + do (*state).lock.lock { + if !(*state).queue.is_empty() { + (*state).count += 1; + Some((*state).queue.shift()) + } else { + None + } + } + } + } + + /// A pop that may sometimes miss enqueued elements, but is much faster + /// to give up without doing any synchronization + pub fn casual_pop(&mut self) -> Option<T> { + unsafe { + let state = self.state.get(); + // NB: Unsynchronized check + if (*state).count == 0 { return None; } + do (*state).lock.lock { + if !(*state).queue.is_empty() { + (*state).count += 1; + Some((*state).queue.shift()) } else { None } @@ -51,10 +84,10 @@ impl<T: Send> MessageQueue<T> { } } -impl<T> Clone for MessageQueue<T> { +impl<T: Send> Clone for MessageQueue<T> { fn clone(&self) -> MessageQueue<T> { MessageQueue { - queue: self.queue.clone() + state: self.state.clone() } } } |
