Skip to content

Commit 3c295d4

Browse files
committed
Add ThreadPool::drain_execute() and document shutdown semantics
1 parent 49d6720 commit 3c295d4

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,18 @@ Support for futures is based on an approach sketched out by members of the `rayo
2323
Forte is distributed under the terms of both the MIT license and the Apache License (Version 2.0).
2424
See LICENSE-APACHE and LICENSE-MIT for details.
2525
Opening a pull request is assumed to signal agreement with these licensing terms.
26+
27+
## Shutdown semantics
28+
29+
Heap-allocated jobs created via `HeapJob::into_job_ref` are owned by the
30+
job reference and will be dropped when executed. If a `JobRef` is placed
31+
into the shared injector but never executed (for example, if the pool is
32+
shut down before the job is drained) the allocation may be leaked. This is
33+
an intentional tradeoff to avoid adding complex bookkeeping to the fast
34+
path of job scheduling.
35+
36+
If you need to ensure that all remaining shared jobs are executed (and thus
37+
freed) before shutdown, call `ThreadPool::drain_execute()` which will run
38+
remaining shared jobs on the calling thread. Note this drains only the
39+
shared injector queue; work that remains in other workers' local deques may
40+
not be reachable by this call.

src/thread_pool.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,22 @@ impl ThreadPool {
647647
work.spawn(self, None)
648648
}
649649

650+
/// Drain and execute any remaining shared jobs on the calling thread.
651+
///
652+
/// This is useful during shutdown if you want to ensure that heap-allocated
653+
/// jobs are actually executed (and therefore dropped) rather than being
654+
/// leaked in the shared queue. This will claim a temporary worker for the
655+
/// current thread and execute items from the shared queue until it is
656+
/// empty. Note that this only drains the shared injector queue; jobs that
657+
/// remain in other workers' local deques cannot be accessed here.
658+
pub fn drain_execute(&'static self) {
659+
self.with_worker(|worker| {
660+
while let Some(job_ref) = self.shared_jobs.pop() {
661+
worker.execute(job_ref, true);
662+
}
663+
})
664+
}
665+
650666
/// Blocks the thread waiting for a future to complete.
651667
///
652668
/// See also: [`Worker::block_on`] and [`block_on`].

0 commit comments

Comments
 (0)