Skip to content

Instantly share code, notes, and snippets.

@fantix
Last active August 29, 2015 14:02
Show Gist options
  • Save fantix/c00c0a26a57279b15fd7 to your computer and use it in GitHub Desktop.
Save fantix/c00c0a26a57279b15fd7 to your computer and use it in GitHub Desktop.
Select
use std::comm::{Select, Receiver};
use std::collections::HashMap;
trait Endpoint {
fn register(&self, selector: &Select) -> uint;
fn on_event(&self);
}
struct Sub {
chan: Receiver<int>,
}
impl Sub {
fn new(chan: Receiver<int>) -> Sub {
Sub {
chan: chan,
}
}
}
impl Endpoint for Sub {
fn register(&self, selector: &Select) -> uint {
let mut handle = selector.handle(&self.chan);
unsafe {
handle.add();
}
handle.id()
}
fn on_event(&self) {
println!("Result: {}", self.chan.recv());
}
}
struct Main {
selector: Select,
endpoints: HashMap<uint, Box<Endpoint>>,
}
impl Main {
fn new() -> Main {
Main {
selector: Select::new(),
endpoints: HashMap::new(),
}
}
fn run(&self) {
let hid = self.selector.wait();
self.endpoints.get(&hid).on_event();
}
fn add(&mut self, sub: Box<Endpoint>) {
let hid = sub.register(&self.selector);
self.endpoints.insert(hid, sub);
}
}
fn main() {
let (tx, rx) = channel();
let s = box Sub::new(rx);
let mut m = Main::new();
m.add(s);
tx.send(1);
m.run();
}
```
$ ./before_storing_handle
task '<main>' failed at 'assertion failed: amt > 0', /build/rust-git/src/rust/src/libsync/comm/select.rs:168
```
Guess: `Handle` is freed when out of scope, so `selector.wait()` simply fails due to no handle.
So I tries to store `Handle` in `Sub`.
use std::comm::{Select, Receiver, Handle};
use std::collections::HashMap;
trait Endpoint<'a> {
fn register(&'a mut self, selector: &'a Select) -> uint;
fn on_event(&self);
fn get_chan(&'a self) -> &'a Receiver<int>;
}
struct Sub<'a> {
chan: Receiver<int>,
handle: Option<Handle<'a, int>>,
}
impl<'a> Sub<'a> {
fn new(chan: Receiver<int>) -> Sub {
Sub {
chan: chan,
handle: None,
}
}
}
impl<'a> Endpoint<'a> for Sub<'a> {
fn register(&'a mut self, selector: &'a Select) -> uint {
let handle = selector.handle(&self.chan);
self.handle = Some(handle);
let handle = self.handle.get_mut_ref();
unsafe {
handle.add();
}
handle.id()
}
fn on_event(&self) {
println!("Result: {}", self.chan.recv());
}
fn get_chan(&'a self) -> &'a Receiver<int> {
&self.chan
}
}
struct Main<'a> {
selector: Select,
bucket: Vec<Box<Endpoint<'a>>>,
endpoints: HashMap<uint, uint>,
}
impl<'a> Main<'a> {
fn new() -> Main {
Main {
selector: Select::new(),
bucket: Vec::new(),
endpoints: HashMap::new(),
}
}
fn run(&mut self) {
let hid = self.selector.wait();
self.bucket.get_mut(*self.endpoints.get(&hid)).on_event();
}
fn add(&'a mut self, sub: Box<Endpoint<'a>>) {
let index = self.bucket.len();
self.bucket.push(sub);
let sub = self.bucket.get_mut(index);
let hid = sub.register(&self.selector);
self.endpoints.insert(hid, index);
}
}
fn main() {
let (tx, rx) = channel();
let s = box Sub::new(rx);
let mut m = Main::new();
m.add(s);
tx.send(1);
m.run();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment