@@ -37,42 +37,47 @@ pub fn start_unix_server() -> PathBuf {
37
37
std:: fs:: remove_file ( & path) . unwrap ( ) ;
38
38
}
39
39
40
- let listener = UnixListener :: bind ( & path) . unwrap ( ) ;
41
-
42
- in_tokio ( async move {
43
- loop {
44
- let ( stream, _) = listener. accept ( ) . await . unwrap ( ) ;
45
- let tokio_io = TokioIo :: new ( stream) ;
46
-
47
- tokio:: task:: spawn ( async move {
48
- if let Err ( err) = http1:: Builder :: new ( )
49
- . serve_connection ( tokio_io, service_fn ( hello_world_route) )
50
- . await
51
- {
52
- eprintln ! ( "Error serving connection: {:?}" , err) ;
53
- }
54
- } ) ;
55
- }
56
- } ) ;
40
+ let cloned_path = path. clone ( ) ;
41
+
42
+ in_dedicated_thread (
43
+ move || UnixListener :: bind ( & cloned_path) . unwrap ( ) ,
44
+ move |listener| async move {
45
+ loop {
46
+ let ( stream, _) = listener. accept ( ) . await . unwrap ( ) ;
47
+ let tokio_io = TokioIo :: new ( stream) ;
48
+
49
+ tokio:: task:: spawn ( async move {
50
+ if let Err ( err) = http1:: Builder :: new ( )
51
+ . serve_connection ( tokio_io, service_fn ( hello_world_route) )
52
+ . await
53
+ {
54
+ eprintln ! ( "Error serving connection: {:?}" , err) ;
55
+ }
56
+ } ) ;
57
+ }
58
+ } ,
59
+ ) ;
57
60
58
61
path
59
62
}
60
63
61
64
pub fn start_vsock_server ( ) -> ( u32 , u32 ) {
62
65
let port = rand:: thread_rng ( ) . gen_range ( 10000 ..=65536 ) as u32 ;
63
- let mut listener = VsockListener :: bind ( VsockAddr :: new ( VMADDR_CID_LOCAL , port) ) . unwrap ( ) ;
64
-
65
- in_tokio ( async move {
66
- loop {
67
- let tokio_io = TokioIo :: new ( listener. accept ( ) . await . unwrap ( ) . 0 ) ;
68
- tokio:: task:: spawn ( async move {
69
- http1:: Builder :: new ( )
70
- . serve_connection ( tokio_io, service_fn ( hello_world_route) )
71
- . await
72
- . unwrap ( ) ;
73
- } ) ;
74
- }
75
- } ) ;
66
+
67
+ in_dedicated_thread (
68
+ move || VsockListener :: bind ( VsockAddr :: new ( VMADDR_CID_LOCAL , port) ) . unwrap ( ) ,
69
+ |mut listener| async move {
70
+ loop {
71
+ let tokio_io = TokioIo :: new ( listener. accept ( ) . await . unwrap ( ) . 0 ) ;
72
+ tokio:: task:: spawn ( async move {
73
+ http1:: Builder :: new ( )
74
+ . serve_connection ( tokio_io, service_fn ( hello_world_route) )
75
+ . await
76
+ . unwrap ( ) ;
77
+ } ) ;
78
+ }
79
+ } ,
80
+ ) ;
76
81
77
82
( VMADDR_CID_LOCAL , port)
78
83
}
@@ -82,45 +87,62 @@ pub fn start_firecracker_server() -> (PathBuf, u32) {
82
87
if path. exists ( ) {
83
88
std:: fs:: remove_file ( & path) . unwrap ( ) ;
84
89
}
90
+ let cloned_path = path. clone ( ) ;
91
+
85
92
let guest_port = rand:: thread_rng ( ) . gen_range ( 1 ..=1000 ) as u32 ;
86
93
87
- let listener = UnixListener :: bind ( & path ) . unwrap ( ) ;
88
-
89
- in_tokio ( async move {
90
- loop {
91
- // Recreate the CONNECT behavior of a real Firecracker socket
92
- let ( mut stream, _) = listener. accept ( ) . await . unwrap ( ) ;
93
- let mut buf_reader = BufReader :: new ( & mut stream) . lines ( ) ;
94
- let mut line = String :: new ( ) ;
95
- buf_reader. get_mut ( ) . read_line ( & mut line) . await . unwrap ( ) ;
96
-
97
- if line == format ! ( "CONNECT {guest_port}\n " ) {
98
- stream. write_all ( b"OK\n " ) . await . unwrap ( ) ;
99
- } else {
100
- stream. write_all ( b"REJECTED\n " ) . await . unwrap ( ) ;
101
- return ;
102
- }
94
+ in_dedicated_thread (
95
+ move || UnixListener :: bind ( & cloned_path ) . unwrap ( ) ,
96
+ move |listener| async move {
97
+ loop {
98
+ // Recreate the CONNECT behavior of a real Firecracker socket
99
+ let ( mut stream, _) = listener. accept ( ) . await . unwrap ( ) ;
100
+ let mut buf_reader = BufReader :: new ( & mut stream) . lines ( ) ;
101
+ let mut line = String :: new ( ) ;
102
+ buf_reader. get_mut ( ) . read_line ( & mut line) . await . unwrap ( ) ;
103
+
104
+ if line == format ! ( "CONNECT {guest_port}\n " ) {
105
+ stream. write_all ( b"OK\n " ) . await . unwrap ( ) ;
106
+ } else {
107
+ stream. write_all ( b"REJECTED\n " ) . await . unwrap ( ) ;
108
+ return ;
109
+ }
103
110
104
- // After sending out approval, serve HTTP
105
- let tokio_io = TokioIo :: new ( stream) ;
106
- tokio:: task:: spawn ( async move {
107
- http1:: Builder :: new ( )
108
- . serve_connection ( tokio_io, service_fn ( hello_world_route) )
109
- . await
110
- . unwrap ( ) ;
111
- } ) ;
112
- }
113
- } ) ;
111
+ // After sending out approval, serve HTTP
112
+ let tokio_io = TokioIo :: new ( stream) ;
113
+ tokio:: task:: spawn ( async move {
114
+ http1:: Builder :: new ( )
115
+ . serve_connection ( tokio_io, service_fn ( hello_world_route) )
116
+ . await
117
+ . unwrap ( ) ;
118
+ } ) ;
119
+ }
120
+ } ,
121
+ ) ;
114
122
115
123
( path, guest_port)
116
124
}
117
125
118
- fn in_tokio ( future : impl Future < Output = ( ) > + Send + ' static ) {
126
+ fn in_dedicated_thread < Listener , MakeListener , Act , ActFuture > ( make_listener : MakeListener , act : Act )
127
+ where
128
+ MakeListener : ' static + Send + FnOnce ( ) -> Listener ,
129
+ Listener : Send ,
130
+ Act : ' static + Send + FnOnce ( Listener ) -> ActFuture ,
131
+ ActFuture : Future < Output = ( ) > + Send ,
132
+ {
133
+ let ( tx, rx) = std:: sync:: mpsc:: channel ( ) ;
134
+
119
135
std:: thread:: spawn ( move || {
120
136
tokio:: runtime:: Builder :: new_current_thread ( )
121
137
. enable_all ( )
122
138
. build ( )
123
139
. unwrap ( )
124
- . block_on ( future)
140
+ . block_on ( async move {
141
+ let listener = make_listener ( ) ;
142
+ tx. send ( ( ) ) . unwrap ( ) ;
143
+ act ( listener) . await ;
144
+ } )
125
145
} ) ;
146
+
147
+ rx. recv ( ) . unwrap ( ) ;
126
148
}
0 commit comments