pub struct Client { /* private fields */ }
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.

Implementations

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

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 configure function is required for a child process to have access to a job server.

Return value

If a jobserver was found in the environment and it looks correct then Some of the connected client will be returned. If no jobserver was found then None will be returned.

Note that on Unix the Client returned takes ownership of the file descriptors specified in the environment. Jobservers on Unix are implemented with pipe file descriptors, and they’re inherited from parent processes. This Client returned takes ownership of the file descriptors for this process and will close the file descriptors after this value is dropped.

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

Unsafety

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’s generally unsafe to call this function twice in a program if the previous invocation returned Some.

Note, though, that on Windows it should be safe to call this function any number of times.

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.

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 Child::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.

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

The fact that the acquire function on Client blocks 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 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.

Blocks the current thread until a token is acquired.

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

Releases a jobserver token back to the original jobserver.

This is intended to be paired with 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

Returns a copy of the value. Read more

Performs copy-assignment from source. Read more

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more

Immutably borrows from an owned value. Read more

Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The resulting type after obtaining ownership.

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

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

The type returned in the event of a conversion error.

Performs the conversion.

The type returned in the event of a conversion error.

Performs the conversion.