use axfs_ng_vfs::{VfsError, VfsResult};
use super::IdentityTraceBuffer;
use crate::{
pseudofs::DirectRwFsFileOps,
sync::Mutex,
task::{current_user_task, future::block_on_user},
};
pub struct TracePipeFile(Mutex<super::TextDrain>);
impl TracePipeFile {
pub const fn new() -> Self {
Self(Mutex::new(super::TextDrain::new()))
}
fn readable(&self) -> bool {
let trace_raw_pipe = super::TRACE_STATE.raw_pipe.lock();
!trace_raw_pipe.is_empty()
}
}
impl DirectRwFsFileOps for TracePipeFile {
fn read_at(&self, buf: &mut [u8], _offset: u64) -> VfsResult<usize> {
if buf.is_empty() {
return Ok(0);
}
let read_len = loop {
{
let mut drain = self.0.lock();
let mut trace_raw_pipe = super::TRACE_STATE.raw_pipe.lock();
let read_len = super::common_trace_pipe_read(&mut *trace_raw_pipe, &mut drain, buf);
if read_len != 0 {
break read_len;
}
}
let task = current_user_task();
let _result = block_on_user(
&task,
crate::task::wait_on_pollset(&super::TRACE_STATE.pipe_event, || {
self.readable().then_some(true)
}),
)
.into_result()
.map_err(|error| VfsError::from(crate::StarryError::from(error)))?;
};
Ok(read_len)
}
}