Skip to content

Commit 15b93a7

Browse files
authored
Merge pull request #13 from bjorn3/misc_arch_support
Add support for non-unix and non-windows platforms
2 parents 0cc0028 + 98b7c55 commit 15b93a7

File tree

1 file changed

+93
-0
lines changed

1 file changed

+93
-0
lines changed

src/lib.rs

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,8 @@ impl Client {
254254
/// On Unix and Windows this will clobber the `CARGO_MAKEFLAGS` environment
255255
/// variables for the child process, and on Unix this will also allow the
256256
/// two file descriptors for this client to be inherited to the child.
257+
///
258+
/// On platforms other than Unix and Windows this panics.
257259
pub fn configure(&self, cmd: &mut Command) {
258260
let arg = self.inner.string_arg();
259261
// Older implementations of make use `--jobserver-fds` and newer
@@ -961,3 +963,94 @@ mod imp {
961963
}
962964
}
963965
}
966+
967+
#[cfg(not(any(unix, windows)))]
968+
mod imp {
969+
use std::io;
970+
use std::sync::Mutex;
971+
use std::sync::mpsc::{self, SyncSender, Receiver};
972+
use std::thread::{Builder, JoinHandle};
973+
use std::process::Command;
974+
975+
#[derive(Debug)]
976+
pub struct Client {
977+
tx: SyncSender<()>,
978+
rx: Mutex<Receiver<()>>,
979+
}
980+
981+
#[derive(Debug)]
982+
pub struct Acquired(());
983+
984+
impl Client {
985+
pub fn new(limit: usize) -> io::Result<Client> {
986+
let (tx, rx) = mpsc::sync_channel(limit);
987+
for _ in 0..limit {
988+
tx.send(()).unwrap();
989+
}
990+
Ok(Client {
991+
tx,
992+
rx: Mutex::new(rx),
993+
})
994+
}
995+
996+
pub unsafe fn open(_s: &str) -> Option<Client> {
997+
None
998+
}
999+
1000+
pub fn acquire(&self) -> io::Result<Acquired> {
1001+
self.rx.lock().unwrap().recv().unwrap();
1002+
Ok(Acquired(()))
1003+
}
1004+
1005+
pub fn release(&self, _data: Option<&Acquired>) -> io::Result<()> {
1006+
self.tx.send(()).unwrap();
1007+
Ok(())
1008+
}
1009+
1010+
pub fn string_arg(&self) -> String {
1011+
panic!(
1012+
"On this platform there is no cross process jobserver support,
1013+
so Client::configure is not supported."
1014+
);
1015+
}
1016+
1017+
pub fn configure(&self, _cmd: &mut Command) {
1018+
unreachable!();
1019+
}
1020+
}
1021+
1022+
#[derive(Debug)]
1023+
pub struct Helper {
1024+
thread: JoinHandle<()>,
1025+
}
1026+
1027+
pub fn spawn_helper(client: ::Client,
1028+
rx: Receiver<()>,
1029+
mut f: Box<FnMut(io::Result<::Acquired>) + Send>)
1030+
-> io::Result<Helper>
1031+
{
1032+
let thread = Builder::new().spawn(move || {
1033+
for () in rx {
1034+
let res = client.acquire();
1035+
f(res);
1036+
}
1037+
})?;
1038+
1039+
Ok(Helper {
1040+
thread: thread,
1041+
})
1042+
}
1043+
1044+
impl Helper {
1045+
pub fn join(self) {
1046+
drop(self.thread.join());
1047+
}
1048+
}
1049+
}
1050+
1051+
#[test]
1052+
fn no_helper_deadlock() {
1053+
let x = crate::Client::new(32).unwrap();
1054+
let _y = x.clone();
1055+
std::mem::drop(x.into_helper_thread(|_| {}).unwrap());
1056+
}

0 commit comments

Comments
 (0)