47ef20014c
Beforehand, using a concurrent queue always mandated that the "shared state" be stored internally to the queues in order to provide a safe interface. This isn't quite as flexible as one would want in some circumstances, so instead this commit moves the queues to not containing the shared state. The queues no longer have a "default useful safe" interface, but rather a "default safe" interface (minus the useful part). The queues have to be shared manually through an Arc or some other means. This allows them to be a little more flexible at the cost of a usability hindrance. I plan on using this new flexibility to upgrade a channel to a shared channel seamlessly.
62 lines
1.6 KiB
Rust
62 lines
1.6 KiB
Rust
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
|
|
// file at the top-level directory of this distribution and at
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
// option. This file may not be copied, modified, or distributed
|
|
// except according to those terms.
|
|
|
|
use mpsc = std::sync::mpsc_queue;
|
|
use std::sync::arc::UnsafeArc;
|
|
|
|
pub enum PopResult<T> {
|
|
Inconsistent,
|
|
Empty,
|
|
Data(T),
|
|
}
|
|
|
|
pub fn queue<T: Send>() -> (Consumer<T>, Producer<T>) {
|
|
let (a, b) = UnsafeArc::new2(mpsc::Queue::new());
|
|
(Consumer { inner: a }, Producer { inner: b })
|
|
}
|
|
|
|
pub struct Producer<T> {
|
|
priv inner: UnsafeArc<mpsc::Queue<T>>,
|
|
}
|
|
|
|
pub struct Consumer<T> {
|
|
priv inner: UnsafeArc<mpsc::Queue<T>>,
|
|
}
|
|
|
|
impl<T: Send> Consumer<T> {
|
|
pub fn pop(&mut self) -> PopResult<T> {
|
|
match unsafe { (*self.inner.get()).pop() } {
|
|
mpsc::Inconsistent => Inconsistent,
|
|
mpsc::Empty => Empty,
|
|
mpsc::Data(t) => Data(t),
|
|
}
|
|
}
|
|
|
|
pub fn casual_pop(&mut self) -> Option<T> {
|
|
match unsafe { (*self.inner.get()).pop() } {
|
|
mpsc::Inconsistent => None,
|
|
mpsc::Empty => None,
|
|
mpsc::Data(t) => Some(t),
|
|
}
|
|
}
|
|
}
|
|
|
|
impl<T: Send> Producer<T> {
|
|
pub fn push(&mut self, t: T) {
|
|
unsafe { (*self.inner.get()).push(t); }
|
|
}
|
|
}
|
|
|
|
impl<T: Send> Clone for Producer<T> {
|
|
fn clone(&self) -> Producer<T> {
|
|
Producer { inner: self.inner.clone() }
|
|
}
|
|
}
|