forked from rust-lang/jobserver-rs
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* Optimize(linux): Use `/dev/fd/$fd` to switch to fifo when pipe is received Fifo uses a cloned file descriptor, which can set `O_NONBLOCK1 without affecing other users' of josberver. Signed-off-by: Jiahao XU <[email protected]> * Impl `TryacquireClient` Signed-off-by: Jiahao XU <[email protected]> * Impl `TryAcquireClient::into_inner` Signed-off-by: Jiahao XU <[email protected]> * Fix linux optimization in `unix::Client::from_pipe Signed-off-by: Jiahao XU <[email protected]> * Impl `try_acquire` for wasm and windows impl Signed-off-by: Jiahao XU <[email protected]> * Fix `Client::into_try_acquire_client` The `TryAcquireClient` returned, whether as `Ok` or `Err`, must have `O_NONBLOCK` set. Signed-off-by: Jiahao XU <[email protected]> * Fix linux optimization in `unix::Client::from_pipe` Signed-off-by: Jiahao XU <[email protected]> * Impl `AsyncAcquireClient` Signed-off-by: Jiahao XU <[email protected]> * Fix msrv on windows Signed-off-by: Jiahao XU <[email protected]> * Fix compilation on windows Signed-off-by: Jiahao XU <[email protected]> * Impl `AsyncAcquireClient::{acquire, acquire_owned}` And move `AsyncAcquireClient` into a separate module Signed-off-by: Jiahao XU <[email protected]> * Add CI checking for wasm32-wasi Signed-off-by: Jiahao XU <[email protected]> * Add missing `async_client.rs` Forgot to commit Signed-off-by: Jiahao XU <[email protected]> * Fix msrv-wasm Signed-off-by: Jiahao XU <[email protected]> * FIx msrv-wasm Signed-off-by: Jiahao XU <[email protected]> * Impl `AsyncAcquireClient` for wasm targets Signed-off-by: Jiahao XU <[email protected]> * Fix `wasm.rs` Signed-off-by: Jiahao XU <[email protected]> * Add tests Signed-off-by: Jiahao XU <[email protected]> * Fix `TryAcquireClient`: Set non-blocking on first instance of client And clear it on last instance of client. Signed-off-by: Jiahao XU <[email protected]> * Optimize `wasm` client impl Rm unused `Arc` Signed-off-by: Jiahao XU <[email protected]> * Optimize `unix::Client::acquire` Avoid call to `poll` unless `EAGAIN` is returned Signed-off-by: Jiahao XU <[email protected]> --------- Signed-off-by: Jiahao XU <[email protected]>
- Loading branch information
Showing
9 changed files
with
555 additions
and
99 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
use std::{ | ||
fmt, | ||
future::Future, | ||
io, ops, | ||
pin::Pin, | ||
task::{Context, Poll}, | ||
}; | ||
|
||
#[cfg(unix)] | ||
use tokio::io::{unix::AsyncFd, Interest}; | ||
|
||
use crate::{Acquired, TryAcquireClient}; | ||
|
||
#[cfg(unix)] | ||
type AsyncAcquireClientInner = AsyncFd<TryAcquireClient>; | ||
|
||
#[cfg(not(unix))] | ||
type AsyncAcquireClientInner = TryAcquireClient; | ||
|
||
/// Extension of [`Client`] that supports async acquire. | ||
#[derive(Debug)] | ||
pub struct AsyncAcquireClient(AsyncAcquireClientInner); | ||
|
||
impl ops::Deref for AsyncAcquireClient { | ||
type Target = TryAcquireClient; | ||
|
||
fn deref(&self) -> &Self::Target { | ||
#[cfg(unix)] | ||
return self.0.get_ref(); | ||
|
||
#[cfg(not(unix))] | ||
return &self.0; | ||
} | ||
} | ||
|
||
impl AsyncAcquireClient { | ||
/// Create async acquire client | ||
pub fn new(try_acquire_client: TryAcquireClient) -> io::Result<Self> { | ||
#[cfg(unix)] | ||
return AsyncFd::with_interest(try_acquire_client, Interest::READABLE).map(Self); | ||
|
||
#[cfg(not(unix))] | ||
return Ok(Self(try_acquire_client)); | ||
} | ||
|
||
/// Deregisters and returns [`TryAcquireClient`] | ||
pub fn into_inner(self) -> TryAcquireClient { | ||
#[cfg(unix)] | ||
return self.0.into_inner(); | ||
|
||
#[cfg(not(unix))] | ||
return self.0; | ||
} | ||
|
||
/// Async poll version of [`crate::Client::acquire`] | ||
pub fn poll_acquire(&self, cx: &mut Context<'_>) -> Poll<io::Result<Acquired>> { | ||
#[cfg(unix)] | ||
return loop { | ||
let mut ready_guard = match self.0.poll_read_ready(cx) { | ||
Poll::Pending => break Poll::Pending, | ||
Poll::Ready(res) => res?, | ||
}; | ||
|
||
if let Some(acquired) = self.try_acquire()? { | ||
break Poll::Ready(Ok(acquired)); | ||
} else { | ||
ready_guard.clear_ready(); | ||
} | ||
}; | ||
|
||
#[cfg(not(unix))] | ||
return self | ||
.0 | ||
.0 | ||
.0 | ||
.inner | ||
.poll_acquire(cx) | ||
.map_ok(|data| Acquired::new(&self.0, data)); | ||
} | ||
|
||
/// Async version of [`crate::Client::acquire`] | ||
pub fn acquire(&self) -> impl Future<Output = io::Result<Acquired>> + Send + Sync + Unpin + '_ { | ||
poll_fn(move |cx| self.poll_acquire(cx)) | ||
} | ||
|
||
/// Async owned version of [`crate::Client::acquire`] | ||
pub fn acquire_owned( | ||
self, | ||
) -> impl Future<Output = io::Result<Acquired>> + Send + Sync + Unpin + 'static { | ||
poll_fn(move |cx| self.poll_acquire(cx)) | ||
} | ||
} | ||
|
||
// Code below is copied from https://doc.rust-lang.org/nightly/src/core/future/poll_fn.rs.html#143-153 | ||
|
||
fn poll_fn<T, F>(f: F) -> PollFn<F> | ||
where | ||
F: FnMut(&mut Context<'_>) -> Poll<T>, | ||
{ | ||
PollFn { f } | ||
} | ||
|
||
#[must_use = "futures do nothing unless you `.await` or poll them"] | ||
struct PollFn<F> { | ||
f: F, | ||
} | ||
|
||
impl<F: Unpin> Unpin for PollFn<F> {} | ||
|
||
impl<F> fmt::Debug for PollFn<F> { | ||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
f.debug_struct("PollFn").finish() | ||
} | ||
} | ||
|
||
impl<T, F> Future for PollFn<F> | ||
where | ||
F: FnMut(&mut Context<'_>) -> Poll<T>, | ||
{ | ||
type Output = T; | ||
|
||
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<T> { | ||
// SAFETY: We are not moving out of the pinned field. | ||
(unsafe { &mut self.get_unchecked_mut().f })(cx) | ||
} | ||
} |
Oops, something went wrong.