nyx_lite/
timer_event.rs

1use std::time::Duration;
2
3use event_manager::{EventOps, EventSet, Events, MutEventSubscriber};
4use timerfd::{SetTimeFlags, TimerFd, TimerState};
5use vmm::utils::signal::{Killable, sigrtmin};
6use vmm::vstate::vcpu::VCPU_RTSIG_OFFSET;
7
8use libc::pthread_t;
9
10pub struct TimerEvent {
11    timer: TimerFd,
12    target_thread: pthread_t,
13}
14
15impl TimerEvent {
16    pub fn new() -> Self {
17        // Send the SIGTERM signal to the current thread that makes the TimerEvent
18        let target_thread = unsafe { libc::pthread_self() };
19        println!("current_thread_id :{:?}", target_thread);
20
21        Self {
22            timer: TimerFd::new().unwrap(),
23            target_thread,
24        }
25    }
26    pub fn set_timeout(&mut self, timeout: Duration) {
27        if timeout != Duration::MAX {
28            self.timer
29                .set_state(TimerState::Oneshot(timeout), SetTimeFlags::Default);
30        }
31    }
32    pub fn disable(&mut self) {
33        self.timer
34            .set_state(TimerState::Disarmed, SetTimeFlags::Default);
35    }
36}
37
38impl MutEventSubscriber for TimerEvent {
39    // Handle an event for queue or rate limiter.
40    fn process(&mut self, event: Events, _ops: &mut EventOps) {
41        let source = event.data();
42        let event_set = event.event_set();
43
44        let supported_events = EventSet::IN;
45        if !supported_events.contains(event_set) {
46            panic!(
47                "Block: Received unknown event: {:?} from source: {:?}",
48                event_set, source
49            );
50        }
51        self.timer
52            .set_state(TimerState::Disarmed, SetTimeFlags::Default);
53        let sig_num_kick = sigrtmin() + VCPU_RTSIG_OFFSET;
54        self.kill(sig_num_kick).unwrap();
55    }
56
57    fn init(&mut self, ops: &mut EventOps) {
58        ops.add(Events::new(&self.timer, EventSet::IN)).unwrap();
59    }
60}
61
62// This actually needs to make sure that self.target_thread is still running &
63// valid. Since target_thread SHOULD be the main thread for this VM, this should
64// be mostly true. However, if the user was making multiple VM objects in
65// multiple threads, this might no longer be true - it's unclear how the timer
66// event would be drop'ed for now. So this is probably actually not safe.
67unsafe impl Killable for TimerEvent {
68    fn pthread_handle(&self) -> pthread_t {
69        self.target_thread
70    }
71}