Skip to content

Commit faac185

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

File tree

2 files changed

+81
-23
lines changed

2 files changed

+81
-23
lines changed

src/runtime.rs

Lines changed: 39 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,33 @@ 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
139+
.lock()
140+
.unwrap()
141+
.get(&fd.id())
142+
.cloned()
143+
.ok_or(IOError::NotFound)
121144
}
122145

123146
async fn unlink(&self, path: &str) -> IOResult<()> {
@@ -166,6 +189,10 @@ where
166189
T: Sync + Send + Write + 'static,
167190
{
168191
fn clone(&self) -> Self {
169-
Self { stdout: self.stdout.clone() }
192+
Self {
193+
stdout: self.stdout.clone(),
194+
file_table: self.file_table.clone(),
195+
next_fd: self.next_fd.clone(),
196+
}
170197
}
171198
}

test_utils/src/lib.rs

Lines changed: 42 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,49 @@
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::{sync::Mutex, time::{SystemTime, UNIX_EPOCH}};
1010

1111
use jvm::{ClassDefinition, Jvm, Result};
1212
use jvm_rust::{ArrayClassDefinitionImpl, ClassDefinitionImpl};
1313

1414
use java_runtime::{
15-
File, FileSize, FileStat, FileType, IOError, IOResult, RT_RUSTJAR, Runtime, SpawnCallback, get_bootstrap_class_loader, get_runtime_class_proto,
15+
File, FileDescriptorId, FileSize, FileStat, FileType, IOError, IOResult, RT_RUSTJAR, Runtime, SpawnCallback, get_bootstrap_class_loader, get_runtime_class_proto,
1616
};
1717

18-
#[derive(Clone)]
1918
pub struct TestRuntime {
2019
filesystem: BTreeMap<String, Vec<u8>>,
20+
file_table: Arc<Mutex<BTreeMap<usize, Box<dyn File>>>>,
21+
next_fd: Arc<AtomicUsize>,
22+
}
23+
24+
impl Clone for TestRuntime {
25+
fn clone(&self) -> Self {
26+
Self {
27+
filesystem: self.filesystem.clone(),
28+
file_table: self.file_table.clone(),
29+
next_fd: self.next_fd.clone(),
30+
}
31+
}
2132
}
2233

2334
impl TestRuntime {
2435
pub fn new(filesystem: BTreeMap<String, Vec<u8>>) -> Self {
25-
Self { filesystem }
36+
Self {
37+
filesystem,
38+
file_table: Arc::new(Mutex::new(BTreeMap::new())),
39+
next_fd: Arc::new(AtomicUsize::new(0)),
40+
}
41+
}
42+
43+
fn register_file(&self, file: Box<dyn File>) -> FileDescriptorId {
44+
let fd = self.next_fd.fetch_add(1, Ordering::SeqCst);
45+
self.file_table.lock().unwrap().insert(fd, file);
46+
FileDescriptorId::new(fd)
2647
}
2748
}
2849

@@ -61,27 +82,37 @@ impl Runtime for TestRuntime {
6182
TASK_ID.try_with(|x| *x).unwrap_or(0)
6283
}
6384

64-
fn stdin(&self) -> IOResult<Box<dyn File>> {
85+
fn stdin(&self) -> IOResult<FileDescriptorId> {
6586
Err(IOError::NotFound)
6687
}
6788

68-
fn stdout(&self) -> IOResult<Box<dyn File>> {
89+
fn stdout(&self) -> IOResult<FileDescriptorId> {
6990
Err(IOError::NotFound)
7091
}
7192

72-
fn stderr(&self) -> IOResult<Box<dyn File>> {
93+
fn stderr(&self) -> IOResult<FileDescriptorId> {
7394
Err(IOError::NotFound)
7495
}
7596

76-
async fn open(&self, path: &str, _write: bool) -> IOResult<Box<dyn File>> {
97+
async fn open(&self, path: &str, _write: bool) -> IOResult<FileDescriptorId> {
7798
let entry = self.filesystem.get(path);
7899
if let Some(data) = entry {
79-
Ok(Box::new(DummyFile::new(data.clone())) as Box<_>)
100+
let file = Box::new(DummyFile::new(data.clone())) as Box<dyn File>;
101+
Ok(self.register_file(file))
80102
} else {
81103
Err(IOError::NotFound)
82104
}
83105
}
84106

107+
fn get_file(&self, fd: FileDescriptorId) -> IOResult<Box<dyn File>> {
108+
self.file_table
109+
.lock()
110+
.unwrap()
111+
.get(&fd.id())
112+
.cloned()
113+
.ok_or(IOError::NotFound)
114+
}
115+
85116
async fn unlink(&self, _path: &str) -> IOResult<()> {
86117
Err(IOError::NotFound)
87118
}

0 commit comments

Comments
 (0)