@@ -74,9 +74,8 @@ use crate::p2::bindings::{
74
74
} ;
75
75
use crate :: p2:: { FsError , IsATTY , WasiCtx , WasiImpl , WasiView } ;
76
76
use anyhow:: { Context , bail} ;
77
- use std:: collections:: { BTreeMap , HashSet } ;
77
+ use std:: collections:: { BTreeMap , BTreeSet , HashSet , btree_map } ;
78
78
use std:: mem:: { self , size_of, size_of_val} ;
79
- use std:: ops:: { Deref , DerefMut } ;
80
79
use std:: slice;
81
80
use std:: sync:: Arc ;
82
81
use std:: sync:: atomic:: { AtomicU64 , Ordering } ;
@@ -286,21 +285,7 @@ struct WasiPreview1Adapter {
286
285
#[ derive( Debug , Default ) ]
287
286
struct Descriptors {
288
287
used : BTreeMap < u32 , Descriptor > ,
289
- free : Vec < u32 > ,
290
- }
291
-
292
- impl Deref for Descriptors {
293
- type Target = BTreeMap < u32 , Descriptor > ;
294
-
295
- fn deref ( & self ) -> & Self :: Target {
296
- & self . used
297
- }
298
- }
299
-
300
- impl DerefMut for Descriptors {
301
- fn deref_mut ( & mut self ) -> & mut Self :: Target {
302
- & mut self . used
303
- }
288
+ free : BTreeSet < u32 > ,
304
289
}
305
290
306
291
impl Descriptors {
@@ -377,42 +362,34 @@ impl Descriptors {
377
362
378
363
/// Returns next descriptor number, which was never assigned
379
364
fn unused ( & self ) -> Result < u32 > {
380
- match self . last_key_value ( ) {
365
+ match self . used . last_key_value ( ) {
381
366
Some ( ( fd, _) ) => {
382
367
if let Some ( fd) = fd. checked_add ( 1 ) {
383
368
return Ok ( fd) ;
384
369
}
385
- if self . len ( ) == u32:: MAX as usize {
370
+ if self . used . len ( ) == u32:: MAX as usize {
386
371
return Err ( types:: Errno :: Loop . into ( ) ) ;
387
372
}
388
373
// TODO: Optimize
389
374
Ok ( ( 0 ..u32:: MAX )
390
375
. rev ( )
391
- . find ( |fd| !self . contains_key ( fd) )
376
+ . find ( |fd| !self . used . contains_key ( fd) )
392
377
. expect ( "failed to find an unused file descriptor" ) )
393
378
}
394
379
None => Ok ( 0 ) ,
395
380
}
396
381
}
397
382
398
- /// Removes the [Descriptor] corresponding to `fd`
399
- fn remove ( & mut self , fd : types:: Fd ) -> Option < Descriptor > {
400
- let fd = fd. into ( ) ;
401
- let desc = self . used . remove ( & fd) ?;
402
- self . free . push ( fd) ;
403
- Some ( desc)
404
- }
405
-
406
383
/// Pushes the [Descriptor] returning corresponding number.
407
384
/// This operation will try to reuse numbers previously removed via [`Self::remove`]
408
385
/// and rely on [`Self::unused`] if no free numbers are recorded
409
386
fn push ( & mut self , desc : Descriptor ) -> Result < u32 > {
410
- let fd = if let Some ( fd) = self . free . pop ( ) {
387
+ let fd = if let Some ( fd) = self . free . pop_last ( ) {
411
388
fd
412
389
} else {
413
390
self . unused ( ) ?
414
391
} ;
415
- assert ! ( self . insert( fd, desc) . is_none( ) ) ;
392
+ assert ! ( self . used . insert( fd, desc) . is_none( ) ) ;
416
393
Ok ( fd)
417
394
}
418
395
}
@@ -453,15 +430,15 @@ impl Transaction<'_> {
453
430
/// Returns [`types::Errno::Badf`] if no [`Descriptor`] is found
454
431
fn get_descriptor ( & self , fd : types:: Fd ) -> Result < & Descriptor > {
455
432
let fd = fd. into ( ) ;
456
- let desc = self . descriptors . get ( & fd) . ok_or ( types:: Errno :: Badf ) ?;
433
+ let desc = self . descriptors . used . get ( & fd) . ok_or ( types:: Errno :: Badf ) ?;
457
434
Ok ( desc)
458
435
}
459
436
460
437
/// Borrows [`File`] corresponding to `fd`
461
438
/// if it describes a [`Descriptor::File`]
462
439
fn get_file ( & self , fd : types:: Fd ) -> Result < & File > {
463
440
let fd = fd. into ( ) ;
464
- match self . descriptors . get ( & fd) {
441
+ match self . descriptors . used . get ( & fd) {
465
442
Some ( Descriptor :: File ( file) ) => Ok ( file) ,
466
443
_ => Err ( types:: Errno :: Badf . into ( ) ) ,
467
444
}
@@ -471,7 +448,7 @@ impl Transaction<'_> {
471
448
/// if it describes a [`Descriptor::File`]
472
449
fn get_file_mut ( & mut self , fd : types:: Fd ) -> Result < & mut File > {
473
450
let fd = fd. into ( ) ;
474
- match self . descriptors . get_mut ( & fd) {
451
+ match self . descriptors . used . get_mut ( & fd) {
475
452
Some ( Descriptor :: File ( file) ) => Ok ( file) ,
476
453
_ => Err ( types:: Errno :: Badf . into ( ) ) ,
477
454
}
@@ -485,7 +462,7 @@ impl Transaction<'_> {
485
462
/// Returns [`types::Errno::Spipe`] if the descriptor corresponds to stdio
486
463
fn get_seekable ( & self , fd : types:: Fd ) -> Result < & File > {
487
464
let fd = fd. into ( ) ;
488
- match self . descriptors . get ( & fd) {
465
+ match self . descriptors . used . get ( & fd) {
489
466
Some ( Descriptor :: File ( file) ) => Ok ( file) ,
490
467
Some (
491
468
Descriptor :: Stdin { .. } | Descriptor :: Stdout { .. } | Descriptor :: Stderr { .. } ,
@@ -518,7 +495,7 @@ impl Transaction<'_> {
518
495
/// if it describes a [`Descriptor::Directory`]
519
496
fn get_dir_fd ( & self , fd : types:: Fd ) -> Result < Resource < filesystem:: Descriptor > > {
520
497
let fd = fd. into ( ) ;
521
- match self . descriptors . get ( & fd) {
498
+ match self . descriptors . used . get ( & fd) {
522
499
Some ( Descriptor :: Directory { fd, .. } ) => Ok ( fd. borrowed ( ) ) ,
523
500
_ => Err ( types:: Errno :: Badf . into ( ) ) ,
524
501
}
@@ -1327,11 +1304,13 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
1327
1304
_memory : & mut GuestMemory < ' _ > ,
1328
1305
fd : types:: Fd ,
1329
1306
) -> Result < ( ) , types:: Error > {
1330
- let desc = self
1331
- . transact ( ) ?
1332
- . descriptors
1333
- . remove ( fd)
1334
- . ok_or ( types:: Errno :: Badf ) ?;
1307
+ let desc = {
1308
+ let fd = fd. into ( ) ;
1309
+ let mut st = self . transact ( ) ?;
1310
+ let desc = st. descriptors . used . remove ( & fd) . ok_or ( types:: Errno :: Badf ) ?;
1311
+ st. descriptors . free . insert ( fd) ;
1312
+ desc
1313
+ } ;
1335
1314
match desc {
1336
1315
Descriptor :: Stdin { stream, .. } => {
1337
1316
streams:: HostInputStream :: drop ( & mut self . as_io_impl ( ) , stream)
@@ -1830,8 +1809,17 @@ impl wasi_snapshot_preview1::WasiSnapshotPreview1 for WasiP1Ctx {
1830
1809
to : types:: Fd ,
1831
1810
) -> Result < ( ) , types:: Error > {
1832
1811
let mut st = self . transact ( ) ?;
1833
- let desc = st. descriptors . remove ( from) . ok_or ( types:: Errno :: Badf ) ?;
1834
- st. descriptors . insert ( to. into ( ) , desc) ;
1812
+ let from = from. into ( ) ;
1813
+ let btree_map:: Entry :: Occupied ( desc) = st. descriptors . used . entry ( from) else {
1814
+ return Err ( types:: Errno :: Badf . into ( ) ) ;
1815
+ } ;
1816
+ let to = to. into ( ) ;
1817
+ if from != to {
1818
+ let desc = desc. remove ( ) ;
1819
+ st. descriptors . free . insert ( from) ;
1820
+ st. descriptors . free . remove ( & to) ;
1821
+ st. descriptors . used . insert ( to, desc) ;
1822
+ }
1835
1823
Ok ( ( ) )
1836
1824
}
1837
1825
0 commit comments