@@ -2,17 +2,26 @@ use crate::clocks::WasiClocks;
22use crate :: dir:: { DirCaps , DirEntry , WasiDir } ;
33use crate :: file:: { FileCaps , FileEntry , WasiFile } ;
44use crate :: sched:: WasiSched ;
5- use crate :: string_array:: { StringArray , StringArrayError } ;
5+ use crate :: string_array:: StringArray ;
66use crate :: table:: Table ;
7- use crate :: Error ;
7+ use crate :: { Error , StringArrayError } ;
88use cap_rand:: RngCore ;
9+ use std:: ops:: Deref ;
910use std:: path:: { Path , PathBuf } ;
10- use std:: sync:: Arc ;
11+ use std:: sync:: { Arc , Mutex } ;
1112
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 {
1322 pub args : StringArray ,
1423 pub env : StringArray ,
15- pub random : Box < dyn RngCore + Send + Sync > ,
24+ pub random : Mutex < Box < dyn RngCore + Send + Sync > > ,
1625 pub clocks : WasiClocks ,
1726 pub sched : Box < dyn WasiSched > ,
1827 pub table : Table ,
@@ -25,14 +34,14 @@ impl WasiCtx {
2534 sched : Box < dyn WasiSched > ,
2635 table : Table ,
2736 ) -> Self {
28- let s = WasiCtx {
37+ let s = WasiCtx ( Arc :: new ( WasiCtxInner {
2938 args : StringArray :: new ( ) ,
3039 env : StringArray :: new ( ) ,
31- random,
40+ random : Mutex :: new ( random ) ,
3241 clocks,
3342 sched,
3443 table,
35- } ;
44+ } ) ) ;
3645 s. set_stdin ( Box :: new ( crate :: pipe:: ReadPipe :: new ( std:: io:: empty ( ) ) ) ) ;
3746 s. set_stdout ( Box :: new ( crate :: pipe:: WritePipe :: new ( std:: io:: sink ( ) ) ) ) ;
3847 s. set_stderr ( Box :: new ( crate :: pipe:: WritePipe :: new ( std:: io:: sink ( ) ) ) ) ;
@@ -77,12 +86,22 @@ impl WasiCtx {
7786 & self . table
7887 }
7988
89+ pub fn table_mut ( & mut self ) -> Option < & mut Table > {
90+ Arc :: get_mut ( & mut self . 0 ) . map ( |c| & mut c. table )
91+ }
92+
8093 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 ( ) )
8298 }
8399
84100 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) ) ?;
86105 Ok ( ( ) )
87106 }
88107
@@ -130,3 +149,10 @@ impl WasiCtx {
130149 Ok ( ( ) )
131150 }
132151}
152+
153+ impl Deref for WasiCtx {
154+ type Target = WasiCtxInner ;
155+ fn deref ( & self ) -> & Self :: Target {
156+ & self . 0
157+ }
158+ }
0 commit comments