Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for non-unix and non-windows platforms #13

Merged
merged 7 commits into from
May 17, 2019
Merged
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 86 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ impl Client {
/// On Unix and Windows this will clobber the `CARGO_MAKEFLAGS` environment
/// variables for the child process, and on Unix this will also allow the
/// two file descriptors for this client to be inherited to the child.
///
/// On platforms other than Unix and Windows this panics.
pub fn configure(&self, cmd: &mut Command) {
let arg = self.inner.string_arg();
// Older implementations of make use `--jobserver-fds` and newer
Expand Down Expand Up @@ -961,3 +963,87 @@ mod imp {
}
}
}

#[cfg(not(any(unix, windows)))]
mod imp {
use std::io;
use std::sync::Mutex;
use std::sync::mpsc::{self, SyncSender, Receiver};
use std::thread::{Builder, JoinHandle};
use std::process::Command;

#[derive(Debug)]
pub struct Client {
tx: SyncSender<()>,
rx: Mutex<Receiver<()>>,
}

#[derive(Debug)]
pub struct Acquired(());

impl Client {
pub fn new(limit: usize) -> io::Result<Client> {
let (tx, rx) = mpsc::sync_channel(limit);
for _ in 0..limit {
tx.send(()).unwrap();
}
Ok(Client {
tx,
rx: Mutex::new(rx),
})
}

pub unsafe fn open(_s: &str) -> Option<Client> {
None
}

pub fn acquire(&self) -> io::Result<Acquired> {
self.rx.lock().unwrap().recv().unwrap();
Ok(Acquired(()))
}

pub fn release(&self, _data: Option<&Acquired>) -> io::Result<()> {
self.tx.send(()).unwrap();
Ok(())
}

pub fn string_arg(&self) -> String {
panic!(
"On this platform there is no cross process jobserver support,
so Client::configure is not supported."
);
}

pub fn configure(&self, _cmd: &mut Command) {
unreachable!();
}
}

#[derive(Debug)]
pub struct Helper {
thread: JoinHandle<()>,
}

pub fn spawn_helper(client: ::Client,
rx: Receiver<()>,
mut f: Box<FnMut(io::Result<::Acquired>) + Send>)
-> io::Result<Helper>
{
let thread = Builder::new().spawn(move || {
for () in rx {
let res = client.acquire();
f(res);
}
})?;

Ok(Helper {
thread: thread,
})
}

impl Helper {
pub fn join(self) {
drop(self.thread.join());
}
}
}