Skip to content

Commit 2c90640

Browse files
committed
Add fd table to RuntimeImpl and TestRuntime
1 parent 63e348d commit 2c90640

2 files changed

Lines changed: 75 additions & 23 deletions

File tree

src/runtime.rs

Lines changed: 34 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::{AtomicU64, AtomicUsize, 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<usize, Box<dyn File>>>>,
61+
next_fd: Arc<AtomicUsize>,
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(AtomicUsize::new(0)),
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,28 @@ 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)
121139
}
122140

123141
async fn unlink(&self, path: &str) -> IOResult<()> {
@@ -166,6 +184,10 @@ where
166184
T: Sync + Send + Write + 'static,
167185
{
168186
fn clone(&self) -> Self {
169-
Self { stdout: self.stdout.clone() }
187+
Self {
188+
stdout: self.stdout.clone(),
189+
file_table: self.file_table.clone(),
190+
next_fd: self.next_fd.clone(),
191+
}
170192
}
171193
}

test_utils/src/lib.rs

Lines changed: 41 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::{AtomicU64, AtomicUsize, 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<usize, Box<dyn File>>>>,
25+
next_fd: Arc<AtomicUsize>,
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(AtomicUsize::new(0)),
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)
2651
}
2752
}
2853

@@ -61,27 +86,32 @@ 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+
85115
async fn unlink(&self, _path: &str) -> IOResult<()> {
86116
Err(IOError::NotFound)
87117
}

0 commit comments

Comments
 (0)