@@ -32,15 +32,17 @@ impl Default for SingleThreadRuntime {
3232}
3333
3434struct Sender {
35- scheduling : kanal:: Sender < SpawnFuture < ' static > > ,
36- cpu : kanal:: Sender < SpawnCpu < ' static > > ,
35+ scheduling : kanal:: Sender < SpawnAsync < ' static > > ,
36+ cpu : kanal:: Sender < SpawnSync < ' static > > ,
37+ blocking : kanal:: Sender < SpawnSync < ' static > > ,
3738 io : kanal:: Sender < IoTask > ,
3839}
3940
4041impl Sender {
4142 fn new ( local : & Rc < LocalExecutor < ' static > > ) -> Self {
42- let ( scheduling_send, scheduling_recv) = kanal:: unbounded :: < SpawnFuture > ( ) ;
43- let ( cpu_send, cpu_recv) = kanal:: unbounded :: < SpawnCpu > ( ) ;
43+ let ( scheduling_send, scheduling_recv) = kanal:: unbounded :: < SpawnAsync > ( ) ;
44+ let ( cpu_send, cpu_recv) = kanal:: unbounded :: < SpawnSync > ( ) ;
45+ let ( blocking_send, blocking_recv) = kanal:: unbounded :: < SpawnSync > ( ) ;
4446 let ( io_send, io_recv) = kanal:: unbounded :: < IoTask > ( ) ;
4547
4648 // We pass weak references to the local executor into the async tasks such that the task's
@@ -68,10 +70,26 @@ impl Sender {
6870 . spawn ( async move {
6971 while let Ok ( spawn) = cpu_recv. as_async ( ) . recv ( ) . await {
7072 if let Some ( local) = weak_local2. upgrade ( ) {
71- let cpu = spawn. cpu ;
73+ let work = spawn. sync ;
7274 // Ignore send errors since it means the caller immediately detached.
7375 let _ = spawn. task_callback . send ( SmolAbortHandle :: new_handle (
74- local. spawn ( async move { cpu ( ) } ) ,
76+ local. spawn ( async move { work ( ) } ) ,
77+ ) ) ;
78+ }
79+ }
80+ } )
81+ . detach ( ) ;
82+
83+ // Drive blocking tasks.
84+ let weak_local2 = weak_local. clone ( ) ;
85+ local
86+ . spawn ( async move {
87+ while let Ok ( spawn) = blocking_recv. as_async ( ) . recv ( ) . await {
88+ if let Some ( local) = weak_local2. upgrade ( ) {
89+ let work = spawn. sync ;
90+ // Ignore send errors since it means the caller immediately detached.
91+ let _ = spawn. task_callback . send ( SmolAbortHandle :: new_handle (
92+ local. spawn ( async move { work ( ) } ) ,
7593 ) ) ;
7694 }
7795 }
@@ -93,6 +111,7 @@ impl Sender {
93111 Self {
94112 scheduling : scheduling_send,
95113 cpu : cpu_send,
114+ blocking : blocking_send,
96115 io : io_send,
97116 }
98117 }
@@ -105,7 +124,7 @@ impl Sender {
105124impl Runtime for Sender {
106125 fn spawn ( & self , future : BoxFuture < ' static , ( ) > ) -> AbortHandleRef {
107126 let ( send, recv) = oneshot:: channel ( ) ;
108- if let Err ( e) = self . scheduling . send ( SpawnFuture {
127+ if let Err ( e) = self . scheduling . send ( SpawnAsync {
109128 future,
110129 task_callback : send,
111130 } ) {
@@ -118,8 +137,21 @@ impl Runtime for Sender {
118137
119138 fn spawn_cpu ( & self , cpu : Box < dyn FnOnce ( ) + Send + ' static > ) -> AbortHandleRef {
120139 let ( send, recv) = oneshot:: channel ( ) ;
121- if let Err ( e) = self . cpu . send ( SpawnCpu {
122- cpu,
140+ if let Err ( e) = self . cpu . send ( SpawnSync {
141+ sync : cpu,
142+ task_callback : send,
143+ } ) {
144+ vortex_panic ! ( "Executor missing: {}" , e) ;
145+ }
146+ Box :: new ( LazyAbortHandle {
147+ task : Mutex :: new ( recv) ,
148+ } )
149+ }
150+
151+ fn spawn_blocking ( & self , work : Box < dyn FnOnce ( ) + Send + ' static > ) -> AbortHandleRef {
152+ let ( send, recv) = oneshot:: channel ( ) ;
153+ if let Err ( e) = self . blocking . send ( SpawnSync {
154+ sync : work,
123155 task_callback : send,
124156 } ) {
125157 vortex_panic ! ( "Executor missing: {}" , e) ;
@@ -198,14 +230,14 @@ where
198230/// we invert the behaviour of abort and drop. Dropping the abort handle results in the task being
199231/// detached, whereas dropping the smol::Task results in the task being canceled. This helps avoid
200232/// a race where the caller detaches the LazyAbortHandle before the smol::Task has been launched.
201- struct SpawnFuture < ' rt > {
233+ struct SpawnAsync < ' rt > {
202234 future : BoxFuture < ' rt , ( ) > ,
203235 task_callback : oneshot:: Sender < AbortHandleRef > ,
204236}
205237
206- // A spawn request for a CPU job.
207- struct SpawnCpu < ' rt > {
208- cpu : Box < dyn FnOnce ( ) + Send + ' rt > ,
238+ // A spawn request for a synchronous job.
239+ struct SpawnSync < ' rt > {
240+ sync : Box < dyn FnOnce ( ) + Send + ' rt > ,
209241 task_callback : oneshot:: Sender < AbortHandleRef > ,
210242}
211243
0 commit comments