Skip to content

Commit 6c9d1b2

Browse files
committed
refactor: separate FileHandle and Pipe types
1 parent 6c22ed2 commit 6c9d1b2

10 files changed

Lines changed: 321 additions & 198 deletions

File tree

ch7/src/fs.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::virtio_block::BLOCK_DEVICE;
22
use alloc::{string::String, sync::Arc, vec::Vec};
33
use spin::Lazy;
4-
use tg_easy_fs::{EasyFileSystem, FSManager, FileHandle, Inode, OpenFlags};
4+
use tg_easy_fs::{
5+
EasyFileSystem, FSManager, FileHandle, Inode, OpenFlags, PipeReader, PipeWriter, UserBuffer,
6+
};
57

68
pub static FS: Lazy<FileSystem> = Lazy::new(|| FileSystem {
79
root: EasyFileSystem::root_inode(&EasyFileSystem::open(BLOCK_DEVICE.clone())),
@@ -68,3 +70,61 @@ pub fn read_all(fd: Arc<FileHandle>) -> Vec<u8> {
6870
}
6971
v
7072
}
73+
74+
/// 统一的文件描述符类型
75+
#[derive(Clone)]
76+
pub enum Fd {
77+
/// 普通文件
78+
File(FileHandle),
79+
/// 管道读端
80+
PipeRead(PipeReader),
81+
/// 管道写端
82+
PipeWrite(Arc<PipeWriter>),
83+
/// 空描述符(用于 stdin/stdout/stderr)
84+
Empty {
85+
/// 是否可读
86+
read: bool,
87+
/// 是否可写
88+
write: bool,
89+
},
90+
}
91+
92+
impl Fd {
93+
/// 是否可读
94+
pub fn readable(&self) -> bool {
95+
match self {
96+
Fd::File(f) => f.readable(),
97+
Fd::PipeRead(_) => true,
98+
Fd::PipeWrite(_) => false,
99+
Fd::Empty { read, .. } => *read,
100+
}
101+
}
102+
103+
/// 是否可写
104+
pub fn writable(&self) -> bool {
105+
match self {
106+
Fd::File(f) => f.writable(),
107+
Fd::PipeRead(_) => false,
108+
Fd::PipeWrite(_) => true,
109+
Fd::Empty { write, .. } => *write,
110+
}
111+
}
112+
113+
/// 读取数据
114+
pub fn read(&self, buf: UserBuffer) -> isize {
115+
match self {
116+
Fd::File(f) => f.read(buf),
117+
Fd::PipeRead(p) => p.read(buf),
118+
_ => -1,
119+
}
120+
}
121+
122+
/// 写入数据
123+
pub fn write(&self, buf: UserBuffer) -> isize {
124+
match self {
125+
Fd::File(f) => f.write(buf),
126+
Fd::PipeWrite(p) => p.write(buf),
127+
_ => -1,
128+
}
129+
}
130+
}

ch7/src/main.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ fn map_portal(space: &AddressSpace<Sv39, Sv39Manager>) {
228228
/// 各种接口库的实现。
229229
mod impls {
230230
use crate::{
231-
fs::{read_all, FS},
231+
fs::{read_all, Fd, FS},
232232
process::Process as ProcStruct,
233233
processor::ProcManager,
234234
PROCESSOR,
@@ -389,7 +389,6 @@ mod impls {
389389
}
390390

391391
fn open(&self, _caller: Caller, path: usize, flags: usize) -> isize {
392-
// FS.open(, flags)
393392
let current = PROCESSOR.get_mut().current().unwrap();
394393
if let Some(ptr) = current.address_space.translate(VAddr::new(path), READABLE) {
395394
let mut string = String::new();
@@ -405,11 +404,14 @@ mod impls {
405404
}
406405
}
407406

408-
if let Some(fd) =
407+
if let Some(file_handle) =
409408
FS.open(string.as_str(), OpenFlags::from_bits(flags as u32).unwrap())
410409
{
411410
let new_fd = current.fd_table.len();
412-
current.fd_table.push(Some(Mutex::new(fd)));
411+
// Arc<FileHandle> -> FileHandle,需要解引用
412+
current
413+
.fd_table
414+
.push(Some(Mutex::new(Fd::File((*file_handle).clone()))));
413415
new_fd as isize
414416
} else {
415417
-1
@@ -454,8 +456,12 @@ mod impls {
454456
return -1;
455457
}
456458
// 最后添加,避免中途写入异常导致浪费一个 fd
457-
current.fd_table.push(Some(Mutex::new(read_end)));
458-
current.fd_table.push(Some(Mutex::new(write_end)));
459+
current
460+
.fd_table
461+
.push(Some(Mutex::new(Fd::PipeRead(read_end))));
462+
current
463+
.fd_table
464+
.push(Some(Mutex::new(Fd::PipeWrite(write_end))));
459465
0
460466
}
461467
}

ch7/src/process.rs

Lines changed: 20 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
use crate::{map_portal, Sv39Manager};
2-
use alloc::{alloc::alloc_zeroed, boxed::Box, sync::Arc, vec::Vec};
1+
use crate::{fs::Fd, map_portal, Sv39Manager};
2+
use alloc::{alloc::alloc_zeroed, boxed::Box, vec::Vec};
33
use core::{alloc::Layout, str::FromStr};
44
use spin::Mutex;
5-
use tg_easy_fs::FileHandle;
65
use tg_kernel_context::{foreign::ForeignContext, LocalContext};
76
use tg_kernel_vm::{
87
page_table::{MmuMeta, Sv39, VAddr, VmFlags, PPN, VPN},
@@ -25,7 +24,7 @@ pub struct Process {
2524
pub address_space: AddressSpace<Sv39, Sv39Manager>,
2625

2726
/// 文件描述符表
28-
pub fd_table: Vec<Option<Mutex<Arc<FileHandle>>>>,
27+
pub fd_table: Vec<Option<Mutex<Fd>>>,
2928

3029
/// 信号模块
3130
pub signal: Box<dyn Signal>,
@@ -58,14 +57,11 @@ impl Process {
5857
let satp = (8 << 60) | address_space.root_ppn().val();
5958
let foreign_ctx = ForeignContext { context, satp };
6059
// 复制父进程文件符描述表
61-
let mut new_fd_table: Vec<Option<Mutex<Arc<FileHandle>>>> = Vec::new();
62-
for fd in self.fd_table.iter_mut() {
63-
if let Some(file) = fd {
64-
new_fd_table.push(Some(Mutex::new(file.get_mut().clone())));
65-
} else {
66-
new_fd_table.push(None);
67-
}
68-
}
60+
let new_fd_table: Vec<Option<Mutex<Fd>>> = self
61+
.fd_table
62+
.iter()
63+
.map(|fd| fd.as_ref().map(|f| Mutex::new(f.lock().clone())))
64+
.collect();
6965
Some(Self {
7066
pid,
7167
context: foreign_ctx,
@@ -153,11 +149,20 @@ impl Process {
153149
address_space,
154150
fd_table: vec![
155151
// Stdin
156-
Some(Mutex::new(Arc::new(FileHandle::empty(true, false)))),
152+
Some(Mutex::new(Fd::Empty {
153+
read: true,
154+
write: false,
155+
})),
157156
// Stdout
158-
Some(Mutex::new(Arc::new(FileHandle::empty(false, true)))),
157+
Some(Mutex::new(Fd::Empty {
158+
read: false,
159+
write: true,
160+
})),
159161
// Stderr
160-
Some(Mutex::new(Arc::new(FileHandle::empty(false, true)))),
162+
Some(Mutex::new(Fd::Empty {
163+
read: false,
164+
write: true,
165+
})),
161166
],
162167
signal: Box::new(SignalImpl::new()),
163168
heap_bottom,

ch8/src/fs.rs

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
use crate::virtio_block::BLOCK_DEVICE;
22
use alloc::{string::String, sync::Arc, vec::Vec};
33
use spin::Lazy;
4-
use tg_easy_fs::{EasyFileSystem, FSManager, FileHandle, Inode, OpenFlags};
4+
use tg_easy_fs::{
5+
EasyFileSystem, FSManager, FileHandle, Inode, OpenFlags, PipeReader, PipeWriter, UserBuffer,
6+
};
57

68
pub static FS: Lazy<FileSystem> = Lazy::new(|| FileSystem {
79
root: EasyFileSystem::root_inode(&EasyFileSystem::open(BLOCK_DEVICE.clone())),
@@ -68,3 +70,61 @@ pub fn read_all(fd: Arc<FileHandle>) -> Vec<u8> {
6870
}
6971
v
7072
}
73+
74+
/// 统一的文件描述符类型
75+
#[derive(Clone)]
76+
pub enum Fd {
77+
/// 普通文件
78+
File(FileHandle),
79+
/// 管道读端
80+
PipeRead(PipeReader),
81+
/// 管道写端
82+
PipeWrite(Arc<PipeWriter>),
83+
/// 空描述符(用于 stdin/stdout/stderr)
84+
Empty {
85+
/// 是否可读
86+
read: bool,
87+
/// 是否可写
88+
write: bool,
89+
},
90+
}
91+
92+
impl Fd {
93+
/// 是否可读
94+
pub fn readable(&self) -> bool {
95+
match self {
96+
Fd::File(f) => f.readable(),
97+
Fd::PipeRead(_) => true,
98+
Fd::PipeWrite(_) => false,
99+
Fd::Empty { read, .. } => *read,
100+
}
101+
}
102+
103+
/// 是否可写
104+
pub fn writable(&self) -> bool {
105+
match self {
106+
Fd::File(f) => f.writable(),
107+
Fd::PipeRead(_) => false,
108+
Fd::PipeWrite(_) => true,
109+
Fd::Empty { write, .. } => *write,
110+
}
111+
}
112+
113+
/// 读取数据
114+
pub fn read(&self, buf: UserBuffer) -> isize {
115+
match self {
116+
Fd::File(f) => f.read(buf),
117+
Fd::PipeRead(p) => p.read(buf),
118+
_ => -1,
119+
}
120+
}
121+
122+
/// 写入数据
123+
pub fn write(&self, buf: UserBuffer) -> isize {
124+
match self {
125+
Fd::File(f) => f.write(buf),
126+
Fd::PipeWrite(p) => p.write(buf),
127+
_ => -1,
128+
}
129+
}
130+
}

ch8/src/main.rs

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ fn map_portal(space: &AddressSpace<Sv39, Sv39Manager>) {
243243
/// 各种接口库的实现。
244244
mod impls {
245245
use crate::{
246-
fs::{read_all, FS},
246+
fs::{read_all, Fd, FS},
247247
processor::ProcessorInner,
248248
Thread, PROCESSOR,
249249
};
@@ -405,7 +405,6 @@ mod impls {
405405
}
406406

407407
fn open(&self, _caller: Caller, path: usize, flags: usize) -> isize {
408-
// FS.open(, flags)
409408
let current = PROCESSOR.get_mut().get_current_proc().unwrap();
410409
if let Some(ptr) = current.address_space.translate(VAddr::new(path), READABLE) {
411410
let mut string = String::new();
@@ -421,11 +420,14 @@ mod impls {
421420
}
422421
}
423422

424-
if let Some(fd) =
423+
if let Some(file_handle) =
425424
FS.open(string.as_str(), OpenFlags::from_bits(flags as u32).unwrap())
426425
{
427426
let new_fd = current.fd_table.len();
428-
current.fd_table.push(Some(Mutex::new(fd)));
427+
// Arc<FileHandle> -> FileHandle,需要解引用
428+
current
429+
.fd_table
430+
.push(Some(Mutex::new(Fd::File((*file_handle).clone()))));
429431
new_fd as isize
430432
} else {
431433
-1
@@ -470,8 +472,12 @@ mod impls {
470472
return -1;
471473
}
472474
// 最后添加,避免中途写入异常导致浪费一个 fd
473-
current.fd_table.push(Some(Mutex::new(read_end)));
474-
current.fd_table.push(Some(Mutex::new(write_end)));
475+
current
476+
.fd_table
477+
.push(Some(Mutex::new(Fd::PipeRead(read_end))));
478+
current
479+
.fd_table
480+
.push(Some(Mutex::new(Fd::PipeWrite(write_end))));
475481
0
476482
}
477483
}

ch8/src/process.rs

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
1-
use crate::{map_portal, processor::ProcessorInner, Sv39Manager, PROCESSOR};
1+
use crate::{fs::Fd, map_portal, processor::ProcessorInner, Sv39Manager, PROCESSOR};
22
use alloc::{alloc::alloc_zeroed, boxed::Box, sync::Arc, vec::Vec};
33
use core::{alloc::Layout, str::FromStr};
44
use spin::Mutex;
5-
use tg_easy_fs::FileHandle;
65
use tg_kernel_context::{foreign::ForeignContext, LocalContext};
76
use tg_kernel_vm::{
87
page_table::{MmuMeta, Sv39, VAddr, VmFlags, PPN, VPN},
@@ -41,7 +40,7 @@ pub struct Process {
4140
/// 可变
4241
pub address_space: AddressSpace<Sv39, Sv39Manager>,
4342
/// 文件描述符表
44-
pub fd_table: Vec<Option<Mutex<Arc<FileHandle>>>>,
43+
pub fd_table: Vec<Option<Mutex<Fd>>>,
4544
/// 信号模块
4645
pub signal: Box<dyn Signal>,
4746
/// 分配的锁以及信号量
@@ -84,14 +83,11 @@ impl Process {
8483
let satp = (8 << 60) | address_space.root_ppn().val();
8584
let thread = Thread::new(satp, context);
8685
// 复制父进程文件符描述表
87-
let mut new_fd_table: Vec<Option<Mutex<Arc<FileHandle>>>> = Vec::new();
88-
for fd in self.fd_table.iter_mut() {
89-
if let Some(file) = fd {
90-
new_fd_table.push(Some(Mutex::new(file.get_mut().clone())));
91-
} else {
92-
new_fd_table.push(None);
93-
}
94-
}
86+
let new_fd_table: Vec<Option<Mutex<Fd>>> = self
87+
.fd_table
88+
.iter()
89+
.map(|fd| fd.as_ref().map(|f| Mutex::new(f.lock().clone())))
90+
.collect();
9591
Some((
9692
Self {
9793
pid,
@@ -174,11 +170,20 @@ impl Process {
174170
address_space,
175171
fd_table: vec![
176172
// Stdin
177-
Some(Mutex::new(Arc::new(FileHandle::empty(true, false)))),
173+
Some(Mutex::new(Fd::Empty {
174+
read: true,
175+
write: false,
176+
})),
178177
// Stdout
179-
Some(Mutex::new(Arc::new(FileHandle::empty(false, true)))),
178+
Some(Mutex::new(Fd::Empty {
179+
read: false,
180+
write: true,
181+
})),
180182
// Stderr
181-
Some(Mutex::new(Arc::new(FileHandle::empty(false, true)))),
183+
Some(Mutex::new(Fd::Empty {
184+
read: false,
185+
write: true,
186+
})),
182187
],
183188
signal: Box::new(SignalImpl::new()),
184189
semaphore_list: Vec::new(),

0 commit comments

Comments
 (0)