@@ -5,6 +5,7 @@ use is_terminal::IsTerminal;
5
5
use std:: any:: Any ;
6
6
use std:: convert:: TryInto ;
7
7
use std:: io;
8
+ use std:: sync:: { Arc , RwLock , RwLockReadGuard } ;
8
9
use system_interface:: {
9
10
fs:: { FileIoExt , GetSetFdFlags } ,
10
11
io:: { IoExt , ReadReady } ,
@@ -14,11 +15,48 @@ use wasi_common::{
14
15
Error , ErrorExt ,
15
16
} ;
16
17
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 > ) ;
18
52
19
53
impl File {
20
54
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 ( ) )
22
60
}
23
61
}
24
62
@@ -27,45 +65,49 @@ impl WasiFile for File {
27
65
fn as_any ( & self ) -> & dyn Any {
28
66
self
29
67
}
68
+
30
69
#[ 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 ( ) ) )
33
72
}
34
73
35
74
#[ 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 ( ) ) ) )
38
77
}
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 ( ) ?;
41
81
Ok ( ( ) )
42
82
}
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 ( ) ?;
45
85
Ok ( ( ) )
46
86
}
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 ( ) ?;
49
89
Ok ( filetype_from ( & meta. file_type ( ) ) )
50
90
}
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) ?;
53
94
Ok ( fdflags)
54
95
}
55
- async fn set_fdflags ( & mut self , fdflags : FdFlags ) -> Result < ( ) , Error > {
96
+ async fn set_fdflags ( & self , fdflags : FdFlags ) -> Result < ( ) , Error > {
56
97
if fdflags. intersects (
57
98
wasi_common:: file:: FdFlags :: DSYNC
58
99
| wasi_common:: file:: FdFlags :: SYNC
59
100
| wasi_common:: file:: FdFlags :: RSYNC ,
60
101
) {
61
102
return Err ( Error :: invalid_argument ( ) . context ( "cannot set DSYNC, SYNC, or RSYNC flag" ) ) ;
62
103
}
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) ?;
65
107
Ok ( ( ) )
66
108
}
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 ( ) ?;
69
111
Ok ( Filestat {
70
112
device_id : meta. dev ( ) ,
71
113
inode : meta. ino ( ) ,
@@ -77,63 +119,68 @@ impl WasiFile for File {
77
119
ctim : meta. created ( ) . map ( |t| Some ( t. into_std ( ) ) ) . unwrap_or ( None ) ,
78
120
} )
79
121
}
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) ?;
82
124
Ok ( ( ) )
83
125
}
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) ) ?;
86
131
Ok ( ( ) )
87
132
}
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) ?;
90
135
Ok ( ( ) )
91
136
}
92
137
async fn set_times (
93
- & mut self ,
138
+ & self ,
94
139
atime : Option < wasi_common:: SystemTimeSpec > ,
95
140
mtime : Option < wasi_common:: SystemTimeSpec > ,
96
141
) -> Result < ( ) , Error > {
97
142
self . 0
143
+ . read ( )
144
+ . unwrap ( )
98
145
. set_times ( convert_systimespec ( atime) , convert_systimespec ( mtime) ) ?;
99
146
Ok ( ( ) )
100
147
}
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) ?;
103
150
Ok ( n. try_into ( ) ?)
104
151
}
105
152
async fn read_vectored_at < ' a > (
106
- & mut self ,
153
+ & self ,
107
154
bufs : & mut [ io:: IoSliceMut < ' a > ] ,
108
155
offset : u64 ,
109
156
) -> 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) ?;
111
158
Ok ( n. try_into ( ) ?)
112
159
}
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) ?;
115
162
Ok ( n. try_into ( ) ?)
116
163
}
117
164
async fn write_vectored_at < ' a > (
118
- & mut self ,
165
+ & self ,
119
166
bufs : & [ io:: IoSlice < ' a > ] ,
120
167
offset : u64 ,
121
168
) -> 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) ?;
123
170
Ok ( n. try_into ( ) ?)
124
171
}
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) ?)
127
174
}
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) ?;
130
177
Ok ( n. try_into ( ) ?)
131
178
}
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 ( ) ?)
134
181
}
135
- fn isatty ( & mut self ) -> bool {
136
- self . 0 . is_terminal ( )
182
+ fn isatty ( & self ) -> bool {
183
+ self . 0 . read ( ) . unwrap ( ) . is_terminal ( )
137
184
}
138
185
}
139
186
@@ -160,35 +207,6 @@ pub fn filetype_from(ft: &cap_std::fs::FileType) -> FileType {
160
207
}
161
208
}
162
209
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
-
192
210
pub ( crate ) fn convert_systimespec (
193
211
t : Option < wasi_common:: SystemTimeSpec > ,
194
212
) -> Option < SystemTimeSpec > {
0 commit comments