use std::env; | |
use std::io::prelude::*; | |
use std::io::BufReader; | |
use std::process::{Command, Stdio}; | |
use std::sync::mpsc; | |
use std::thread; | |
use jobserver::Client; | |
macro_rules! t { | |
($e:expr) => { | |
match $e { | |
Ok(e) => e, | |
Err(e) => panic!("{} failed with {}", stringify!($e), e), | |
} | |
}; | |
} | |
fn main() { | |
if env::var("I_AM_THE_CLIENT").is_ok() { | |
client(); | |
} else { | |
server(); | |
} | |
} | |
fn server() { | |
let me = t!(env::current_exe()); | |
let client = t!(Client::new(1)); | |
let mut cmd = Command::new(me); | |
cmd.env("I_AM_THE_CLIENT", "1").stdout(Stdio::piped()); | |
client.configure(&mut cmd); | |
let acq = client.acquire().unwrap(); | |
let mut child = t!(cmd.spawn()); | |
let stdout = child.stdout.take().unwrap(); | |
let (tx, rx) = mpsc::channel(); | |
let t = thread::spawn(move || { | |
for line in BufReader::new(stdout).lines() { | |
tx.send(t!(line)).unwrap(); | |
} | |
}); | |
for _ in 0..100 { | |
assert!(rx.try_recv().is_err()); | |
} | |
drop(acq); | |
assert_eq!(rx.recv().unwrap(), "hello!"); | |
t.join().unwrap(); | |
assert!(rx.recv().is_err()); | |
client.acquire().unwrap(); | |
} | |
fn client() { | |
let client = unsafe { Client::from_env().unwrap() }; | |
let acq = client.acquire().unwrap(); | |
println!("hello!"); | |
drop(acq); | |
} |