@@ -21,6 +21,40 @@ mod internal;
21
21
#[ cfg( test) ]
22
22
mod test;
23
23
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
+
24
58
///Represents a fork-join scope which can be used to spawn any number of tasks. See [`scope()`] for more information.
25
59
///
26
60
///[`scope()`]: fn.scope.html
@@ -44,7 +78,7 @@ pub struct Scope<'scope> {
44
78
/// all of which outlive `'scope`. They're not actually required to be
45
79
/// `Sync`, but it's still safe to let the `Scope` implement `Sync` because
46
80
/// the closures are only *moved* across threads to be executed.
47
- marker : PhantomData < Box < FnOnce ( & Scope < ' scope > ) + Send + Sync + ' scope > > ,
81
+ marker : PhantomData < & ' scope ( ) > ,
48
82
}
49
83
50
84
/// Create a "fork-join" scope `s` and invokes the closure with a
0 commit comments