Skip to content

Commit a5a4b20

Browse files
committed
fix: docs and tests
1 parent 9523d1d commit a5a4b20

File tree

3 files changed

+44
-21
lines changed

3 files changed

+44
-21
lines changed

src/lib.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,18 @@ mod signal;
4242
mod thread_pool;
4343
mod unwind;
4444

45+
// -----------------------------------------------------------------------------
46+
// Type markers
47+
48+
#[doc(hidden)]
49+
pub struct FnOnceMarker;
50+
51+
#[doc(hidden)]
52+
pub struct FutureMarker;
53+
54+
#[doc(hidden)]
55+
pub struct AsyncMarker;
56+
4557
// -----------------------------------------------------------------------------
4658
// Top-level exports
4759

src/scope.rs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@ use crate::job::JobRef;
1515
use crate::platform::*;
1616
use crate::signal::Signal;
1717
use crate::thread_pool::Worker;
18+
use crate::AsyncMarker;
19+
use crate::FnOnceMarker;
20+
use crate::FutureMarker;
1821

1922
// -----------------------------------------------------------------------------
2023
// Scope
@@ -148,14 +151,18 @@ impl Drop for Scope<'_> {
148151
// -----------------------------------------------------------------------------
149152
// Generalized scoped spawn trait
150153

151-
pub trait ScopedSpawn<'scope, T> {
154+
/// Logic for spawning scoped work onto a thread pool.
155+
///
156+
/// This trait defines the behavor of [`Scope::spawn`] for various types.
157+
pub trait ScopedSpawn<'scope, M> {
158+
/// The output returned by the spawn operation. This is usually either the
159+
/// empty type `()` or a `Task<T>`.
152160
type Output;
153161

162+
/// Spawns scoped work onto the thread pool.
154163
fn spawn(self, scope: &Scope<'scope>) -> Self::Output;
155164
}
156165

157-
struct FnOnceMarker;
158-
159166
impl<'scope, F> ScopedSpawn<'scope, FnOnceMarker> for F
160167
where
161168
F: FnOnce(&Scope<'scope>) + Send + 'scope,
@@ -191,8 +198,6 @@ where
191198
}
192199
}
193200

194-
struct FutureMarker;
195-
196201
impl<'scope, Fut, T> ScopedSpawn<'scope, FutureMarker> for Fut
197202
where
198203
Fut: Future<Output = T> + Send + 'scope,
@@ -207,8 +212,6 @@ where
207212
}
208213
}
209214

210-
struct AsyncMarker;
211-
212215
impl<'scope, Fn, Fut, T> ScopedSpawn<'scope, AsyncMarker> for Fn
213216
where
214217
Fn: FnOnce(&Scope<'scope>) -> Fut + Send + 'scope,
@@ -225,7 +228,11 @@ where
225228
// scope is via `Scope::new` and that function requires the caller pin
226229
// the scope before using it.
227230
let scope_ptr = unsafe { ScopePtr::new(scope) };
228-
let future = async move { scope_ptr.run(self).await };
231+
let future = async move {
232+
let result = scope_ptr.run(self).await;
233+
drop(scope_ptr);
234+
result
235+
};
229236

230237
// The schedule function will turn the future into a job when woken.
231238
let schedule = move |runnable: Runnable| {

src/thread_pool.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,9 @@ use crate::platform::*;
3131
use crate::scope::Scope;
3232
use crate::signal::Signal;
3333
use crate::unwind;
34+
use crate::AsyncMarker;
35+
use crate::FnOnceMarker;
36+
use crate::FutureMarker;
3437

3538
// -----------------------------------------------------------------------------
3639
// Thread pool worker leases
@@ -491,22 +494,26 @@ impl ThreadPool {
491494
// -----------------------------------------------------------------------------
492495
// Generalized spawn trait
493496

494-
pub trait Spawn<T> {
497+
/// Logic for spawning work onto a thread pool.
498+
///
499+
/// This trait defines the behavior of [`ThreadPool::spawn`] for various types.
500+
pub trait Spawn<M> {
501+
/// The output returned by the spawn operation. This is usually either the
502+
/// empty type `()` or a `Task<T>`.
495503
type Output;
496504

505+
/// Spawns work onto the thread pool.
497506
fn spawn(self, thread_pool: &'static ThreadPool, worker: Option<&Worker>) -> Self::Output;
498507
}
499508

500-
struct FnOnceMarker;
501-
502509
impl<F> Spawn<FnOnceMarker> for F
503510
where
504511
F: FnOnce(&Worker) + Send + 'static,
505512
{
506513
type Output = ();
507514

508515
#[inline]
509-
fn spawn(self, _thread_pool: &'static ThreadPool, worker: Option<&Worker>) {
516+
fn spawn(self, thread_pool: &'static ThreadPool, worker: Option<&Worker>) {
510517
// Allocate a new job on the heap to store the closure.
511518
let job = HeapJob::new(self);
512519

@@ -523,13 +530,12 @@ where
523530
if let Some(worker) = worker {
524531
worker.queue.push_back(job_ref);
525532
} else {
526-
todo!();
533+
let mut state = thread_pool.state.lock().unwrap();
534+
state.shared_jobs.push_back(job_ref);
527535
}
528536
}
529537
}
530538

531-
struct FutureMarker;
532-
533539
impl<Fut, T> Spawn<FutureMarker> for Fut
534540
where
535541
Fut: Future<Output = T> + Send + 'static,
@@ -588,8 +594,6 @@ where
588594
}
589595
}
590596

591-
struct AsyncMarker;
592-
593597
impl<Fn, Fut, T> Spawn<AsyncMarker> for Fn
594598
where
595599
Fn: FnOnce() -> Fut + Send + 'static,
@@ -613,7 +617,7 @@ impl ThreadPool {
613617
///
614618
/// See also: [`Worker::spawn`] and [`spawn`].
615619
#[inline]
616-
pub fn spawn<T, S: Spawn<T>>(&'static self, work: S) -> <S as Spawn<T>>::Output {
620+
pub fn spawn<M, S: Spawn<M>>(&'static self, work: S) -> <S as Spawn<M>>::Output {
617621
work.spawn(self, None)
618622
}
619623

@@ -955,7 +959,7 @@ impl Worker {
955959
/// If you do not have access to a [`Worker`], you may call
956960
/// [`ThreadPool::spawn`] or simply [`spawn`].
957961
#[inline]
958-
pub fn spawn<T, S: Spawn<T>>(&self, work: S) -> <S as Spawn<T>>::Output {
962+
pub fn spawn<M, S: Spawn<M>>(&self, work: S) -> <S as Spawn<M>>::Output {
959963
work.spawn(self.lease.thread_pool, Some(self))
960964
}
961965

@@ -1104,7 +1108,7 @@ impl Worker {
11041108
/// If there is no current thread pool, this panics.
11051109
///
11061110
/// See also: [`Worker::spawn`] and [`ThreadPool::spawn`].
1107-
pub fn spawn<T, S: Spawn<T>>(work: S) -> <S as Spawn<T>>::Output {
1111+
pub fn spawn<M, S: Spawn<M>>(work: S) -> <S as Spawn<M>>::Output {
11081112
Worker::with_current(|worker| {
11091113
worker
11101114
.expect("attempt to call `forte::spawn` from outside a thread pool")
@@ -1353,7 +1357,7 @@ mod tests {
13531357

13541358
THREAD_POOL.scope(|scope| {
13551359
for _ in 0..NUM_JOBS {
1356-
scope.spawn(|_| {
1360+
scope.spawn(|_: &Scope<'_>| {
13571361
THREAD_POOL.join(
13581362
|_| a.fetch_add(1, Ordering::Relaxed),
13591363
|_| b.fetch_add(1, Ordering::Relaxed),

0 commit comments

Comments
 (0)