11mod io;
22
3- use alloc:: sync:: Arc ;
3+ use alloc:: { collections :: BTreeMap , sync:: Arc } ;
44use core:: {
5- sync:: atomic:: { AtomicU64 , Ordering } ,
5+ sync:: atomic:: { AtomicU32 , AtomicU64 , Ordering } ,
66 time:: Duration ,
77} ;
88use std:: {
@@ -11,7 +11,7 @@ use std::{
1111 sync:: Mutex ,
1212} ;
1313
14- use java_runtime:: { File , FileStat , FileType , IOError , IOResult , RT_RUSTJAR , Runtime , SpawnCallback , get_runtime_class_proto} ;
14+ use java_runtime:: { File , FileDescriptorId , FileStat , FileType , IOError , IOResult , RT_RUSTJAR , Runtime , SpawnCallback , get_runtime_class_proto} ;
1515use jvm:: { ClassDefinition , Jvm } ;
1616use jvm_rust:: { ArrayClassDefinitionImpl , ClassDefinitionImpl } ;
1717
5757 T : Sync + Send + Write + ' static ,
5858{
5959 stdout : WriteWrapper < T > ,
60+ file_table : Arc < Mutex < BTreeMap < u32 , Box < dyn File > > > > ,
61+ next_fd : Arc < AtomicU32 > ,
6062}
6163
6264impl < T > RuntimeImpl < T >
6870 stdout : WriteWrapper {
6971 write : Arc :: new ( Mutex :: new ( stdout) ) ,
7072 } ,
73+ file_table : Arc :: new ( Mutex :: new ( BTreeMap :: new ( ) ) ) ,
74+ next_fd : Arc :: new ( AtomicU32 :: new ( 1 ) ) ,
7175 }
7276 }
77+
78+ fn register_file ( & self , file : Box < dyn File > ) -> FileDescriptorId {
79+ let fd = self . next_fd . fetch_add ( 1 , Ordering :: SeqCst ) ;
80+ self . file_table . lock ( ) . unwrap ( ) . insert ( fd, file) ;
81+ FileDescriptorId :: new ( fd)
82+ }
7383}
7484
7585#[ async_trait:: async_trait]
@@ -104,20 +114,32 @@ where
104114 TASK_ID . try_with ( |x| * x) . unwrap_or ( 0 )
105115 }
106116
107- fn stdin ( & self ) -> IOResult < Box < dyn File > > {
108- Ok ( Box :: new ( InputStreamFile :: new ( stdin ( ) ) ) )
117+ fn stdin ( & self ) -> IOResult < FileDescriptorId > {
118+ let file = Box :: new ( InputStreamFile :: new ( stdin ( ) ) ) ;
119+ Ok ( self . register_file ( file) )
120+ }
121+
122+ fn stdout ( & self ) -> IOResult < FileDescriptorId > {
123+ let file = Box :: new ( WriteStreamFile :: new ( self . stdout . clone ( ) ) ) ;
124+ Ok ( self . register_file ( file) )
109125 }
110126
111- fn stdout ( & self ) -> IOResult < Box < dyn File > > {
112- Ok ( Box :: new ( WriteStreamFile :: new ( self . stdout . clone ( ) ) ) )
127+ fn stderr ( & self ) -> IOResult < FileDescriptorId > {
128+ let file = Box :: new ( WriteStreamFile :: new ( stderr ( ) ) ) ;
129+ Ok ( self . register_file ( file) )
113130 }
114131
115- fn stderr ( & self ) -> IOResult < Box < dyn File > > {
116- Ok ( Box :: new ( WriteStreamFile :: new ( stderr ( ) ) ) )
132+ async fn open ( & self , path : & str , write : bool ) -> IOResult < FileDescriptorId > {
133+ let file = Box :: new ( FileImpl :: new ( path, write) ) ;
134+ Ok ( self . register_file ( file) )
117135 }
118136
119- async fn open ( & self , path : & str , write : bool ) -> IOResult < Box < dyn File > > {
120- Ok ( Box :: new ( FileImpl :: new ( path, write) ) )
137+ fn get_file ( & self , fd : FileDescriptorId ) -> IOResult < Box < dyn File > > {
138+ self . file_table . lock ( ) . unwrap ( ) . get ( & fd. id ( ) ) . cloned ( ) . ok_or ( IOError :: NotFound )
139+ }
140+
141+ fn close_file ( & self , fd : FileDescriptorId ) {
142+ self . file_table . lock ( ) . unwrap ( ) . remove ( & fd. id ( ) ) ;
121143 }
122144
123145 async fn unlink ( & self , path : & str ) -> IOResult < ( ) > {
@@ -166,6 +188,10 @@ where
166188 T : Sync + Send + Write + ' static ,
167189{
168190 fn clone ( & self ) -> Self {
169- Self { stdout : self . stdout . clone ( ) }
191+ Self {
192+ stdout : self . stdout . clone ( ) ,
193+ file_table : self . file_table . clone ( ) ,
194+ next_fd : self . next_fd . clone ( ) ,
195+ }
170196 }
171197}
0 commit comments