rustc_data_structures::jobserver

Struct Client

source
pub struct Client {
    pub(crate) inner: Arc<Client>,
}
Expand description

A client of a jobserver

This structure is the main type exposed by this library, and is where interaction to a jobserver is configured through. Clients are either created from scratch in which case the internal semphore is initialied on the spot, or a client is created from the environment to connect to a jobserver already created.

Some usage examples can be found in the crate documentation for using a client.

Note that a Client implements the Clone trait, and all instances of a Client refer to the same jobserver instance.

Fields§

§inner: Arc<Client>

Implementations§

source§

impl Client

source

pub fn new(limit: usize) -> Result<Client, Error>

Creates a new jobserver initialized with the given parallelism limit.

A client to the jobserver created will be returned. This client will allow at most limit tokens to be acquired from it in parallel. More calls to Client::acquire will cause the calling thread to block.

Note that the created Client is not automatically inherited into spawned child processes from this program. Manual usage of the Client::configure function is required for a child process to have access to a job server.

§Examples
use jobserver::Client;

let client = Client::new(4).expect("failed to create jobserver");
§Errors

Returns an error if any I/O error happens when attempting to create the jobserver client.

source

pub unsafe fn from_env_ext(check_pipe: bool) -> FromEnv

Attempts to connect to the jobserver specified in this process’s environment.

When the a make executable calls a child process it will configure the environment of the child to ensure that it has handles to the jobserver it’s passing down. This function will attempt to look for these details and connect to the jobserver.

Note that the created Client is not automatically inherited into spawned child processes from this program. Manual usage of the Client::configure function is required for a child process to have access to a job server.

§Return value

FromEnv contains result and relevant environment variable. If a jobserver was found in the environment and it looks correct then result with the connected client will be returned. In other cases result will contain Err(FromEnvErr).

Additionally on Unix this function will configure the file descriptors with CLOEXEC so they’re not automatically inherited by spawned children.

On unix if check_pipe enabled this function will check if provided files are actually pipes.

§Safety

This function is unsafe to call on Unix specifically as it transitively requires usage of the from_raw_fd function, which is itself unsafe in some circumstances.

It’s recommended to call this function very early in the lifetime of a program before any other file descriptors are opened. That way you can make sure to take ownership properly of the file descriptors passed down, if any.

It is ok to call this function any number of times.

source

pub unsafe fn from_env() -> Option<Client>

Attempts to connect to the jobserver specified in this process’s environment.

Wraps Client::from_env_ext and discards error details.

§Safety

This function is unsafe to call on Unix specifically as it transitively requires usage of the from_raw_fd function, which is itself unsafe in some circumstances.

It’s recommended to call this function very early in the lifetime of a program before any other file descriptors are opened. That way you can make sure to take ownership properly of the file descriptors passed down, if any.

It is ok to call this function any number of times.

source

pub fn acquire(&self) -> Result<Acquired, Error>

Acquires a token from this jobserver client.

This function will block the calling thread until a new token can be acquired from the jobserver.

§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.

source

pub fn try_acquire(&self) -> Result<Option<Acquired>, Error>

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.

source

pub fn available(&self) -> Result<usize, Error>

Returns amount of tokens in the read-side pipe.

§Return value

Number of bytes available to be read from the jobserver pipe

§Errors

Underlying errors from the ioctl will be passed up.

source

pub fn configure(&self, cmd: &mut Command)

Configures a child process to have access to this client’s jobserver as well.

This function is required to be called to ensure that a jobserver is properly inherited to a child process. If this function is not called then this Client will not be accessible in the child process. In other words, if not called, then Client::from_env will return None in the child process (or the equivalent of Client::from_env that make uses).

§Platform-specific behavior

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.

source

pub fn configure_make(&self, cmd: &mut Command)

Configures a child process to have access to this client’s jobserver as well.

This function is required to be called to ensure that a jobserver is properly inherited to a child process. If this function is not called then this Client will not be accessible in the child process. In other words, if not called, then Client::from_env will return None in the child process (or the equivalent of Client::from_env that make uses).

§Platform-specific behavior

On Unix and Windows this will clobber the CARGO_MAKEFLAGS, MAKEFLAGS and MFLAGS 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.

source

pub fn into_helper_thread<F>(self, f: F) -> Result<HelperThread, Error>
where F: FnMut(Result<Acquired, Error>) + Send + 'static,

Converts this Client into a helper thread to deal with a blocking Client::acquire function a little more easily.

The fact that the Client::acquire isn’t always the easiest to work with. Typically you’re using a jobserver to manage running other events in parallel! This means that you need to either (a) wait for an existing job to finish or (b) wait for a new token to become available.

Unfortunately the blocking in Client::acquire happens at the implementation layer of jobservers. On Unix this requires a blocking call to read and on Windows this requires one of the WaitFor* functions. Both of these situations aren’t the easiest to deal with:

  • On Unix there’s basically only one way to wake up a read early, and that’s through a signal. This is what the make implementation itself uses, relying on SIGCHLD to wake up a blocking acquisition of a new job token. Unfortunately nonblocking I/O is not an option here, so it means that “waiting for one of two events” means that the latter event must generate a signal! This is not always the case on unix for all jobservers.

  • On Windows you’d have to basically use the WaitForMultipleObjects which means that you’ve got to canonicalize all your event sources into a HANDLE which also isn’t the easiest thing to do unfortunately.

This function essentially attempts to ease these limitations by converting this Client into a helper thread spawned into this process. The application can then request that the helper thread acquires tokens and the provided closure will be invoked for each token acquired.

The intention is that this function can be used to translate the event of a token acquisition into an arbitrary user-defined event.

§Arguments

This function will consume the Client provided to be transferred to the helper thread that is spawned. Additionally a closure f is provided to be invoked whenever a token is acquired.

This closure is only invoked after calls to HelperThread::request_token have been made and a token itself has been acquired. If an error happens while acquiring the token then an error will be yielded to the closure as well.

§Return Value

This function will return an instance of the HelperThread structure which is used to manage the helper thread associated with this client. Through the HelperThread you’ll request that tokens are acquired. When acquired, the closure provided here is invoked.

When the HelperThread structure is returned it will be gracefully torn down, and the calling thread will be blocked until the thread is torn down (which should be prompt).

§Errors

This function may fail due to creation of the helper thread or auxiliary I/O objects to manage the helper thread. In any of these situations the error is propagated upwards.

§Platform-specific behavior

On Windows this function behaves pretty normally as expected, but on Unix the implementation is… a little heinous. As mentioned above we’re forced into blocking I/O for token acquisition, namely a blocking call to read. We must be able to unblock this, however, to tear down the helper thread gracefully!

Essentially what happens is that we’ll send a signal to the helper thread spawned and rely on EINTR being returned to wake up the helper thread. This involves installing a global SIGUSR1 handler that does nothing along with sending signals to that thread. This may cause odd behavior in some applications, so it’s recommended to review and test thoroughly before using this.

source

pub fn acquire_raw(&self) -> Result<(), Error>

Blocks the current thread until a token is acquired.

This is the same as Client::acquire, except that it doesn’t return an RAII helper. If successful the process will need to guarantee that Client::release_raw is called in the future.

source

pub fn release_raw(&self) -> Result<(), Error>

Releases a jobserver token back to the original jobserver.

This is intended to be paired with Client::acquire_raw if it was called, but in some situations it could also be called to relinquish a process’s implicit token temporarily which is then re-acquired later.

Trait Implementations§

source§

impl Clone for Client

source§

fn clone(&self) -> Client

Returns a copy of the value. Read more
source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl Debug for Client

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
source§

impl DynSync for Client
where Client: Sync,

Auto Trait Implementations§

§

impl DynSend for Client

§

impl Freeze for Client

§

impl RefUnwindSafe for Client

§

impl Send for Client

§

impl Sync for Client

§

impl Unpin for Client

§

impl UnwindSafe for Client

Blanket Implementations§

source§

impl<T> Aligned for T

source§

const ALIGN: Alignment = const ALIGN: Alignment = Alignment::of::<Self>();

Alignment of Self.
source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> CloneToUninit for T
where T: Clone,

source§

unsafe fn clone_to_uninit(&self, dst: *mut T)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dst. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T> Instrument for T

source§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
source§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> IntoEither for T

source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
source§

impl<T> Pointable for T

source§

const ALIGN: usize = _

The alignment of pointer.
source§

type Init = T

The type for initializers.
source§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
source§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
source§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
source§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
source§

impl<T> ToOwned for T
where T: Clone,

source§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

source§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> WithSubscriber for T

source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more
source§

impl<'a, T> Captures<'a> for T
where T: ?Sized,

Layout§

Note: Most layout information is completely unstable and may even differ between compilations. The only exception is types with certain repr(...) attributes. Please see the Rust Reference's “Type Layout” chapter for details on type layout guarantees.

Size: 8 bytes