From 69cd8b5fcb559ff3342258273f2cc81023f699ba Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Mon, 9 Jul 2012 13:53:55 -0700 Subject: [PATCH] Added select2 for pipes. --- src/libcore/pipes.rs | 27 ++++++++++++++++++++++++++- src/test/run-pass/pipe-select.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 57 insertions(+), 2 deletions(-) diff --git a/src/libcore/pipes.rs b/src/libcore/pipes.rs index f1617c59ac7d..1d6d70defb95 100644 --- a/src/libcore/pipes.rs +++ b/src/libcore/pipes.rs @@ -1,6 +1,7 @@ // Runtime support for pipes. -import unsafe::{forget, reinterpret_cast}; +import unsafe::{forget, reinterpret_cast, transmute}; +import either::{either, left, right}; enum state { empty, @@ -243,6 +244,30 @@ fn wait_many(pkts: ~[&a.packet_header]) -> uint { ready_packet } +fn select2( + +a: recv_packet, + +b: recv_packet) + -> either<(option, recv_packet), (recv_packet, option)> +{ + let a = unsafe { uniquify(a.unwrap()) }; + let b = unsafe { uniquify(b.unwrap()) }; + let i = { + let headers = ~[&a.header, + &b.header]; + wait_many(headers) + }; + + unsafe { + alt i { + 0 { left((recv(recv_packet(transmute(a))), + recv_packet(transmute(b)))) } + 1 { right((recv_packet(transmute(a)), + recv(recv_packet(transmute(b))))) } + _ { fail "select2 return an invalid packet" } + } + } +} + #[doc = "Waits on a set of endpoints. Returns a message, its index, and a list of the remaining endpoints."] fn select(+endpoints: ~[recv_packet]) diff --git a/src/test/run-pass/pipe-select.rs b/src/test/run-pass/pipe-select.rs index af01e568ffd4..09066eebd37e 100644 --- a/src/test/run-pass/pipe-select.rs +++ b/src/test/run-pass/pipe-select.rs @@ -72,4 +72,34 @@ fn main() { sleep(iotask, 1000); signal(c2); -} \ No newline at end of file + + test_select2(); +} + +fn test_select2() { + let (ac, ap) = stream::init(); + let (bc, bp) = stream::init(); + + stream::client::send(ac, 42); + + alt pipes::select2(ap, bp) { + either::left(*) { } + either::right(*) { fail } + } + + stream::client::send(bc, "abc"); + + #error("done with first select2"); + + let (ac, ap) = stream::init(); + let (bc, bp) = stream::init(); + + stream::client::send(bc, "abc"); + + alt pipes::select2(ap, bp) { + either::left(*) { fail } + either::right(*) { } + } + + stream::client::send(ac, 42); +}