Skip to content

Commit ece38b3

Browse files
committed
core::rt: Add MegaPipe, an unbounded, multiple producer/consumer, lock-free queue
1 parent 51d257f commit ece38b3

File tree

1 file changed

+71
-0
lines changed

1 file changed

+71
-0
lines changed

src/libstd/rt/comm.rs

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,44 @@ impl<T> Clone for SharedPort<T> {
471471
}
472472
}
473473

474+
// XXX: Need better name
475+
type MegaPipe<T> = (SharedPort<T>, SharedChan<T>);
476+
477+
pub fn megapipe<T: Owned>() -> MegaPipe<T> {
478+
let (port, chan) = stream();
479+
(SharedPort::new(port), SharedChan::new(chan))
480+
}
481+
482+
impl<T: Owned> GenericChan<T> for MegaPipe<T> {
483+
fn send(&self, val: T) {
484+
match *self {
485+
(_, ref c) => c.send(val)
486+
}
487+
}
488+
}
489+
490+
impl<T: Owned> GenericSmartChan<T> for MegaPipe<T> {
491+
fn try_send(&self, val: T) -> bool {
492+
match *self {
493+
(_, ref c) => c.try_send(val)
494+
}
495+
}
496+
}
497+
498+
impl<T: Owned> GenericPort<T> for MegaPipe<T> {
499+
fn recv(&self) -> T {
500+
match *self {
501+
(ref p, _) => p.recv()
502+
}
503+
}
504+
505+
fn try_recv(&self) -> Option<T> {
506+
match *self {
507+
(ref p, _) => p.try_recv()
508+
}
509+
}
510+
}
511+
474512
#[cfg(test)]
475513
mod test {
476514
use super::*;
@@ -834,5 +872,38 @@ mod test {
834872
assert!(recvd == send_total);
835873
}
836874
}
875+
876+
#[test]
877+
fn megapipe_stress() {
878+
use rand;
879+
use rand::RngUtil;
880+
881+
do run_in_mt_newsched_task {
882+
let (end_port, end_chan) = stream::<()>();
883+
let end_chan = SharedChan::new(end_chan);
884+
let pipe = megapipe();
885+
let total = stress_factor() + 10;
886+
let mut rng = rand::rng();
887+
for total.times {
888+
let msgs = rng.gen_uint_range(0, 10);
889+
let pipe_clone = pipe.clone();
890+
let end_chan_clone = end_chan.clone();
891+
do spawntask_random {
892+
for msgs.times {
893+
pipe_clone.send(());
894+
}
895+
for msgs.times {
896+
pipe_clone.recv();
897+
}
898+
}
899+
900+
end_chan_clone.send(());
901+
}
902+
903+
for total.times {
904+
end_port.recv();
905+
}
906+
}
907+
}
837908
}
838909

0 commit comments

Comments
 (0)