Make FileIo pollable

This commit is contained in:
Ruihan Li
2024-09-02 14:31:20 +08:00
committed by Tate, Hongliang Tian
parent c7b3a596dd
commit bbfc2cd12d
13 changed files with 112 additions and 74 deletions

View File

@ -3,7 +3,12 @@
#![allow(unused_variables)] #![allow(unused_variables)]
use super::*; use super::*;
use crate::{events::IoEvents, fs::inode_handle::FileIo, prelude::*, process::signal::Poller}; use crate::{
events::IoEvents,
fs::inode_handle::FileIo,
prelude::*,
process::signal::{Pollable, Poller},
};
pub struct Null; pub struct Null;
@ -22,6 +27,13 @@ impl Device for Null {
} }
} }
impl Pollable for Null {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
}
impl FileIo for Null { impl FileIo for Null {
fn read(&self, _writer: &mut VmWriter) -> Result<usize> { fn read(&self, _writer: &mut VmWriter) -> Result<usize> {
Ok(0) Ok(0)
@ -30,9 +42,4 @@ impl FileIo for Null {
fn write(&self, reader: &mut VmReader) -> Result<usize> { fn write(&self, reader: &mut VmReader) -> Result<usize> {
Ok(reader.remain()) Ok(reader.remain())
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
} }

View File

@ -16,7 +16,7 @@ use crate::{
get_current_userspace, get_current_userspace,
prelude::*, prelude::*,
process::{ process::{
signal::{Pollee, Poller}, signal::{Pollable, Pollee, Poller},
JobControl, Terminal, JobControl, Terminal,
}, },
util::ring_buffer::RingBuffer, util::ring_buffer::RingBuffer,
@ -98,6 +98,26 @@ impl PtyMaster {
} }
} }
impl Pollable for PtyMaster {
fn poll(&self, mask: IoEvents, mut poller: Option<&mut Poller>) -> IoEvents {
let mut poll_status = IoEvents::empty();
let poll_in_mask = mask & IoEvents::IN;
if !poll_in_mask.is_empty() {
let poll_in_status = self.pollee.poll(poll_in_mask, poller.as_deref_mut());
poll_status |= poll_in_status;
}
let poll_out_mask = mask & IoEvents::OUT;
if !poll_out_mask.is_empty() {
let poll_out_status = self.output.poll(poll_out_mask, poller);
poll_status |= poll_out_status;
}
poll_status
}
}
impl FileIo for PtyMaster { impl FileIo for PtyMaster {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let read_len = writer.avail(); let read_len = writer.avail();
@ -245,24 +265,6 @@ impl FileIo for PtyMaster {
_ => Ok(0), _ => Ok(0),
} }
} }
fn poll(&self, mask: IoEvents, mut poller: Option<&mut Poller>) -> IoEvents {
let mut poll_status = IoEvents::empty();
let poll_in_mask = mask & IoEvents::IN;
if !poll_in_mask.is_empty() {
let poll_in_status = self.pollee.poll(poll_in_mask, poller.as_deref_mut());
poll_status |= poll_in_status;
}
let poll_out_mask = mask & IoEvents::OUT;
if !poll_out_mask.is_empty() {
let poll_out_status = self.output.poll(poll_out_mask, poller);
poll_status |= poll_out_status;
}
poll_status
}
} }
impl Terminal for PtyMaster { impl Terminal for PtyMaster {
@ -329,6 +331,12 @@ impl Terminal for PtySlave {
} }
} }
impl Pollable for PtySlave {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
self.master().slave_poll(mask, poller)
}
}
impl FileIo for PtySlave { impl FileIo for PtySlave {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let mut buf = vec![0u8; writer.avail()]; let mut buf = vec![0u8; writer.avail()];
@ -354,10 +362,6 @@ impl FileIo for PtySlave {
Ok(write_len) Ok(write_len)
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
self.master().slave_poll(mask, poller)
}
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> { fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
match cmd { match cmd {
IoctlCmd::TCGETS IoctlCmd::TCGETS

View File

@ -9,7 +9,7 @@ use crate::{
inode_handle::FileIo, inode_handle::FileIo,
}, },
prelude::*, prelude::*,
process::signal::Poller, process::signal::{Pollable, Poller},
util::random::getrandom, util::random::getrandom,
}; };
@ -37,6 +37,13 @@ impl Device for Random {
} }
} }
impl Pollable for Random {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
}
impl FileIo for Random { impl FileIo for Random {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let mut buf = vec![0; writer.avail()]; let mut buf = vec![0; writer.avail()];
@ -46,9 +53,4 @@ impl FileIo for Random {
fn write(&self, reader: &mut VmReader) -> Result<usize> { fn write(&self, reader: &mut VmReader) -> Result<usize> {
Ok(reader.remain()) Ok(reader.remain())
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
} }

View File

@ -57,6 +57,13 @@ impl From<TdCallError> for Error {
} }
} }
impl Pollable for TdxGuest {
fn poll(&self, mask: IoEvents, _poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
}
impl FileIo for TdxGuest { impl FileIo for TdxGuest {
fn read(&self, _writer: &mut VmWriter) -> Result<usize> { fn read(&self, _writer: &mut VmWriter) -> Result<usize> {
return_errno_with_message!(Errno::EPERM, "Read operation not supported") return_errno_with_message!(Errno::EPERM, "Read operation not supported")
@ -72,11 +79,6 @@ impl FileIo for TdxGuest {
_ => return_errno_with_message!(Errno::EPERM, "Unsupported ioctl"), _ => return_errno_with_message!(Errno::EPERM, "Unsupported ioctl"),
} }
} }
fn poll(&self, mask: IoEvents, _poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
} }
fn handle_get_report(arg: usize) -> Result<i32> { fn handle_get_report(arg: usize) -> Result<i32> {

View File

@ -9,7 +9,7 @@ use crate::{
inode_handle::FileIo, inode_handle::FileIo,
}, },
prelude::*, prelude::*,
process::signal::Poller, process::signal::{Pollable, Poller},
}; };
/// Corresponds to `/dev/tty` in the file system. This device represents the controlling terminal /// Corresponds to `/dev/tty` in the file system. This device represents the controlling terminal
@ -40,6 +40,12 @@ impl Device for TtyDevice {
} }
} }
impl Pollable for TtyDevice {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
IoEvents::empty()
}
}
impl FileIo for TtyDevice { impl FileIo for TtyDevice {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
return_errno_with_message!(Errno::EINVAL, "cannot read tty device"); return_errno_with_message!(Errno::EINVAL, "cannot read tty device");
@ -48,8 +54,4 @@ impl FileIo for TtyDevice {
fn write(&self, reader: &mut VmReader) -> Result<usize> { fn write(&self, reader: &mut VmReader) -> Result<usize> {
return_errno_with_message!(Errno::EINVAL, "cannot write tty device"); return_errno_with_message!(Errno::EINVAL, "cannot write tty device");
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
IoEvents::empty()
}
} }

View File

@ -16,7 +16,7 @@ use crate::{
get_current_userspace, get_current_userspace,
prelude::*, prelude::*,
process::{ process::{
signal::{signals::kernel::KernelSignal, Poller}, signal::{signals::kernel::KernelSignal, Pollable, Poller},
JobControl, Process, Terminal, JobControl, Process, Terminal,
}, },
}; };
@ -72,6 +72,12 @@ impl Tty {
} }
} }
impl Pollable for Tty {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
self.ldisc.poll(mask, poller)
}
}
impl FileIo for Tty { impl FileIo for Tty {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let mut buf = vec![0; writer.avail()]; let mut buf = vec![0; writer.avail()];
@ -91,10 +97,6 @@ impl FileIo for Tty {
Ok(buf.len()) Ok(buf.len())
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
self.ldisc.poll(mask, poller)
}
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> { fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
match cmd { match cmd {
IoctlCmd::TCGETS => { IoctlCmd::TCGETS => {

View File

@ -9,7 +9,7 @@ use crate::{
inode_handle::FileIo, inode_handle::FileIo,
}, },
prelude::*, prelude::*,
process::signal::Poller, process::signal::{Pollable, Poller},
util::random::getrandom, util::random::getrandom,
}; };
@ -37,6 +37,13 @@ impl Device for Urandom {
} }
} }
impl Pollable for Urandom {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
}
impl FileIo for Urandom { impl FileIo for Urandom {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let mut buf = vec![0; writer.avail()]; let mut buf = vec![0; writer.avail()];
@ -46,9 +53,4 @@ impl FileIo for Urandom {
fn write(&self, reader: &mut VmReader) -> Result<usize> { fn write(&self, reader: &mut VmReader) -> Result<usize> {
Ok(reader.remain()) Ok(reader.remain())
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
} }

View File

@ -3,7 +3,12 @@
#![allow(unused_variables)] #![allow(unused_variables)]
use super::*; use super::*;
use crate::{events::IoEvents, fs::inode_handle::FileIo, prelude::*, process::signal::Poller}; use crate::{
events::IoEvents,
fs::inode_handle::FileIo,
prelude::*,
process::signal::{Pollable, Poller},
};
pub struct Zero; pub struct Zero;
@ -22,6 +27,13 @@ impl Device for Zero {
} }
} }
impl Pollable for Zero {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
}
impl FileIo for Zero { impl FileIo for Zero {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let read_len = writer.fill_zeros(writer.avail())?; let read_len = writer.fill_zeros(writer.avail())?;
@ -31,9 +43,4 @@ impl FileIo for Zero {
fn write(&self, reader: &mut VmReader) -> Result<usize> { fn write(&self, reader: &mut VmReader) -> Result<usize> {
Ok(reader.remain()) Ok(reader.remain())
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
let events = IoEvents::IN | IoEvents::OUT;
events & mask
}
} }

View File

@ -11,7 +11,7 @@ use crate::{
}; };
/// The abstract of device /// The abstract of device
pub trait Device: Sync + Send + FileIo { pub trait Device: FileIo {
/// Return the device type. /// Return the device type.
fn type_(&self) -> DeviceType; fn type_(&self) -> DeviceType;

View File

@ -4,7 +4,11 @@
#![allow(unused_variables)] #![allow(unused_variables)]
use super::*; use super::*;
use crate::{events::IoEvents, fs::inode_handle::FileIo, process::signal::Poller}; use crate::{
events::IoEvents,
fs::inode_handle::FileIo,
process::signal::{Pollable, Poller},
};
/// Same major number with Linux. /// Same major number with Linux.
const PTMX_MAJOR_NUM: u32 = 5; const PTMX_MAJOR_NUM: u32 = 5;
@ -177,6 +181,12 @@ impl Device for Inner {
} }
} }
impl Pollable for Inner {
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
IoEvents::empty()
}
}
impl FileIo for Inner { impl FileIo for Inner {
fn read(&self, writer: &mut VmWriter) -> Result<usize> { fn read(&self, writer: &mut VmWriter) -> Result<usize> {
return_errno_with_message!(Errno::EINVAL, "cannot read ptmx"); return_errno_with_message!(Errno::EINVAL, "cannot read ptmx");
@ -185,8 +195,4 @@ impl FileIo for Inner {
fn write(&self, reader: &mut VmReader) -> Result<usize> { fn write(&self, reader: &mut VmReader) -> Result<usize> {
return_errno_with_message!(Errno::EINVAL, "cannot write ptmx"); return_errno_with_message!(Errno::EINVAL, "cannot write ptmx");
} }
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
IoEvents::empty()
}
} }

View File

@ -5,7 +5,10 @@
use super::*; use super::*;
use crate::{ use crate::{
device::PtySlave, events::IoEvents, fs::inode_handle::FileIo, process::signal::Poller, device::PtySlave,
events::IoEvents,
fs::inode_handle::FileIo,
process::signal::{Pollable, Poller},
}; };
/// Same major number with Linux, the minor number is the index of slave. /// Same major number with Linux, the minor number is the index of slave.

View File

@ -25,7 +25,10 @@ use crate::{
}, },
}, },
prelude::*, prelude::*,
process::{signal::Poller, Gid, Uid}, process::{
signal::{Pollable, Poller},
Gid, Uid,
},
}; };
#[derive(Debug)] #[derive(Debug)]
@ -389,13 +392,11 @@ impl<R> Drop for InodeHandle<R> {
} }
} }
pub trait FileIo: Send + Sync + 'static { pub trait FileIo: Pollable + Send + Sync + 'static {
fn read(&self, writer: &mut VmWriter) -> Result<usize>; fn read(&self, writer: &mut VmWriter) -> Result<usize>;
fn write(&self, reader: &mut VmReader) -> Result<usize>; fn write(&self, reader: &mut VmReader) -> Result<usize>;
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents;
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> { fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32> {
return_errno_with_message!(Errno::EINVAL, "ioctl is not supported"); return_errno_with_message!(Errno::EINVAL, "ioctl is not supported");
} }

View File

@ -11,7 +11,7 @@ use crate::{
/// job control. /// job control.
/// ///
/// We currently support two kinds of terminal, the tty and pty. /// We currently support two kinds of terminal, the tty and pty.
pub trait Terminal: Send + Sync + FileIo { pub trait Terminal: FileIo {
// *************** Foreground *************** // *************** Foreground ***************
/// Returns the foreground process group /// Returns the foreground process group