1
- use std:: cell:: { Cell , RefCell } ;
2
1
use std:: ffi;
3
2
use std:: fs:: File ;
4
3
use std:: fs:: OpenOptions ;
@@ -7,10 +6,12 @@ use std::io::{self, ErrorKind, Read, Write};
7
6
use std:: os:: unix:: fs:: OpenOptionsExt ;
8
7
#[ cfg( windows) ]
9
8
use std:: os:: windows:: fs:: OpenOptionsExt ;
9
+ use std:: sync:: RwLock ;
10
10
use std:: time:: { Duration , SystemTime } ;
11
11
use std:: { env, fs} ;
12
12
13
13
use bitflags:: bitflags;
14
+ use crossbeam_utils:: atomic:: AtomicCell ;
14
15
#[ cfg( unix) ]
15
16
use nix:: errno:: Errno ;
16
17
#[ cfg( all( unix, not( target_os = "redox" ) ) ) ]
@@ -35,8 +36,8 @@ use crate::obj::objstr::{PyString, PyStringRef};
35
36
use crate :: obj:: objtuple:: PyTupleRef ;
36
37
use crate :: obj:: objtype:: PyClassRef ;
37
38
use crate :: pyobject:: {
38
- Either , ItemProtocol , PyClassImpl , PyObjectRef , PyRef , PyResult , PyValue , TryFromObject ,
39
- TypeProtocol ,
39
+ Either , ItemProtocol , PyClassImpl , PyObjectRef , PyRef , PyResult , PyValue , ThreadSafe ,
40
+ TryFromObject , TypeProtocol ,
40
41
} ;
41
42
use crate :: vm:: VirtualMachine ;
42
43
@@ -597,6 +598,8 @@ struct DirEntry {
597
598
mode : OutputMode ,
598
599
}
599
600
601
+ impl ThreadSafe for DirEntry { }
602
+
600
603
type DirEntryRef = PyRef < DirEntry > ;
601
604
602
605
impl PyValue for DirEntry {
@@ -683,11 +686,13 @@ impl DirEntryRef {
683
686
#[ pyclass]
684
687
#[ derive( Debug ) ]
685
688
struct ScandirIterator {
686
- entries : RefCell < fs:: ReadDir > ,
687
- exhausted : Cell < bool > ,
689
+ entries : RwLock < fs:: ReadDir > ,
690
+ exhausted : AtomicCell < bool > ,
688
691
mode : OutputMode ,
689
692
}
690
693
694
+ impl ThreadSafe for ScandirIterator { }
695
+
691
696
impl PyValue for ScandirIterator {
692
697
fn class ( vm : & VirtualMachine ) -> PyClassRef {
693
698
vm. class ( MODULE_NAME , "ScandirIter" )
@@ -698,11 +703,11 @@ impl PyValue for ScandirIterator {
698
703
impl ScandirIterator {
699
704
#[ pymethod( name = "__next__" ) ]
700
705
fn next ( & self , vm : & VirtualMachine ) -> PyResult {
701
- if self . exhausted . get ( ) {
706
+ if self . exhausted . load ( ) {
702
707
return Err ( objiter:: new_stop_iteration ( vm) ) ;
703
708
}
704
709
705
- match self . entries . borrow_mut ( ) . next ( ) {
710
+ match self . entries . write ( ) . unwrap ( ) . next ( ) {
706
711
Some ( entry) => match entry {
707
712
Ok ( entry) => Ok ( DirEntry {
708
713
entry,
@@ -713,15 +718,15 @@ impl ScandirIterator {
713
718
Err ( s) => Err ( convert_io_error ( vm, s) ) ,
714
719
} ,
715
720
None => {
716
- self . exhausted . set ( true ) ;
721
+ self . exhausted . store ( true ) ;
717
722
Err ( objiter:: new_stop_iteration ( vm) )
718
723
}
719
724
}
720
725
}
721
726
722
727
#[ pymethod]
723
728
fn close ( & self ) {
724
- self . exhausted . set ( true ) ;
729
+ self . exhausted . store ( true ) ;
725
730
}
726
731
727
732
#[ pymethod( name = "__iter__" ) ]
@@ -748,8 +753,8 @@ fn os_scandir(path: OptionalArg<PyPathLike>, vm: &VirtualMachine) -> PyResult {
748
753
749
754
match fs:: read_dir ( path. path ) {
750
755
Ok ( iter) => Ok ( ScandirIterator {
751
- entries : RefCell :: new ( iter) ,
752
- exhausted : Cell :: new ( false ) ,
756
+ entries : RwLock :: new ( iter) ,
757
+ exhausted : AtomicCell :: new ( false ) ,
753
758
mode : path. mode ,
754
759
}
755
760
. into_ref ( vm)
0 commit comments