use core::{future::poll_fn, task::Poll};
use ax_sync::Mutex;
use ax_task::future::{block_on, interruptible};
use axfs_ng_vfs::VfsResult;
use ktracepoint::TracePipeOps;
use crate::pseudofs::DirectRwFsFileOps;
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 _result = block_on(interruptible(poll_fn(|cx| match self.readable() {
true => Poll::Ready(true),
false => {
super::TRACE_STATE.pipe_event.register(cx.waker());
if self.readable() {
Poll::Ready(true)
} else {
Poll::Pending
}
}
})))?;
};
Ok(read_len)
}
}