| 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); |
| } |