File tree Expand file tree Collapse file tree 4 files changed +79
-0
lines changed
code/spawn-blocking-workspace
members/spawn-blocking-lib Expand file tree Collapse file tree 4 files changed +79
-0
lines changed Original file line number Diff line number Diff line change 1+ workspace = { members = [" members/spawn-blocking-lib" ] }
2+ [package ]
3+ name = " spawn-blocking-workspace"
4+ version = " 0.1.0"
5+ edition = " 2021"
6+
7+ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
8+
9+ [dependencies ]
Original file line number Diff line number Diff line change 1+ [package ]
2+ name = " spawn-blocking-lib"
3+ version = " 0.1.0"
4+ edition = " 2021"
5+
6+ # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+ [dependencies ]
9+
10+ async-std = " 1.7"
Original file line number Diff line number Diff line change 1+ use std:: sync:: { Arc , Mutex } ;
2+ use std:: task:: Waker ;
3+
4+ pub struct SpawnBlocking < T > ( Arc < Mutex < Shared < T > > > ) ;
5+
6+ struct Shared < T > {
7+ value : Option < T > ,
8+ waker : Option < Waker > ,
9+ }
10+
11+ pub fn spawn_blocking < T , F > ( closure : F ) -> SpawnBlocking < T >
12+ where F : FnOnce ( ) -> T ,
13+ F : Send + ' static ,
14+ T : Send + ' static ,
15+ {
16+ let inner = Arc :: new ( Mutex :: new ( Shared {
17+ value : None ,
18+ waker : None ,
19+ } ) ) ;
20+
21+ std:: thread:: spawn ( {
22+ let inner = inner. clone ( ) ;
23+ move || {
24+ let value = closure ( ) ;
25+
26+ let maybe_waker = {
27+ let mut guard = inner. lock ( ) . unwrap ( ) ;
28+ guard. value = Some ( value) ;
29+ guard. waker . take ( )
30+ } ;
31+
32+ if let Some ( waker) = maybe_waker {
33+ waker. wake ( ) ;
34+ }
35+ }
36+ } ) ;
37+
38+ SpawnBlocking ( inner)
39+ }
40+
41+ use std:: future:: Future ;
42+ use std:: pin:: Pin ;
43+ use std:: task:: { Context , Poll } ;
44+
45+ impl < T : Send > Future for SpawnBlocking < T > {
46+ type Output = T ;
47+
48+ fn poll ( self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < T > {
49+ let mut guard = self . 0 . lock ( ) . unwrap ( ) ;
50+ if let Some ( value) = guard. value . take ( ) {
51+ return Poll :: Ready ( value) ;
52+ }
53+
54+ guard. waker = Some ( cx. waker ( ) . clone ( ) ) ;
55+ Poll :: Pending
56+ }
57+ }
Original file line number Diff line number Diff line change 1+ fn main ( ) {
2+ println ! ( "Hello, world!" ) ;
3+ }
You can’t perform that action at this time.
0 commit comments