refactor epoll related implementation (#1128)

* Refactor epoll related implementation

Add PollableInode trait
Implement PollableInode for pollable inodes

fix https://github.com/DragonOS-Community/DragonOS/issues/1094

Signed-off-by: Godones <chenlinfeng25@outlook.com>
This commit is contained in:
linfeng
2025-04-20 16:41:49 +08:00
committed by GitHub
parent 0f827fb191
commit 167d272792
16 changed files with 461 additions and 289 deletions

View File

@ -490,6 +490,16 @@ impl TtyCoreData {
self.epitems.lock().push_back(epitem)
}
pub fn remove_epitem(&self, epitem: &Arc<EPollItem>) -> Result<(), SystemError> {
let mut guard = self.epitems.lock();
let len = guard.len();
guard.retain(|x| !Arc::ptr_eq(x, epitem));
if len != guard.len() {
return Ok(());
}
Err(SystemError::ENOENT)
}
pub fn eptiems(&self) -> &SpinLock<LinkedList<Arc<EPollItem>>> {
&self.epitems
}

View File

@ -26,7 +26,10 @@ use crate::{
filesystem::{
devfs::{devfs_register, DevFS, DeviceINode},
kernfs::KernFSInode,
vfs::{file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata},
vfs::{
file::FileMode, syscall::ModeType, FilePrivateData, FileType, IndexNode, Metadata,
PollableInode,
},
},
init::initcall::INITCALL_DEVICE,
libs::{
@ -34,7 +37,7 @@ use crate::{
spinlock::SpinLockGuard,
},
mm::VirtAddr,
net::event_poll::{EPollItem, KernelIoctlData},
net::event_poll::EPollItem,
process::ProcessManager,
syscall::user_access::{UserBufferReader, UserBufferWriter},
};
@ -130,6 +133,43 @@ impl TtyDevice {
pub fn name_ref(&self) -> &str {
&self.name
}
fn tty_core(private_data: &FilePrivateData) -> Result<Arc<TtyCore>, SystemError> {
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
(tty_priv.tty.clone(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
Ok(tty)
}
}
impl PollableInode for TtyDevice {
fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
let tty = TtyDevice::tty_core(private_data)?;
tty.ldisc().poll(tty)
}
fn add_epitem(
&self,
epitem: Arc<EPollItem>,
private_data: &FilePrivateData,
) -> Result<(), SystemError> {
let tty = TtyDevice::tty_core(private_data)?;
let core = tty.core();
core.add_epitem(epitem);
Ok(())
}
fn remove_epitem(
&self,
epitem: &Arc<EPollItem>,
private_data: &FilePrivateData,
) -> Result<(), SystemError> {
let tty = TtyDevice::tty_core(private_data)?;
let core = tty.core();
core.remove_epitem(epitem)
}
}
impl IndexNode for TtyDevice {
@ -312,35 +352,6 @@ impl IndexNode for TtyDevice {
Ok(())
}
fn kernel_ioctl(
&self,
arg: Arc<dyn KernelIoctlData>,
data: &FilePrivateData,
) -> Result<usize, SystemError> {
let epitem = arg
.arc_any()
.downcast::<EPollItem>()
.map_err(|_| SystemError::EFAULT)?;
let _ = UserBufferReader::new(
&epitem as *const Arc<EPollItem>,
core::mem::size_of::<Arc<EPollItem>>(),
false,
)?;
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
let core = tty.core();
core.add_epitem(epitem.clone());
return Ok(0);
}
fn ioctl(&self, cmd: u32, arg: usize, data: &FilePrivateData) -> Result<usize, SystemError> {
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = data {
(tty_priv.tty(), tty_priv.mode)
@ -423,14 +434,8 @@ impl IndexNode for TtyDevice {
Ok(0)
}
fn poll(&self, private_data: &FilePrivateData) -> Result<usize, SystemError> {
let (tty, _) = if let FilePrivateData::Tty(tty_priv) = private_data {
(tty_priv.tty.clone(), tty_priv.mode)
} else {
return Err(SystemError::EIO);
};
tty.ldisc().poll(tty)
fn as_pollable_inode(&self) -> Result<&dyn PollableInode, SystemError> {
Ok(self)
}
}