实现pty,附带测试程序 (#685)

* 实现pty,附带测试程序

* fmt ** clippy

* 将file层的锁粒度缩小,从而不使用no_preempt。更改pipe在sleep部分的bug

* 修复拼写错误
This commit is contained in:
GnoCiYeH
2024-04-05 00:21:55 +08:00
committed by GitHub
parent b8ed38251d
commit dfe53cf087
49 changed files with 1691 additions and 384 deletions

View File

@ -82,7 +82,7 @@ pub struct EPollItem {
/// 监听的描述符
fd: i32,
/// 对应的文件
file: Weak<SpinLock<File>>,
file: Weak<File>,
}
impl EPollItem {
@ -90,7 +90,7 @@ impl EPollItem {
epoll: Weak<SpinLock<EventPoll>>,
events: EPollEvent,
fd: i32,
file: Weak<SpinLock<File>>,
file: Weak<File>,
) -> Self {
Self {
epoll,
@ -108,7 +108,7 @@ impl EPollItem {
&self.event
}
pub fn file(&self) -> Weak<SpinLock<File>> {
pub fn file(&self) -> Weak<File> {
self.file.clone()
}
@ -122,7 +122,7 @@ impl EPollItem {
if file.is_none() {
return EPollEventType::empty();
}
if let Ok(events) = file.unwrap().lock_irqsave().poll() {
if let Ok(events) = file.unwrap().poll() {
let events = events as u32 & self.event.read().events;
return EPollEventType::from_bits_truncate(events);
}
@ -154,7 +154,7 @@ impl IndexNode for EPollInode {
_offset: usize,
_len: usize,
_buf: &mut [u8],
_data: &mut crate::filesystem::vfs::FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
@ -164,7 +164,7 @@ impl IndexNode for EPollInode {
_offset: usize,
_len: usize,
_buf: &[u8],
_data: &mut crate::filesystem::vfs::FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
Err(SystemError::ENOSYS)
}
@ -190,7 +190,7 @@ impl IndexNode for EPollInode {
Ok(Metadata::default())
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
// 释放资源
let mut epoll = self.epoll.0.lock_irqsave();
@ -208,9 +208,7 @@ impl IndexNode for EPollInode {
.get_file_by_fd(fd);
if file.is_some() {
file.unwrap()
.lock_irqsave()
.remove_epoll(&Arc::downgrade(&self.epoll.0))?;
file.unwrap().remove_epoll(&Arc::downgrade(&self.epoll.0))?;
}
epoll.ep_items.remove(&fd);
@ -219,7 +217,11 @@ impl IndexNode for EPollInode {
Ok(())
}
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
Ok(())
}
}
@ -250,7 +252,7 @@ impl EventPoll {
)?;
// 设置ep_file的FilePrivateData
ep_file.private_data = FilePrivateData::EPoll(EPollPrivateData { epoll });
ep_file.private_data = SpinLock::new(FilePrivateData::EPoll(EPollPrivateData { epoll }));
let current_pcb = ProcessManager::current_pcb();
let fd_table = current_pcb.fd_table();
@ -321,7 +323,7 @@ impl EventPoll {
}
// 从FilePrivateData获取到epoll
if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data {
if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
let mut epoll_guard = {
if nonblock {
// 如果设置非阻塞,则尝试获取一次锁
@ -412,7 +414,7 @@ impl EventPoll {
// 从epoll文件获取到epoll
let mut epolldata = None;
if let FilePrivateData::EPoll(epoll_data) = &ep_file.lock_irqsave().private_data {
if let FilePrivateData::EPoll(epoll_data) = &*ep_file.private_data.lock() {
epolldata = Some(epoll_data.clone())
}
if let Some(epoll_data) = epolldata {
@ -583,8 +585,8 @@ impl EventPoll {
}
// ### 查看文件是否为epoll文件
fn is_epoll_file(file: &Arc<SpinLock<File>>) -> bool {
if let FilePrivateData::EPoll(_) = file.lock_irqsave().private_data {
fn is_epoll_file(file: &Arc<File>) -> bool {
if let FilePrivateData::EPoll(_) = *file.private_data.lock() {
return true;
}
return false;
@ -592,7 +594,7 @@ impl EventPoll {
fn ep_insert(
epoll_guard: &mut SpinLockGuard<EventPoll>,
dst_file: Arc<SpinLock<File>>,
dst_file: Arc<File>,
epitem: Arc<EPollItem>,
) -> Result<(), SystemError> {
if Self::is_epoll_file(&dst_file) {
@ -600,7 +602,7 @@ impl EventPoll {
// TODO现在的实现先不考虑嵌套其它类型的文件(暂时只针对socket),这里的嵌套指epoll/select/poll
}
let test_poll = dst_file.lock_irqsave().poll();
let test_poll = dst_file.poll();
if test_poll.is_err() && test_poll.unwrap_err() == SystemError::EOPNOTSUPP_OR_ENOTSUP {
// 如果目标文件不支持poll
return Err(SystemError::ENOSYS);
@ -624,19 +626,17 @@ impl EventPoll {
return Err(SystemError::ENOSYS);
}
dst_file.lock_irqsave().add_epoll(epitem.clone())?;
dst_file.add_epoll(epitem.clone())?;
Ok(())
}
pub fn ep_remove(
epoll: &mut SpinLockGuard<EventPoll>,
fd: i32,
dst_file: Option<Arc<SpinLock<File>>>,
dst_file: Option<Arc<File>>,
) -> Result<(), SystemError> {
if let Some(dst_file) = dst_file {
let mut file_guard = dst_file.lock_irqsave();
file_guard.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
dst_file.remove_epoll(epoll.self_ref.as_ref().unwrap())?;
}
let epitem = epoll.ep_items.remove(&fd).unwrap();

View File

@ -299,12 +299,16 @@ impl SocketInode {
}
impl IndexNode for SocketInode {
fn open(&self, _data: &mut FilePrivateData, _mode: &FileMode) -> Result<(), SystemError> {
fn open(
&self,
_data: SpinLockGuard<FilePrivateData>,
_mode: &FileMode,
) -> Result<(), SystemError> {
self.1.fetch_add(1, core::sync::atomic::Ordering::SeqCst);
Ok(())
}
fn close(&self, _data: &mut FilePrivateData) -> Result<(), SystemError> {
fn close(&self, _data: SpinLockGuard<FilePrivateData>) -> Result<(), SystemError> {
let prev_ref_count = self.1.fetch_sub(1, core::sync::atomic::Ordering::SeqCst);
if prev_ref_count == 1 {
// 最后一次关闭,需要释放
@ -333,7 +337,7 @@ impl IndexNode for SocketInode {
_offset: usize,
len: usize,
buf: &mut [u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
self.0.lock_no_preempt().read(&mut buf[0..len]).0
}
@ -343,7 +347,7 @@ impl IndexNode for SocketInode {
_offset: usize,
len: usize,
buf: &[u8],
_data: &mut FilePrivateData,
_data: SpinLockGuard<FilePrivateData>,
) -> Result<usize, SystemError> {
self.0.lock_no_preempt().write(&buf[0..len], None)
}

View File

@ -603,8 +603,7 @@ impl SockAddr {
let binding = ProcessManager::current_pcb().fd_table();
let fd_table_guard = binding.read();
let binding = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
let file = binding.lock();
let file = fd_table_guard.get_file_by_fd(fd as i32).unwrap();
if file.file_type() != FileType::Socket {
return Err(SystemError::ENOTSOCK);
}