feat(tty): 将tty设备适配epoll,修改串口部分问题 (#968)

- tty文件适配epoll,使epoll能够监听tty
- 修改串口handle_irq,原有每次只读取一个字节会导致:输入left(esc+[+A)被错误解析为(esc)+([)+(A)三个字符
- 为串口加上vcdata用于控制输入输出的格式问题(未解决,这个pr捎带)
This commit is contained in:
GnoCiYeH
2024-10-13 01:10:36 +08:00
committed by GitHub
parent 40db1e61da
commit c709f79fda
11 changed files with 148 additions and 106 deletions

View File

@ -716,41 +716,50 @@ impl EventPoll {
/// ### epoll的回调支持epoll的文件有事件到来时直接调用该方法即可
pub fn wakeup_epoll(
epitems: &SpinLock<LinkedList<Arc<EPollItem>>>,
pollflags: EPollEventType,
pollflags: Option<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());
let pollflags = pollflags.unwrap_or({
if let Some(file) = epitem.file.upgrade() {
EPollEventType::from_bits_truncate(file.poll()? as u32)
} else {
EPollEventType::empty()
}
});
// 检查事件合理性以及是否有感兴趣的事件
if !(ep_events
.difference(EPollEventType::EP_PRIVATE_BITS)
.is_empty()
|| pollflags.difference(ep_events).is_empty())
{
// TODO: 未处理pm相关
if let Some(epoll) = epitem.epoll().upgrade() {
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());
// 首先将就绪的epitem加入等待队列
epoll_guard.ep_add_ready(epitem.clone());
// 检查事件合理性以及是否有感兴趣的事件
if !(ep_events
.difference(EPollEventType::EP_PRIVATE_BITS)
.is_empty()
|| pollflags.difference(ep_events).is_empty())
{
// TODO: 未处理pm相关
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();
// 首先将就绪的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);
epitems_guard.push_back(epitem);
}
}
Ok(())
}

View File

@ -233,7 +233,7 @@ fn send_event(sockets: &smoltcp::iface::SocketSet) -> Result<(), SystemError> {
}
EventPoll::wakeup_epoll(
&posix_item.epitems,
EPollEventType::from_bits_truncate(events as u32),
Some(EPollEventType::from_bits_truncate(events as u32)),
)?;
drop(handle_guard);
// crate::debug!(