Skip to content

Commit 1238fbf

Browse files
committed
Add fd table to RuntimeImpl and TestRuntime
1 parent 0084673 commit 1238fbf

File tree

2 files changed

+83
-23
lines changed

2 files changed

+83
-23
lines changed

src/runtime.rs

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
mod io;
22

3-
use alloc::sync::Arc;
3+
use alloc::{collections::BTreeMap, sync::Arc};
44
use core::{
5-
sync::atomic::{AtomicU64, Ordering},
5+
sync::atomic::{AtomicU32, AtomicU64, Ordering},
66
time::Duration,
77
};
88
use 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};
1515
use jvm::{ClassDefinition, Jvm};
1616
use jvm_rust::{ArrayClassDefinitionImpl, ClassDefinitionImpl};
1717

@@ -57,6 +57,8 @@ where
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

6264
impl<T> RuntimeImpl<T>
@@ -68,8 +70,16 @@ where
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
}

test_utils/src/lib.rs

Lines changed: 45 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,53 @@
11
extern crate alloc;
22

3-
use alloc::{boxed::Box, collections::BTreeMap, string::String, vec::Vec};
3+
use alloc::{boxed::Box, collections::BTreeMap, string::String, sync::Arc, vec::Vec};
44
use core::{
55
cmp::min,
6-
sync::atomic::{AtomicU64, Ordering},
6+
sync::atomic::{AtomicU32, AtomicU64, Ordering},
77
time::Duration,
88
};
9-
use std::time::{SystemTime, UNIX_EPOCH};
9+
use std::{
10+
sync::Mutex,
11+
time::{SystemTime, UNIX_EPOCH},
12+
};
1013

1114
use jvm::{ClassDefinition, Jvm, Result};
1215
use jvm_rust::{ArrayClassDefinitionImpl, ClassDefinitionImpl};
1316

1417
use java_runtime::{
15-
File, FileSize, FileStat, FileType, IOError, IOResult, RT_RUSTJAR, Runtime, SpawnCallback, get_bootstrap_class_loader, get_runtime_class_proto,
18+
File, FileDescriptorId, FileSize, FileStat, FileType, IOError, IOResult, RT_RUSTJAR, Runtime, SpawnCallback, get_bootstrap_class_loader,
19+
get_runtime_class_proto,
1620
};
1721

18-
#[derive(Clone)]
1922
pub struct TestRuntime {
2023
filesystem: BTreeMap<String, Vec<u8>>,
24+
file_table: Arc<Mutex<BTreeMap<u32, Box<dyn File>>>>,
25+
next_fd: Arc<AtomicU32>,
26+
}
27+
28+
impl Clone for TestRuntime {
29+
fn clone(&self) -> Self {
30+
Self {
31+
filesystem: self.filesystem.clone(),
32+
file_table: self.file_table.clone(),
33+
next_fd: self.next_fd.clone(),
34+
}
35+
}
2136
}
2237

2338
impl TestRuntime {
2439
pub fn new(filesystem: BTreeMap<String, Vec<u8>>) -> Self {
25-
Self { filesystem }
40+
Self {
41+
filesystem,
42+
file_table: Arc::new(Mutex::new(BTreeMap::new())),
43+
next_fd: Arc::new(AtomicU32::new(1)),
44+
}
45+
}
46+
47+
fn register_file(&self, file: Box<dyn File>) -> FileDescriptorId {
48+
let fd = self.next_fd.fetch_add(1, Ordering::SeqCst);
49+
self.file_table.lock().unwrap().insert(fd, file);
50+
FileDescriptorId::new(fd as u32)
2651
}
2752
}
2853

@@ -61,27 +86,36 @@ impl Runtime for TestRuntime {
6186
TASK_ID.try_with(|x| *x).unwrap_or(0)
6287
}
6388

64-
fn stdin(&self) -> IOResult<Box<dyn File>> {
89+
fn stdin(&self) -> IOResult<FileDescriptorId> {
6590
Err(IOError::NotFound)
6691
}
6792

68-
fn stdout(&self) -> IOResult<Box<dyn File>> {
93+
fn stdout(&self) -> IOResult<FileDescriptorId> {
6994
Err(IOError::NotFound)
7095
}
7196

72-
fn stderr(&self) -> IOResult<Box<dyn File>> {
97+
fn stderr(&self) -> IOResult<FileDescriptorId> {
7398
Err(IOError::NotFound)
7499
}
75100

76-
async fn open(&self, path: &str, _write: bool) -> IOResult<Box<dyn File>> {
101+
async fn open(&self, path: &str, _write: bool) -> IOResult<FileDescriptorId> {
77102
let entry = self.filesystem.get(path);
78103
if let Some(data) = entry {
79-
Ok(Box::new(DummyFile::new(data.clone())) as Box<_>)
104+
let file = Box::new(DummyFile::new(data.clone())) as Box<dyn File>;
105+
Ok(self.register_file(file))
80106
} else {
81107
Err(IOError::NotFound)
82108
}
83109
}
84110

111+
fn get_file(&self, fd: FileDescriptorId) -> IOResult<Box<dyn File>> {
112+
self.file_table.lock().unwrap().get(&fd.id()).cloned().ok_or(IOError::NotFound)
113+
}
114+
115+
fn close_file(&self, fd: FileDescriptorId) {
116+
self.file_table.lock().unwrap().remove(&fd.id());
117+
}
118+
85119
async fn unlink(&self, _path: &str) -> IOResult<()> {
86120
Err(IOError::NotFound)
87121
}

0 commit comments

Comments
 (0)