mirror of
https://github.com/asterinas/asterinas.git
synced 2025-06-19 12:36:46 +00:00
Use more wait_events
This commit is contained in:
committed by
Tate, Hongliang Tian
parent
bbfc2cd12d
commit
f21394c679
@ -89,6 +89,19 @@ impl PtyMaster {
|
|||||||
self.output.buffer_len()
|
self.output.buffer_len()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_read(&self, writer: &mut VmWriter) -> Result<usize> {
|
||||||
|
let mut input = self.input.disable_irq().lock();
|
||||||
|
|
||||||
|
if input.is_empty() {
|
||||||
|
return_errno_with_message!(Errno::EAGAIN, "the buffer is empty");
|
||||||
|
}
|
||||||
|
|
||||||
|
let read_len = input.read_fallible(writer)?;
|
||||||
|
self.update_state(&input);
|
||||||
|
|
||||||
|
Ok(read_len)
|
||||||
|
}
|
||||||
|
|
||||||
fn update_state(&self, buf: &RingBuffer<u8>) {
|
fn update_state(&self, buf: &RingBuffer<u8>) {
|
||||||
if buf.is_empty() {
|
if buf.is_empty() {
|
||||||
self.pollee.del_events(IoEvents::IN)
|
self.pollee.del_events(IoEvents::IN)
|
||||||
@ -120,35 +133,12 @@ impl Pollable for PtyMaster {
|
|||||||
|
|
||||||
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();
|
if !writer.has_avail() {
|
||||||
// TODO: deal with nonblocking read
|
|
||||||
if read_len == 0 {
|
|
||||||
return Ok(0);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut poller = Poller::new();
|
// TODO: deal with nonblocking and timeout
|
||||||
loop {
|
self.wait_events(IoEvents::IN, || self.try_read(writer))
|
||||||
let mut input = self.input.disable_irq().lock();
|
|
||||||
|
|
||||||
if input.is_empty() {
|
|
||||||
let events = self.pollee.poll(IoEvents::IN, Some(&mut poller));
|
|
||||||
|
|
||||||
if events.contains(IoEvents::ERR) {
|
|
||||||
return_errno_with_message!(Errno::EACCES, "unexpected err");
|
|
||||||
}
|
|
||||||
|
|
||||||
if events.is_empty() {
|
|
||||||
drop(input);
|
|
||||||
// FIXME: deal with pty read timeout
|
|
||||||
poller.wait()?;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
let read_len = input.read_fallible(writer)?;
|
|
||||||
self.update_state(&input);
|
|
||||||
return Ok(read_len);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn write(&self, reader: &mut VmReader) -> Result<usize> {
|
fn write(&self, reader: &mut VmReader) -> Result<usize> {
|
||||||
|
@ -16,7 +16,7 @@ use crate::{
|
|||||||
process::signal::{
|
process::signal::{
|
||||||
constants::{SIGINT, SIGQUIT},
|
constants::{SIGINT, SIGQUIT},
|
||||||
signals::kernel::KernelSignal,
|
signals::kernel::KernelSignal,
|
||||||
Pollee, Poller,
|
Pollable, Pollee, Poller,
|
||||||
},
|
},
|
||||||
thread::work_queue::{submit_work_item, work_item::WorkItem, WorkPriority},
|
thread::work_queue::{submit_work_item, work_item::WorkItem, WorkPriority},
|
||||||
util::ring_buffer::RingBuffer,
|
util::ring_buffer::RingBuffer,
|
||||||
@ -87,6 +87,12 @@ impl CurrentLine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Pollable for LineDiscipline {
|
||||||
|
fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
|
||||||
|
self.pollee.poll(mask, poller)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl LineDiscipline {
|
impl LineDiscipline {
|
||||||
/// Creates a new line discipline
|
/// Creates a new line discipline
|
||||||
pub fn new(send_signal: LdiscSignalSender) -> Arc<Self> {
|
pub fn new(send_signal: LdiscSignalSender) -> Arc<Self> {
|
||||||
@ -229,19 +235,7 @@ impl LineDiscipline {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
pub fn read(&self, buf: &mut [u8]) -> Result<usize> {
|
||||||
loop {
|
self.wait_events(IoEvents::IN, || self.try_read(buf))
|
||||||
let res = self.try_read(buf);
|
|
||||||
match res {
|
|
||||||
Ok(len) => return Ok(len),
|
|
||||||
Err(e) if e.error() != Errno::EAGAIN => return Err(e),
|
|
||||||
Err(_) => {
|
|
||||||
let mut poller = Poller::new();
|
|
||||||
if self.poll(IoEvents::IN, Some(&mut poller)).is_empty() {
|
|
||||||
poller.wait()?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Reads all bytes buffered to `dst`.
|
/// Reads all bytes buffered to `dst`.
|
||||||
@ -275,10 +269,6 @@ impl LineDiscipline {
|
|||||||
Ok(read_len)
|
Ok(read_len)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn poll(&self, mask: IoEvents, poller: Option<&mut Poller>) -> IoEvents {
|
|
||||||
self.pollee.poll(mask, poller)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Reads bytes from `self` to `dst`, returning the actual bytes read.
|
/// Reads bytes from `self` to `dst`, returning the actual bytes read.
|
||||||
///
|
///
|
||||||
/// If no bytes are available, this method returns 0 immediately.
|
/// If no bytes are available, this method returns 0 immediately.
|
||||||
|
@ -130,6 +130,28 @@ impl EventFile {
|
|||||||
// TODO: deal with overflow logic
|
// TODO: deal with overflow logic
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn try_read(&self, writer: &mut VmWriter) -> Result<()> {
|
||||||
|
let mut counter = self.counter.lock();
|
||||||
|
|
||||||
|
// Wait until the counter becomes non-zero
|
||||||
|
if *counter == 0 {
|
||||||
|
return_errno_with_message!(Errno::EAGAIN, "the counter is zero");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Copy value from counter, and set the new counter value
|
||||||
|
if self.flags.lock().contains(Flags::EFD_SEMAPHORE) {
|
||||||
|
writer.write_fallible(&mut 1u64.as_bytes().into())?;
|
||||||
|
*counter -= 1;
|
||||||
|
} else {
|
||||||
|
writer.write_fallible(&mut (*counter).as_bytes().into())?;
|
||||||
|
*counter = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.update_io_state(&counter);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
/// Adds val to the counter.
|
/// Adds val to the counter.
|
||||||
///
|
///
|
||||||
/// If the new_value is overflowed or exceeds MAX_COUNTER_VALUE, the counter value
|
/// If the new_value is overflowed or exceeds MAX_COUNTER_VALUE, the counter value
|
||||||
@ -160,40 +182,15 @@ impl Pollable for EventFile {
|
|||||||
impl FileLike for EventFile {
|
impl FileLike for EventFile {
|
||||||
fn read(&self, writer: &mut VmWriter) -> Result<usize> {
|
fn read(&self, writer: &mut VmWriter) -> Result<usize> {
|
||||||
let read_len = core::mem::size_of::<u64>();
|
let read_len = core::mem::size_of::<u64>();
|
||||||
|
|
||||||
if writer.avail() < read_len {
|
if writer.avail() < read_len {
|
||||||
return_errno_with_message!(Errno::EINVAL, "buf len is less len u64 size");
|
return_errno_with_message!(Errno::EINVAL, "buf len is less len u64 size");
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
if self.is_nonblocking() {
|
||||||
let mut counter = self.counter.lock();
|
self.try_read(writer)?;
|
||||||
|
} else {
|
||||||
// Wait until the counter becomes non-zero
|
self.wait_events(IoEvents::IN, || self.try_read(writer))?;
|
||||||
if *counter == 0 {
|
|
||||||
if self.is_nonblocking() {
|
|
||||||
return_errno_with_message!(Errno::EAGAIN, "try reading event file again");
|
|
||||||
}
|
|
||||||
|
|
||||||
self.update_io_state(&counter);
|
|
||||||
drop(counter);
|
|
||||||
|
|
||||||
let mut poller = Poller::new();
|
|
||||||
if self.pollee.poll(IoEvents::IN, Some(&mut poller)).is_empty() {
|
|
||||||
poller.wait()?;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Copy value from counter, and set the new counter value
|
|
||||||
if self.flags.lock().contains(Flags::EFD_SEMAPHORE) {
|
|
||||||
writer.write_fallible(&mut 1u64.as_bytes().into())?;
|
|
||||||
*counter -= 1;
|
|
||||||
} else {
|
|
||||||
writer.write_fallible(&mut (*counter).as_bytes().into())?;
|
|
||||||
*counter = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.update_io_state(&counter);
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(read_len)
|
Ok(read_len)
|
||||||
|
Reference in New Issue
Block a user