Skip to main content

ThreadpoolPool

Struct ThreadpoolPool 

Source
pub struct ThreadpoolPool { /* private fields */ }
Expand description

An owned private thread pool.

Pass it to CallbackEnviron::set_pool to run an object’s callbacks on this pool instead of the process-default one. The environment borrows the pool, so the pool cannot be closed while an environment still names it.

§Ordering and teardown

Creating a callback object from an environment that names this pool binds the object to the pool. CloseThreadpool – which this type’s Drop calls – frees the pool immediately only when no object is bound; otherwise it defers the release until every bound object has been freed. A live object can therefore never observe a freed pool, whatever order the pool and its objects are dropped in, so this is not a memory-safety obligation on the caller. (The CallbackEnviron borrow of the pool covers the one case binding does not: a freshly created pool with no bound object yet is freed at once, so an environment must not outlive it.)

What the order does control is when teardown blocks. Each object’s Drop waits for its in-flight callbacks; the pool’s deferred release then completes once the last object is gone. Declare the pool before the objects that use it, so it is dropped last and that blocking happens where you expect.

§Examples

use windows_threadpool_sys::callback_env::CallbackEnviron;
use windows_threadpool_sys::pool::ThreadpoolPool;
use windows_threadpool_sys::timer::ThreadpoolTimer;
use std::time::Duration;

// Declared first, so it outlives the objects that use it.
let pool = ThreadpoolPool::new()?;
pool.set_min_threads(1)?;
pool.set_max_threads(4)?;

let mut env = CallbackEnviron::new();
env.set_pool(&pool);

let timer = ThreadpoolTimer::new(|_firing| {}, Some(&mut env))?;
timer.set_after(Duration::from_millis(1));
timer.wait();

Implementations§

Source§

impl ThreadpoolPool

Source

pub fn new() -> Result<Self>

Create a new private thread pool.

§Errors

Returns the error from CreateThreadpool, which fails when the process cannot allocate the pool.

Source

pub fn set_max_threads(&self, maximum: u32) -> Result<()>

Set the maximum number of threads this pool may allocate.

§Conflicting limits

Win32 lets the two limits contradict each other and resolves the conflict by last call wins, silently and unreportably. A pool given a maximum of 2 and then a minimum of 4 was measured running 4 callbacks concurrently, and it did not settle back to 2. This wrapper therefore tracks the limits it has set and rejects a pair that cannot both hold, rather than letting one quietly annul the other.

§The maximum is a steady-state target, not an instantaneous ceiling

Even where the maximum is the effective limit, it bounds the pool once it has settled, not every instant. Raising the minimum creates threads eagerly, and those surplus threads are not retired the moment a lower maximum is applied: with a minimum of 4 then a maximum of 2, a third callback was observed running concurrently in roughly 1 trial in 240 when many pools were being created at once. Do not rely on the maximum as a mutual-exclusion mechanism; use it to bound resource consumption.

§Errors

Returns io::ErrorKind::InvalidInput if maximum is zero. Such a pool runs no callbacks at all – work submitted to it is queued and never executed – and SetThreadpoolThreadMaximum returns void, so nothing else could report the mistake. Use CleanupGroup or the objects’ own teardown to stop callbacks, rather than starving the pool that runs them.

Also returns io::ErrorKind::InvalidInput if maximum is below a minimum previously set through set_min_threads.

§Examples

A maximum below an established minimum is refused instead of silently overriding it:

use windows_threadpool_sys::pool::ThreadpoolPool;

let pool = ThreadpoolPool::new()?;
pool.set_min_threads(4)?;
assert!(pool.set_max_threads(2).is_err());
Source

pub fn set_min_threads(&self, minimum: u32) -> Result<()>

Set the minimum number of threads this pool keeps available.

Raising the minimum makes the pool create threads eagerly, which is what guarantees forward progress for callbacks that block on one another.

§Errors

Returns the error from SetThreadpoolThreadMinimum, which fails when the pool cannot create the requested threads.

Returns io::ErrorKind::InvalidInput if minimum exceeds a maximum previously set through set_max_threads. Win32 would accept it and run up to minimum callbacks concurrently, annulling the maximum without reporting anything; see set_max_threads for the measurements.

§Examples
use windows_threadpool_sys::pool::ThreadpoolPool;

let pool = ThreadpoolPool::new()?;
pool.set_max_threads(2)?;
assert!(pool.set_min_threads(4).is_err());
pool.set_min_threads(2)?;

Trait Implementations§

Source§

impl Debug for ThreadpoolPool

Source§

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

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

impl Drop for ThreadpoolPool

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more
Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more
Source§

impl Send for ThreadpoolPool

Source§

impl Sync for ThreadpoolPool

Auto Trait Implementations§

Blanket Implementations§

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> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

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