Skip to content

Instantly share code, notes, and snippets.

@anka-213
Forked from anonymous/playground.rs
Last active May 12, 2016 22:37
Show Gist options
  • Save anka-213/764d704ee53d7ac12f23f245d16c8d1a to your computer and use it in GitHub Desktop.
Save anka-213/764d704ee53d7ac12f23f245d16c8d1a to your computer and use it in GitHub Desktop.
Shared via Rust Playground
// #![allow(dead_code)]
// #![allow(unused_variables)]
// #![allow(unused_mut)]
#![feature(question_mark)]
use std::sync::Mutex;
use std::sync::Arc;
use std::collections::VecDeque;
use std::thread;
use std::ops::Deref;
use std::time::Duration;
#[derive(Clone)]
#[derive(Debug)]
enum Message {A(i32), B(String)}
#[derive(Default)]
struct MBox (Mutex<VecDeque<Message>>);
impl Deref for MBox {
type Target = Mutex<VecDeque<Message>>;
fn deref(&self) -> &Self::Target {&self.0}
}
impl MBox {
fn send(&self, msg : Message) {
self.lock().unwrap().push_back(msg);
}
fn try_recv(&self) -> Option<Message> {
self.lock().unwrap().pop_front()
}
fn recv(&self) -> Message {
loop {
if let Some(x) = self.try_recv() {
return x;
}
thread::park();
}
}
}
/*
impl Default for MBox {
fn default() -> MBox {
MBox(Mutex::new(Default::default()))
}
}
*/
thread_local!(static MBOX : MBox = Default::default());
struct MBoxThread<T> {
mbox : Arc<MBox>,
join_handle : thread::JoinHandle<T>
}
impl<T> Deref for MBoxThread<T> {
type Target = thread::JoinHandle<T>;
fn deref(&self) -> &Self::Target {&self.join_handle}
}
impl<T> MBoxThread<T> {
fn spawn<F> (f : F) -> MBoxThread<T> where
F: FnOnce(Arc<MBox>) -> T, F: Send + 'static, T: Send + 'static {
let mbox : Arc<MBox> = Default::default();
let mb2 = mbox.clone();
let join_handle = thread::spawn(move || f(mb2));
MBoxThread { mbox: mbox, join_handle: join_handle }
}
fn send(&self, msg : Message) {
self.mbox.send(msg);
self.thread().unpark();
}
fn join(self) -> thread::Result<T> {self.join_handle.join()}
}
fn main() {
MBOX.with(|mbox| {
mbox.send(Message::A(2));
println!("Hello");
});
MBOX.with(|mbox| {
let msg = mbox.try_recv();
println!("Hello {:?}", msg);
});
let mbox2 : Arc<MBox> = Default::default();
let mb2 = mbox2.clone();
let x = thread::spawn( move || {
// thread::current().unpark();
// thread::sleep(Duration::from_millis(20));
let msg = mb2.recv();
println!("Hello2 {:?}", msg);
msg
});
//x.thread().unpark();
//x.thread().unpark();
{let t = x.thread().clone();
thread::spawn(move || {
thread::sleep(Duration::from_millis(500));
mbox2.send(Message::B("Hello".to_string()));
println!("Hello2");
t.unpark();
});}
let result = x.join();
println!("Result: {:?}", result);
let y = MBoxThread::spawn(|mbox| mbox.recv());
y.send(Message::A(1));
let z = y.join().unwrap();
println!("Final: {:?}", z);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment