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
impl ThreadpoolPool
Sourcepub fn new() -> Result<Self>
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.
Sourcepub fn set_max_threads(&self, maximum: u32) -> Result<()>
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());Sourcepub fn set_min_threads(&self, minimum: u32) -> Result<()>
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)?;