@@ -5,6 +5,7 @@ use is_terminal::IsTerminal;
55use std:: any:: Any ;
66use std:: convert:: TryInto ;
77use std:: io;
8+ use std:: sync:: { Arc , RwLock , RwLockReadGuard } ;
89use system_interface:: {
910 fs:: { FileIoExt , GetSetFdFlags } ,
1011 io:: { IoExt , ReadReady } ,
@@ -14,11 +15,48 @@ use wasi_common::{
1415 Error , ErrorExt ,
1516} ;
1617
17- pub struct File ( cap_std:: fs:: File ) ;
18+ #[ cfg( unix) ]
19+ use io_lifetimes:: { AsFd , BorrowedFd } ;
20+
21+ #[ cfg( windows) ]
22+ use io_lifetimes:: { AsHandle , BorrowedHandle } ;
23+
24+ #[ cfg( windows) ]
25+ use io_extras:: os:: windows:: { AsRawHandleOrSocket , RawHandleOrSocket } ;
26+
27+ pub struct BorrowedFile < ' a > ( RwLockReadGuard < ' a , cap_std:: fs:: File > ) ;
28+
29+ #[ cfg( unix) ]
30+ impl AsFd for BorrowedFile < ' _ > {
31+ fn as_fd ( & self ) -> BorrowedFd < ' _ > {
32+ self . 0 . as_fd ( )
33+ }
34+ }
35+
36+ #[ cfg( windows) ]
37+ impl AsHandle for BorrowedFile < ' _ > {
38+ fn as_handle ( & self ) -> BorrowedHandle < ' _ > {
39+ self . 0 . as_handle ( )
40+ }
41+ }
42+
43+ #[ cfg( windows) ]
44+ impl AsRawHandleOrSocket for BorrowedFile < ' _ > {
45+ #[ inline]
46+ fn as_raw_handle_or_socket ( & self ) -> RawHandleOrSocket {
47+ self . 0 . as_raw_handle_or_socket ( )
48+ }
49+ }
50+
51+ pub struct File ( RwLock < cap_std:: fs:: File > ) ;
1852
1953impl File {
2054 pub fn from_cap_std ( file : cap_std:: fs:: File ) -> Self {
21- File ( file)
55+ File ( RwLock :: new ( file) )
56+ }
57+
58+ pub fn borrow ( & self ) -> BorrowedFile {
59+ BorrowedFile ( self . 0 . read ( ) . unwrap ( ) )
2260 }
2361}
2462
@@ -27,45 +65,49 @@ impl WasiFile for File {
2765 fn as_any ( & self ) -> & dyn Any {
2866 self
2967 }
68+
3069 #[ cfg( unix) ]
31- fn pollable ( & self ) -> Option < rustix :: fd :: BorrowedFd > {
32- Some ( self . 0 . as_fd ( ) )
70+ fn pollable ( & self ) -> Option < Arc < dyn AsFd + ' _ > > {
71+ Some ( Arc :: new ( self . borrow ( ) ) )
3372 }
3473
3574 #[ cfg( windows) ]
36- fn pollable ( & self ) -> Option < io_extras :: os :: windows :: RawHandleOrSocket > {
37- Some ( self . 0 . as_raw_handle_or_socket ( ) )
75+ fn pollable ( & self ) -> Option < Arc < dyn AsRawHandleOrSocket + ' _ > > {
76+ Some ( Arc :: new ( BorrowedFile ( self . 0 . read ( ) . unwrap ( ) ) ) )
3877 }
39- async fn datasync ( & mut self ) -> Result < ( ) , Error > {
40- self . 0 . sync_data ( ) ?;
78+
79+ async fn datasync ( & self ) -> Result < ( ) , Error > {
80+ self . 0 . read ( ) . unwrap ( ) . sync_data ( ) ?;
4181 Ok ( ( ) )
4282 }
43- async fn sync ( & mut self ) -> Result < ( ) , Error > {
44- self . 0 . sync_all ( ) ?;
83+ async fn sync ( & self ) -> Result < ( ) , Error > {
84+ self . 0 . read ( ) . unwrap ( ) . sync_all ( ) ?;
4585 Ok ( ( ) )
4686 }
47- async fn get_filetype ( & mut self ) -> Result < FileType , Error > {
48- let meta = self . 0 . metadata ( ) ?;
87+ async fn get_filetype ( & self ) -> Result < FileType , Error > {
88+ let meta = self . 0 . read ( ) . unwrap ( ) . metadata ( ) ?;
4989 Ok ( filetype_from ( & meta. file_type ( ) ) )
5090 }
51- async fn get_fdflags ( & mut self ) -> Result < FdFlags , Error > {
52- let fdflags = get_fd_flags ( & self . 0 ) ?;
91+ async fn get_fdflags ( & self ) -> Result < FdFlags , Error > {
92+ let file = self . 0 . read ( ) . unwrap ( ) ;
93+ let fdflags = get_fd_flags ( & * file) ?;
5394 Ok ( fdflags)
5495 }
55- async fn set_fdflags ( & mut self , fdflags : FdFlags ) -> Result < ( ) , Error > {
96+ async fn set_fdflags ( & self , fdflags : FdFlags ) -> Result < ( ) , Error > {
5697 if fdflags. intersects (
5798 wasi_common:: file:: FdFlags :: DSYNC
5899 | wasi_common:: file:: FdFlags :: SYNC
59100 | wasi_common:: file:: FdFlags :: RSYNC ,
60101 ) {
61102 return Err ( Error :: invalid_argument ( ) . context ( "cannot set DSYNC, SYNC, or RSYNC flag" ) ) ;
62103 }
63- let set_fd_flags = self . 0 . new_set_fd_flags ( to_sysif_fdflags ( fdflags) ) ?;
64- self . 0 . set_fd_flags ( set_fd_flags) ?;
104+ let mut file = self . 0 . write ( ) . unwrap ( ) ;
105+ let set_fd_flags = ( * file) . new_set_fd_flags ( to_sysif_fdflags ( fdflags) ) ?;
106+ ( * file) . set_fd_flags ( set_fd_flags) ?;
65107 Ok ( ( ) )
66108 }
67- async fn get_filestat ( & mut self ) -> Result < Filestat , Error > {
68- let meta = self . 0 . metadata ( ) ?;
109+ async fn get_filestat ( & self ) -> Result < Filestat , Error > {
110+ let meta = self . 0 . read ( ) . unwrap ( ) . metadata ( ) ?;
69111 Ok ( Filestat {
70112 device_id : meta. dev ( ) ,
71113 inode : meta. ino ( ) ,
@@ -77,63 +119,68 @@ impl WasiFile for File {
77119 ctim : meta. created ( ) . map ( |t| Some ( t. into_std ( ) ) ) . unwrap_or ( None ) ,
78120 } )
79121 }
80- async fn set_filestat_size ( & mut self , size : u64 ) -> Result < ( ) , Error > {
81- self . 0 . set_len ( size) ?;
122+ async fn set_filestat_size ( & self , size : u64 ) -> Result < ( ) , Error > {
123+ self . 0 . read ( ) . unwrap ( ) . set_len ( size) ?;
82124 Ok ( ( ) )
83125 }
84- async fn advise ( & mut self , offset : u64 , len : u64 , advice : Advice ) -> Result < ( ) , Error > {
85- self . 0 . advise ( offset, len, convert_advice ( advice) ) ?;
126+ async fn advise ( & self , offset : u64 , len : u64 , advice : Advice ) -> Result < ( ) , Error > {
127+ self . 0
128+ . read ( )
129+ . unwrap ( )
130+ . advise ( offset, len, convert_advice ( advice) ) ?;
86131 Ok ( ( ) )
87132 }
88- async fn allocate ( & mut self , offset : u64 , len : u64 ) -> Result < ( ) , Error > {
89- self . 0 . allocate ( offset, len) ?;
133+ async fn allocate ( & self , offset : u64 , len : u64 ) -> Result < ( ) , Error > {
134+ self . 0 . read ( ) . unwrap ( ) . allocate ( offset, len) ?;
90135 Ok ( ( ) )
91136 }
92137 async fn set_times (
93- & mut self ,
138+ & self ,
94139 atime : Option < wasi_common:: SystemTimeSpec > ,
95140 mtime : Option < wasi_common:: SystemTimeSpec > ,
96141 ) -> Result < ( ) , Error > {
97142 self . 0
143+ . read ( )
144+ . unwrap ( )
98145 . set_times ( convert_systimespec ( atime) , convert_systimespec ( mtime) ) ?;
99146 Ok ( ( ) )
100147 }
101- async fn read_vectored < ' a > ( & mut self , bufs : & mut [ io:: IoSliceMut < ' a > ] ) -> Result < u64 , Error > {
102- let n = self . 0 . read_vectored ( bufs) ?;
148+ async fn read_vectored < ' a > ( & self , bufs : & mut [ io:: IoSliceMut < ' a > ] ) -> Result < u64 , Error > {
149+ let n = self . 0 . read ( ) . unwrap ( ) . read_vectored ( bufs) ?;
103150 Ok ( n. try_into ( ) ?)
104151 }
105152 async fn read_vectored_at < ' a > (
106- & mut self ,
153+ & self ,
107154 bufs : & mut [ io:: IoSliceMut < ' a > ] ,
108155 offset : u64 ,
109156 ) -> Result < u64 , Error > {
110- let n = self . 0 . read_vectored_at ( bufs, offset) ?;
157+ let n = self . 0 . read ( ) . unwrap ( ) . read_vectored_at ( bufs, offset) ?;
111158 Ok ( n. try_into ( ) ?)
112159 }
113- async fn write_vectored < ' a > ( & mut self , bufs : & [ io:: IoSlice < ' a > ] ) -> Result < u64 , Error > {
114- let n = self . 0 . write_vectored ( bufs) ?;
160+ async fn write_vectored < ' a > ( & self , bufs : & [ io:: IoSlice < ' a > ] ) -> Result < u64 , Error > {
161+ let n = self . 0 . read ( ) . unwrap ( ) . write_vectored ( bufs) ?;
115162 Ok ( n. try_into ( ) ?)
116163 }
117164 async fn write_vectored_at < ' a > (
118- & mut self ,
165+ & self ,
119166 bufs : & [ io:: IoSlice < ' a > ] ,
120167 offset : u64 ,
121168 ) -> Result < u64 , Error > {
122- let n = self . 0 . write_vectored_at ( bufs, offset) ?;
169+ let n = self . 0 . read ( ) . unwrap ( ) . write_vectored_at ( bufs, offset) ?;
123170 Ok ( n. try_into ( ) ?)
124171 }
125- async fn seek ( & mut self , pos : std:: io:: SeekFrom ) -> Result < u64 , Error > {
126- Ok ( self . 0 . seek ( pos) ?)
172+ async fn seek ( & self , pos : std:: io:: SeekFrom ) -> Result < u64 , Error > {
173+ Ok ( self . 0 . read ( ) . unwrap ( ) . seek ( pos) ?)
127174 }
128- async fn peek ( & mut self , buf : & mut [ u8 ] ) -> Result < u64 , Error > {
129- let n = self . 0 . peek ( buf) ?;
175+ async fn peek ( & self , buf : & mut [ u8 ] ) -> Result < u64 , Error > {
176+ let n = self . 0 . read ( ) . unwrap ( ) . peek ( buf) ?;
130177 Ok ( n. try_into ( ) ?)
131178 }
132- async fn num_ready_bytes ( & self ) -> Result < u64 , Error > {
133- Ok ( self . 0 . num_ready_bytes ( ) ?)
179+ fn num_ready_bytes ( & self ) -> Result < u64 , Error > {
180+ Ok ( self . 0 . read ( ) . unwrap ( ) . num_ready_bytes ( ) ?)
134181 }
135- fn isatty ( & mut self ) -> bool {
136- self . 0 . is_terminal ( )
182+ fn isatty ( & self ) -> bool {
183+ self . 0 . read ( ) . unwrap ( ) . is_terminal ( )
137184 }
138185}
139186
@@ -160,35 +207,6 @@ pub fn filetype_from(ft: &cap_std::fs::FileType) -> FileType {
160207 }
161208}
162209
163- #[ cfg( windows) ]
164- use io_lifetimes:: { AsHandle , BorrowedHandle } ;
165- #[ cfg( windows) ]
166- impl AsHandle for File {
167- fn as_handle ( & self ) -> BorrowedHandle < ' _ > {
168- self . 0 . as_handle ( )
169- }
170- }
171-
172- #[ cfg( windows) ]
173- use io_extras:: os:: windows:: { AsRawHandleOrSocket , RawHandleOrSocket } ;
174- #[ cfg( windows) ]
175- impl AsRawHandleOrSocket for File {
176- #[ inline]
177- fn as_raw_handle_or_socket ( & self ) -> RawHandleOrSocket {
178- self . 0 . as_raw_handle_or_socket ( )
179- }
180- }
181-
182- #[ cfg( unix) ]
183- use io_lifetimes:: { AsFd , BorrowedFd } ;
184-
185- #[ cfg( unix) ]
186- impl AsFd for File {
187- fn as_fd ( & self ) -> BorrowedFd < ' _ > {
188- self . 0 . as_fd ( )
189- }
190- }
191-
192210pub ( crate ) fn convert_systimespec (
193211 t : Option < wasi_common:: SystemTimeSpec > ,
194212) -> Option < SystemTimeSpec > {
0 commit comments