mirror of
https://github.com/DragonOS-Community/DragonOS.git
synced 2025-06-25 22:33:22 +00:00
增加内存分配日志监视器 (#424)
* 完成内存日志监视,并输出日志到文件 * 修复进程退出后,procfs查看进程status文件会崩溃的问题 * 修复signal唤醒进程的判断条件问题
This commit is contained in:
83
tools/debugging/logmonitor/src/event.rs
Normal file
83
tools/debugging/logmonitor/src/event.rs
Normal file
@ -0,0 +1,83 @@
|
||||
use crate::app::AppResult;
|
||||
use crate::backend::event::BackendEvent;
|
||||
use crossterm::event::{self, Event as CrosstermEvent, KeyEvent, MouseEvent};
|
||||
use std::sync::mpsc;
|
||||
use std::thread;
|
||||
use std::time::{Duration, Instant};
|
||||
|
||||
/// Terminal events.
|
||||
#[derive(Clone, Debug)]
|
||||
pub enum Event {
|
||||
/// Terminal tick.
|
||||
Tick,
|
||||
/// Key press.
|
||||
Key(KeyEvent),
|
||||
/// Mouse click/scroll.
|
||||
Mouse(MouseEvent),
|
||||
/// Terminal resize.
|
||||
Resize(u16, u16),
|
||||
Backend(BackendEvent),
|
||||
}
|
||||
|
||||
/// Terminal event handler.
|
||||
#[allow(dead_code)]
|
||||
#[derive(Debug)]
|
||||
pub struct EventHandler {
|
||||
/// Event sender channel.
|
||||
sender: mpsc::Sender<Event>,
|
||||
/// Event receiver channel.
|
||||
receiver: mpsc::Receiver<Event>,
|
||||
/// Event handler thread.
|
||||
handler: thread::JoinHandle<()>,
|
||||
}
|
||||
|
||||
impl EventHandler {
|
||||
/// Constructs a new instance of [`EventHandler`].
|
||||
pub fn new(tick_rate: u64) -> Self {
|
||||
let tick_rate = Duration::from_millis(tick_rate);
|
||||
let (sender, receiver) = mpsc::channel();
|
||||
let handler = {
|
||||
let sender = sender.clone();
|
||||
thread::spawn(move || {
|
||||
let mut last_tick = Instant::now();
|
||||
loop {
|
||||
let timeout = tick_rate
|
||||
.checked_sub(last_tick.elapsed())
|
||||
.unwrap_or(tick_rate);
|
||||
|
||||
if event::poll(timeout).expect("no events available") {
|
||||
match event::read().expect("unable to read event") {
|
||||
CrosstermEvent::Key(e) => sender.send(Event::Key(e)),
|
||||
CrosstermEvent::Mouse(e) => sender.send(Event::Mouse(e)),
|
||||
CrosstermEvent::Resize(w, h) => sender.send(Event::Resize(w, h)),
|
||||
_ => unimplemented!(),
|
||||
}
|
||||
.expect("failed to send terminal event")
|
||||
}
|
||||
|
||||
if last_tick.elapsed() >= tick_rate {
|
||||
sender.send(Event::Tick).expect("failed to send tick event");
|
||||
last_tick = Instant::now();
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
Self {
|
||||
sender,
|
||||
receiver,
|
||||
handler,
|
||||
}
|
||||
}
|
||||
|
||||
/// Receive the next event from the handler thread.
|
||||
///
|
||||
/// This function will always block the current thread if
|
||||
/// there is no data available and it's possible for more data to be sent.
|
||||
pub fn next(&self) -> AppResult<Event> {
|
||||
Ok(self.receiver.recv()?)
|
||||
}
|
||||
|
||||
pub fn sender(&self) -> mpsc::Sender<Event> {
|
||||
self.sender.clone()
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user