File tree 4 files changed +79
-0
lines changed
code/spawn-blocking-workspace
members/spawn-blocking-lib
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