Skip to content

Instantly share code, notes, and snippets.

@ongardie
Created November 16, 2013 00:55
Show Gist options
  • Save ongardie/7494388 to your computer and use it in GitHub Desktop.
Save ongardie/7494388 to your computer and use it in GitHub Desktop.
Workaround for Rust select() once priv is removed from std::comm::Port See https://mail.mozilla.org/pipermail/rust-dev/2013-November/006665.html
#[feature(macro_rules)];
extern mod std;
/* SelectBox is a wrapper to allow calling select() on pointers */
struct SelectBox<'self> {
inner: &'self mut std::select::Select,
}
impl<'self> std::rt::shouldnt_be_public::SelectInner for SelectBox<'self> {
fn optimistic_check(&mut self) -> bool {
self.inner.optimistic_check()
}
fn block_on(&mut self, sched: &mut std::rt::sched::Scheduler, task: std::rt::BlockedTask) -> bool {
self.inner.block_on(sched, task)
}
fn unblock_from(&mut self) -> bool {
self.inner.unblock_from()
}
}
impl<'self> std::select::Select for SelectBox<'self> {
}
/* recursive helper for selectmatch macro */
macro_rules! selectmatch_rec(
($index:expr,
$port:expr => $action:expr,
$( $port_rest:expr => $action_rest:expr ),+) => (
if $index == 0 {
$action
} else {
$index -= 1;
selectmatch_rec!($index, $( $port_rest => $action_rest ),*)
}
);
($index:expr, $port:expr => $action:expr) => (
if $index == 0 {
$action
} else {
fail!("Bogus return value from select()");
}
);
)
/* bearable syntax for calling select with SelectBox */
macro_rules! selectmatch(
($( $port:expr => $action:expr ),+) => (
do 1.times {
let mut selectmatch_i : uint = std::select::select([$( SelectBox{ inner: &mut $port as &mut std::select::Select } ),+]);
selectmatch_rec!(selectmatch_i, $( $port => $action ),+)
}
);
)
fn main() {
let mut signals = std::io::signal::Listener::new();
signals.register(std::io::signal::Interrupt);
let (mut port, chan): (std::comm::Port<uint>, std::comm::Chan<uint>) = stream();
let chan = std::comm::SharedChan::new(chan);
let child_chan = chan.clone();
do spawn {
let mut timer = std::io::Timer::new().unwrap();
timer.sleep(1000);
child_chan.send(1337);
}
selectmatch!(
signals.port.x => {
match signals.port.recv() {
std::io::signal::Interrupt => {
println!("Ctrl-C");
},
_ => fail!("Unexpected signal"),
}
},
port.x => {
println!("Child says: {}", port.recv());
}
);
/* or more verbosely: */
match std::select::select([SelectBox{inner: &mut signals.port.x as &mut std::select::Select},
SelectBox{inner: &mut port.x as &mut std::select::Select}]) {
0 => println!("..."),
1 => println!("..."),
_ => println!("..."),
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment