@@ -2,17 +2,26 @@ use crate::clocks::WasiClocks;
2
2
use crate :: dir:: { DirCaps , DirEntry , WasiDir } ;
3
3
use crate :: file:: { FileCaps , FileEntry , WasiFile } ;
4
4
use crate :: sched:: WasiSched ;
5
- use crate :: string_array:: { StringArray , StringArrayError } ;
5
+ use crate :: string_array:: StringArray ;
6
6
use crate :: table:: Table ;
7
- use crate :: Error ;
7
+ use crate :: { Error , StringArrayError } ;
8
8
use cap_rand:: RngCore ;
9
+ use std:: ops:: Deref ;
9
10
use std:: path:: { Path , PathBuf } ;
10
- use std:: sync:: Arc ;
11
+ use std:: sync:: { Arc , Mutex } ;
11
12
12
- pub struct WasiCtx {
13
+ /// An `Arc`-wrapper around the wasi-common context to allow mutable access to
14
+ /// the file descriptor table. This wrapper is only necessary due to the
15
+ /// signature of `fd_fdstat_set_flags`; if that changes, there are a variety of
16
+ /// improvements that can be made (TODO:
17
+ /// https://github.com/bytecodealliance/wasmtime/issues/5643).
18
+ #[ derive( Clone ) ]
19
+ pub struct WasiCtx ( Arc < WasiCtxInner > ) ;
20
+
21
+ pub struct WasiCtxInner {
13
22
pub args : StringArray ,
14
23
pub env : StringArray ,
15
- pub random : Box < dyn RngCore + Send + Sync > ,
24
+ pub random : Mutex < Box < dyn RngCore + Send + Sync > > ,
16
25
pub clocks : WasiClocks ,
17
26
pub sched : Box < dyn WasiSched > ,
18
27
pub table : Table ,
@@ -25,14 +34,14 @@ impl WasiCtx {
25
34
sched : Box < dyn WasiSched > ,
26
35
table : Table ,
27
36
) -> Self {
28
- let s = WasiCtx {
37
+ let s = WasiCtx ( Arc :: new ( WasiCtxInner {
29
38
args : StringArray :: new ( ) ,
30
39
env : StringArray :: new ( ) ,
31
- random,
40
+ random : Mutex :: new ( random ) ,
32
41
clocks,
33
42
sched,
34
43
table,
35
- } ;
44
+ } ) ) ;
36
45
s. set_stdin ( Box :: new ( crate :: pipe:: ReadPipe :: new ( std:: io:: empty ( ) ) ) ) ;
37
46
s. set_stdout ( Box :: new ( crate :: pipe:: WritePipe :: new ( std:: io:: sink ( ) ) ) ) ;
38
47
s. set_stderr ( Box :: new ( crate :: pipe:: WritePipe :: new ( std:: io:: sink ( ) ) ) ) ;
@@ -77,12 +86,22 @@ impl WasiCtx {
77
86
& self . table
78
87
}
79
88
89
+ pub fn table_mut ( & mut self ) -> Option < & mut Table > {
90
+ Arc :: get_mut ( & mut self . 0 ) . map ( |c| & mut c. table )
91
+ }
92
+
80
93
pub fn push_arg ( & mut self , arg : & str ) -> Result < ( ) , StringArrayError > {
81
- self . args . push ( arg. to_owned ( ) )
94
+ let s = Arc :: get_mut ( & mut self . 0 ) . expect (
95
+ "`push_arg` should only be used during initialization before the context is cloned" ,
96
+ ) ;
97
+ s. args . push ( arg. to_owned ( ) )
82
98
}
83
99
84
100
pub fn push_env ( & mut self , var : & str , value : & str ) -> Result < ( ) , StringArrayError > {
85
- self . env . push ( format ! ( "{}={}" , var, value) ) ?;
101
+ let s = Arc :: get_mut ( & mut self . 0 ) . expect (
102
+ "`push_env` should only be used during initialization before the context is cloned" ,
103
+ ) ;
104
+ s. env . push ( format ! ( "{}={}" , var, value) ) ?;
86
105
Ok ( ( ) )
87
106
}
88
107
@@ -130,3 +149,10 @@ impl WasiCtx {
130
149
Ok ( ( ) )
131
150
}
132
151
}
152
+
153
+ impl Deref for WasiCtx {
154
+ type Target = WasiCtxInner ;
155
+ fn deref ( & self ) -> & Self :: Target {
156
+ & self . 0
157
+ }
158
+ }
0 commit comments