shadow_rs/core/work/
event.rs1use shadow_shim_helper_rs::HostId;
2use shadow_shim_helper_rs::emulated_time::EmulatedTime;
3
4use super::task::TaskRef;
5use crate::host::host::Host;
6use crate::network::packet::PacketRc;
7use crate::utility::{Magic, ObjectCounter};
8
9#[derive(Debug)]
10pub struct Event {
11    magic: Magic<Self>,
12    time: EmulatedTime,
13    data: EventData,
14    _counter: ObjectCounter,
15}
16
17impl Event {
18    pub fn new_packet(packet: PacketRc, time: EmulatedTime, src_host: &Host) -> Self {
21        Self {
22            magic: Magic::new(),
23            time,
24            data: EventData::Packet(PacketEventData {
25                packet,
26                src_host_id: src_host.id(),
27                src_host_event_id: src_host.get_new_event_id(),
28            }),
29            _counter: ObjectCounter::new("Event"),
30        }
31    }
32
33    pub fn new_local(task: TaskRef, time: EmulatedTime, host: &Host) -> Self {
36        Self {
37            magic: Magic::new(),
38            time,
39            data: EventData::Local(LocalEventData {
40                task,
41                event_id: host.get_new_event_id(),
42            }),
43            _counter: ObjectCounter::new("Event"),
44        }
45    }
46
47    pub fn time(&self) -> EmulatedTime {
48        self.magic.debug_check();
49        self.time
50    }
51
52    pub fn set_time(&mut self, time: EmulatedTime) {
53        self.magic.debug_check();
54        self.time = time;
55    }
56
57    pub fn data(self) -> EventData {
59        self.magic.debug_check();
60        self.data
61    }
62}
63
64impl PartialEq for Event {
65    fn eq(&self, other: &Self) -> bool {
66        self.magic.debug_check();
67        other.magic.debug_check();
68
69        fn check_impl_eq(_: impl Eq) {}
70
71        check_impl_eq(self.time);
74        check_impl_eq(&self.data);
75
76        self.time == other.time && self.data == other.data
78    }
79}
80
81impl Eq for Event {}
83
84impl PartialOrd for Event {
85    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
86        self.magic.debug_check();
87        other.magic.debug_check();
88
89        let cmp = self.time.cmp(&other.time);
91
92        if cmp.is_ne() {
93            Some(cmp)
94        } else {
95            self.data.partial_cmp(&other.data)
97        }
98    }
99}
100
101#[derive(Debug, PartialEq, Eq, PartialOrd)]
103pub enum EventData {
104    Packet(PacketEventData),
109    Local(LocalEventData),
110}
111
112#[derive(Debug, PartialEq, Eq)]
113pub struct PacketEventData {
114    packet: PacketRc,
115    src_host_id: HostId,
116    src_host_event_id: u64,
117}
118
119#[derive(Debug, PartialEq, Eq)]
120pub struct LocalEventData {
121    task: TaskRef,
122    event_id: u64,
123}
124
125impl From<PacketEventData> for PacketRc {
126    fn from(data: PacketEventData) -> Self {
127        data.packet
128    }
129}
130
131impl PartialOrd for PacketEventData {
132    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
133        let cmp = self
135            .src_host_id
136            .cmp(&other.src_host_id)
137            .then_with(|| self.src_host_event_id.cmp(&other.src_host_event_id));
138
139        if cmp == std::cmp::Ordering::Equal {
142            if self.packet != other.packet {
143                assert_ne!(self, other);
145                return None;
147            }
148
149            assert_eq!(self, other);
151        }
152
153        Some(cmp)
154    }
155}
156
157impl From<LocalEventData> for TaskRef {
158    fn from(data: LocalEventData) -> Self {
159        data.task
160    }
161}
162
163impl PartialOrd for LocalEventData {
164    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
165        let cmp = self.event_id.cmp(&other.event_id);
167
168        if cmp == std::cmp::Ordering::Equal {
171            if self.task != other.task {
172                assert_ne!(self, other);
174                return None;
176            }
177
178            assert_eq!(self, other);
180        }
181
182        Some(cmp)
183    }
184}