fuchsia_async/runtime/fuchsia/executor/
packets.rs1use rustc_hash::FxHashMap as HashMap;
6use std::ops::Deref;
7use std::sync::Arc;
8
9use super::common::EHandle;
10
11pub trait PacketReceiver: Send + Sync + 'static {
28 fn receive_packet(&self, packet: zx::Packet);
30}
31
32pub(crate) struct PacketReceiverMap<T> {
35 next_key: u64,
36 pub mapping: HashMap<u64, T>,
37}
38
39impl<T> PacketReceiverMap<T> {
40 pub fn new() -> Self {
41 Self { next_key: 0, mapping: HashMap::default() }
42 }
43
44 pub fn get(&self, key: u64) -> Option<&T> {
45 self.mapping.get(&key)
46 }
47
48 pub fn insert<R>(&mut self, val: impl FnOnce(u64) -> (T, R)) -> R {
49 let key = self.next_key;
50 self.next_key = self.next_key.checked_add(1).expect("ran out of keys");
51 let (val, out) = val(key);
52 self.mapping.insert(key, val);
53 out
54 }
55
56 pub fn remove(&mut self, key: u64) -> T {
57 self.mapping.remove(&key).unwrap_or_else(|| panic!("invalid key"))
58 }
59
60 pub fn contains(&self, key: u64) -> bool {
61 self.mapping.contains_key(&key)
62 }
63}
64
65#[derive(Debug)]
69pub struct ReceiverRegistration<T: PacketReceiver> {
70 pub(super) receiver: Arc<T>,
71 pub(super) ehandle: EHandle,
72 pub(super) key: u64,
73}
74
75impl<T> ReceiverRegistration<T>
76where
77 T: PacketReceiver,
78{
79 pub fn key(&self) -> u64 {
81 self.key
82 }
83
84 pub fn receiver(&self) -> &T {
86 &*self.receiver
87 }
88
89 pub fn port(&self) -> &zx::Port {
91 self.ehandle.port()
92 }
93}
94
95impl<T: PacketReceiver> Deref for ReceiverRegistration<T> {
96 type Target = T;
97 fn deref(&self) -> &Self::Target {
98 self.receiver()
99 }
100}
101
102impl<T> Drop for ReceiverRegistration<T>
103where
104 T: PacketReceiver,
105{
106 fn drop(&mut self) {
107 self.ehandle.deregister_receiver(self.key);
108 }
109}
110
111#[cfg(test)]
112mod tests {
113 use super::*;
114
115 #[test]
116 fn packet_receiver_map_does_not_reuse_keys() {
117 #[derive(Debug, Copy, Clone, PartialEq)]
118 struct DummyPacketReceiver {
119 id: i32,
120 }
121 let mut map = PacketReceiverMap::<DummyPacketReceiver>::new();
122 let e1 = DummyPacketReceiver { id: 1 };
123 assert_eq!(map.insert(|key| (e1, key)), 0);
124 assert_eq!(map.insert(|key| (e1, key)), 1);
125
126 map.remove(1);
128 assert_eq!(map.insert(|key| (e1, key)), 2);
129 }
130}