Skip to content

Commit

Permalink
Impl Client::try_acquire
Browse files Browse the repository at this point in the history
With suggestions from @weihanglo

Co-authored-by: Weihang Lo <weihanglo@users.noreply.github.com>

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
  • Loading branch information
NobodyXu committed Apr 7, 2024
1 parent 89432f4 commit 81195a4
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 59 deletions.
1 change: 0 additions & 1 deletion .github/actions/compile-make/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ runs:
path: /usr/local/bin/make-${{ inputs.version }}
key: v1-${{ runner.os }}-make-${{ inputs.version }}

# Compile it from source (temporarily)
- name: Make GNU Make from source
if: ${{ !startsWith(runner.os, 'windows') && steps.cache-make.outputs.cache-hit != 'true' }}
env:
Expand Down
1 change: 0 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
target/
**/*.rs.bk
Cargo.lock
23 changes: 21 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

5 changes: 4 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ edition = "2021"
rust-version = "1.63"

[target.'cfg(unix)'.dependencies]
libc = "0.2.72"
libc = "0.2.87"

[target.'cfg(unix)'.dev-dependencies]
nix = { version = "0.28.0", features = ["fs"] }

[dev-dependencies]
tempfile = "3.10.1"
Expand Down
142 changes: 96 additions & 46 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,6 +324,32 @@ impl Client {
})
}

/// Acquires a token from this jobserver client in a non-blocking way.
///
/// # Return value
///
/// On successful acquisition of a token an instance of [`Acquired`] is
/// returned. This structure, when dropped, will release the token back to
/// the jobserver. It's recommended to avoid leaking this value.
///
/// # Errors
///
/// If an I/O error happens while acquiring a token then this function will
/// return immediately with the error. If an error is returned then a token
/// was not acquired.
///
/// If non-blocking acquire is not supported, the return error will have its `kind()`
/// set to [`io::ErrorKind::Unsupported`].
pub fn try_acquire(&self) -> io::Result<Option<Acquired>> {
let ret = self.inner.try_acquire()?;

Ok(ret.map(|data| Acquired {
client: self.inner.clone(),
data,
disabled: false,
}))
}

/// Returns amount of tokens in the read-side pipe.
///
/// # Return value
Expand Down Expand Up @@ -607,52 +633,76 @@ fn find_jobserver_auth(var: &str) -> Option<&str> {
.and_then(|s| s.split(' ').next())
}

#[test]
fn no_helper_deadlock() {
let x = crate::Client::new(32).unwrap();
let _y = x.clone();
std::mem::drop(x.into_helper_thread(|_| {}).unwrap());
}
#[cfg(test)]
mod test {
use super::*;

pub(super) fn run_named_fifo_try_acquire_tests(client: &Client) {
assert!(client.try_acquire().unwrap().is_none());
client.release_raw().unwrap();

#[test]
fn test_find_jobserver_auth() {
let cases = [
("", None),
("-j2", None),
("-j2 --jobserver-auth=3,4", Some("3,4")),
("--jobserver-auth=3,4 -j2", Some("3,4")),
("--jobserver-auth=3,4", Some("3,4")),
("--jobserver-auth=fifo:/myfifo", Some("fifo:/myfifo")),
("--jobserver-auth=", Some("")),
("--jobserver-auth", None),
("--jobserver-fds=3,4", Some("3,4")),
("--jobserver-fds=fifo:/myfifo", Some("fifo:/myfifo")),
("--jobserver-fds=", Some("")),
("--jobserver-fds", None),
(
"--jobserver-auth=auth-a --jobserver-auth=auth-b",
Some("auth-b"),
),
(
"--jobserver-auth=auth-b --jobserver-auth=auth-a",
Some("auth-a"),
),
("--jobserver-fds=fds-a --jobserver-fds=fds-b", Some("fds-b")),
("--jobserver-fds=fds-b --jobserver-fds=fds-a", Some("fds-a")),
(
"--jobserver-auth=auth-a --jobserver-fds=fds-a --jobserver-auth=auth-b",
Some("auth-b"),
),
(
"--jobserver-fds=fds-a --jobserver-auth=auth-a --jobserver-fds=fds-b",
Some("auth-a"),
),
];
for (var, expected) in cases {
let actual = find_jobserver_auth(var);
assert_eq!(
actual, expected,
"expect {expected:?}, got {actual:?}, input `{var:?}`"
);
let acquired = client.try_acquire().unwrap().unwrap();
assert!(client.try_acquire().unwrap().is_none());

drop(acquired);
client.try_acquire().unwrap().unwrap();
}

#[cfg(not(unix))]
#[test]
fn test_try_acquire() {
let client = Client::new(0).unwrap();

run_named_fifo_try_acquire_tests(&client);
}

#[test]
fn no_helper_deadlock() {
let x = crate::Client::new(32).unwrap();
let _y = x.clone();
std::mem::drop(x.into_helper_thread(|_| {}).unwrap());
}

#[test]
fn test_find_jobserver_auth() {
let cases = [
("", None),
("-j2", None),
("-j2 --jobserver-auth=3,4", Some("3,4")),
("--jobserver-auth=3,4 -j2", Some("3,4")),
("--jobserver-auth=3,4", Some("3,4")),
("--jobserver-auth=fifo:/myfifo", Some("fifo:/myfifo")),
("--jobserver-auth=", Some("")),
("--jobserver-auth", None),
("--jobserver-fds=3,4", Some("3,4")),
("--jobserver-fds=fifo:/myfifo", Some("fifo:/myfifo")),
("--jobserver-fds=", Some("")),
("--jobserver-fds", None),
(
"--jobserver-auth=auth-a --jobserver-auth=auth-b",
Some("auth-b"),
),
(
"--jobserver-auth=auth-b --jobserver-auth=auth-a",
Some("auth-a"),
),
("--jobserver-fds=fds-a --jobserver-fds=fds-b", Some("fds-b")),
("--jobserver-fds=fds-b --jobserver-fds=fds-a", Some("fds-a")),
(
"--jobserver-auth=auth-a --jobserver-fds=fds-a --jobserver-auth=auth-b",
Some("auth-b"),
),
(
"--jobserver-fds=fds-a --jobserver-auth=auth-a --jobserver-fds=fds-b",
Some("auth-a"),
),
];
for (var, expected) in cases {
let actual = find_jobserver_auth(var);
assert_eq!(
actual, expected,
"expect {expected:?}, got {actual:?}, input `{var:?}`"
);
}
}
}
Loading

0 comments on commit 81195a4

Please sign in to comment.