Skip to content

Commit 99e87af

Browse files
committed
Add a way to create scopes with a single lifetime
1 parent 51ee2fa commit 99e87af

File tree

2 files changed

+36
-2
lines changed

2 files changed

+36
-2
lines changed

rayon-core/src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ pub mod tlv;
6262
#[cfg(rayon_unstable)]
6363
pub mod internal;
6464
pub use join::{join, join_context};
65-
pub use scope::{scope, Scope};
65+
pub use scope::{scope, Scope, ScopeBuilder};
6666
pub use registry::{Registry, mark_blocked, mark_unblocked};
6767
pub use spawn::spawn;
6868
pub use worker_local::WorkerLocal;

rayon-core/src/scope/mod.rs

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,40 @@ mod internal;
2121
#[cfg(test)]
2222
mod test;
2323

24+
pub struct ScopeBuilder<'scope> {
25+
scope: Option<Scope<'scope>>,
26+
}
27+
28+
impl<'scope> ScopeBuilder<'scope> {
29+
pub fn new() -> Self {
30+
Self {
31+
scope: None,
32+
}
33+
}
34+
35+
pub fn scope<OP, R>(&'scope mut self, op: OP) -> R
36+
where
37+
OP: FnOnce(&'scope Scope<'scope>) -> R + 'scope + Send,
38+
R: Send,
39+
{
40+
in_worker(move |owner_thread, _| {
41+
unsafe {
42+
self.scope = Some(Scope {
43+
owner_thread_index: owner_thread.index(),
44+
registry: owner_thread.registry().clone(),
45+
panic: AtomicPtr::new(ptr::null_mut()),
46+
job_completed_latch: CountLatch::new(),
47+
marker: PhantomData,
48+
});
49+
let scope = self.scope.as_ref().unwrap();
50+
let result = scope.execute_job_closure(move |_| op(scope));
51+
scope.steal_till_jobs_complete(owner_thread);
52+
result.unwrap() // only None if `op` panicked, and that would have been propagated
53+
}
54+
})
55+
}
56+
}
57+
2458
///Represents a fork-join scope which can be used to spawn any number of tasks. See [`scope()`] for more information.
2559
///
2660
///[`scope()`]: fn.scope.html
@@ -44,7 +78,7 @@ pub struct Scope<'scope> {
4478
/// all of which outlive `'scope`. They're not actually required to be
4579
/// `Sync`, but it's still safe to let the `Scope` implement `Sync` because
4680
/// the closures are only *moved* across threads to be executed.
47-
marker: PhantomData<Box<FnOnce(&Scope<'scope>) + Send + Sync + 'scope>>,
81+
marker: PhantomData<&'scope ()>,
4882
}
4983

5084
/// Create a "fork-join" scope `s` and invokes the closure with a

0 commit comments

Comments
 (0)