修正pipe逻辑,将pipe接入epoll。 (#478)

This commit is contained in:
GnoCiYeH
2023-12-27 15:02:29 +08:00
committed by GitHub
parent 0d6cf65aa1
commit 5e948c5650
8 changed files with 201 additions and 89 deletions

View File

@ -161,7 +161,7 @@ impl IndexNode for EPollInode {
Err(SystemError::ENOSYS)
}
fn poll(&self) -> Result<usize, SystemError> {
fn poll(&self, _private_data: &FilePrivateData) -> Result<usize, SystemError> {
// 需要实现epoll嵌套epoll时需要实现这里
todo!()
}
@ -704,6 +704,48 @@ impl EventPoll {
pub fn ep_wake_one(&self) {
self.epoll_wq.wakeup(None);
}
/// ### epoll的回调支持epoll的文件有事件到来时直接调用该方法即可
pub fn wakeup_epoll(
epitems: &mut SpinLock<LinkedList<Arc<EPollItem>>>,
pollflags: EPollEventType,
) -> Result<(), SystemError> {
let mut epitems_guard = epitems.try_lock_irqsave()?;
// 一次只取一个,因为一次也只有一个进程能拿到对应文件的🔓
if let Some(epitem) = epitems_guard.pop_front() {
let epoll = epitem.epoll().upgrade().unwrap();
let mut epoll_guard = epoll.try_lock()?;
let binding = epitem.clone();
let event_guard = binding.event().read();
let ep_events = EPollEventType::from_bits_truncate(event_guard.events());
// 检查事件合理性以及是否有感兴趣的事件
if !(ep_events
.difference(EPollEventType::EP_PRIVATE_BITS)
.is_empty()
|| pollflags.difference(ep_events).is_empty())
{
// TODO: 未处理pm相关
// 首先将就绪的epitem加入等待队列
epoll_guard.ep_add_ready(epitem.clone());
if epoll_guard.ep_has_waiter() {
if ep_events.contains(EPollEventType::EPOLLEXCLUSIVE)
&& !pollflags.contains(EPollEventType::POLLFREE)
{
// 避免惊群
epoll_guard.ep_wake_one();
} else {
epoll_guard.ep_wake_all();
}
}
}
epitems_guard.push_back(epitem);
}
Ok(())
}
}
/// 与C兼容的Epoll事件结构体