servo_base/generic_channel/
generic_channelset.rs1use ipc_channel::ipc::{IpcReceiverSet, IpcSelectionResult};
5use serde::{Deserialize, Serialize};
6use smallvec::SmallVec;
7
8use crate::generic_channel::{GenericReceiver, GenericReceiverVariants, SendError, use_ipc};
9
10pub struct GenericReceiverSet<T: Serialize + for<'de> Deserialize<'de>>(
30 GenericReceiverSetVariants<T>,
31);
32
33impl<T: Serialize + for<'de> Deserialize<'de>> Default for GenericReceiverSet<T> {
34 fn default() -> Self {
35 Self::new()
36 }
37}
38enum GenericReceiverSetVariants<T: for<'de> Deserialize<'de>> {
39 Ipc(ipc_channel::ipc::IpcReceiverSet),
40 Crossbeam(Vec<crossbeam_channel::Receiver<Result<T, SendError>>>),
41}
42
43#[cfg(test)]
44pub fn create_ipc_receiver_set<T: Serialize + for<'de> serde::Deserialize<'de>>()
45-> GenericReceiverSet<T> {
46 GenericReceiverSet(GenericReceiverSetVariants::Ipc(
47 IpcReceiverSet::new().expect("Could not create ipc receiver"),
48 ))
49}
50
51#[cfg(test)]
52pub fn create_crossbeam_receiver_set<T: Serialize + for<'de> serde::Deserialize<'de>>()
53-> GenericReceiverSet<T> {
54 GenericReceiverSet(GenericReceiverSetVariants::Crossbeam(vec![]))
55}
56
57#[derive(Debug, PartialEq)]
59pub enum GenericSelectionResult<T> {
60 MessageReceived(u64, T),
63 ChannelClosed(u64),
65 Error(String),
67}
68
69impl<T: Serialize + for<'de> serde::Deserialize<'de>> From<IpcSelectionResult>
70 for GenericSelectionResult<T>
71{
72 fn from(value: IpcSelectionResult) -> Self {
73 match value {
74 IpcSelectionResult::MessageReceived(channel_id, ipc_message) => {
75 match ipc_message.to() {
76 Ok(value) => GenericSelectionResult::MessageReceived(channel_id, value),
77 Err(error) => GenericSelectionResult::Error(error.to_string()),
78 }
79 },
80 IpcSelectionResult::ChannelClosed(channel_id) => {
81 GenericSelectionResult::ChannelClosed(channel_id)
82 },
83 }
84 }
85}
86
87impl<T: Serialize + for<'de> Deserialize<'de>> GenericReceiverSet<T> {
88 pub fn new() -> GenericReceiverSet<T> {
90 if use_ipc() {
91 GenericReceiverSet(GenericReceiverSetVariants::Ipc(
92 IpcReceiverSet::new().expect("Could not create ipc receiver"),
93 ))
94 } else {
95 GenericReceiverSet(GenericReceiverSetVariants::Crossbeam(vec![]))
96 }
97 }
98
99 pub fn add(&mut self, receiver: GenericReceiver<T>) -> u64 {
101 match (&mut self.0, receiver.0) {
102 (
103 GenericReceiverSetVariants::Ipc(ipc_receiver_set),
104 GenericReceiverVariants::Ipc(ipc_receiver),
105 ) => ipc_receiver_set
106 .add(ipc_receiver)
107 .expect("Could not add channel"),
108 (GenericReceiverSetVariants::Ipc(_), GenericReceiverVariants::Crossbeam(_)) => {
109 unreachable!()
110 },
111 (GenericReceiverSetVariants::Crossbeam(_), GenericReceiverVariants::Ipc(_)) => {
112 unreachable!()
113 },
114 (
115 GenericReceiverSetVariants::Crossbeam(receivers),
116 GenericReceiverVariants::Crossbeam(receiver),
117 ) => {
118 let index = receivers.len() as u64;
119 receivers.push(receiver);
120 index
121 },
122 }
123 }
124
125 pub fn selector(&mut self) -> Selector<'_, T> {
146 let inner = match &mut self.0 {
147 GenericReceiverSetVariants::Ipc(set) => SelectorInner::Ipc(set),
148 GenericReceiverSetVariants::Crossbeam(receivers) => {
149 let mut sel = crossbeam_channel::Select::new();
150 for receiver in receivers.iter() {
151 sel.recv(receiver);
152 }
153 SelectorInner::Crossbeam {
154 receivers: receivers.as_slice(),
155 sel,
156 }
157 },
158 };
159 Selector { inner }
160 }
161
162 pub fn select(&mut self) -> SmallVec<[GenericSelectionResult<T>; 2]> {
167 self.selector().select()
168 }
169}
170
171pub struct Selector<'a, T: Serialize + for<'de> Deserialize<'de>> {
175 inner: SelectorInner<'a, T>,
176}
177
178enum SelectorInner<'a, T: for<'de> Deserialize<'de>> {
179 Ipc(&'a mut IpcReceiverSet),
180 Crossbeam {
181 receivers: &'a [crossbeam_channel::Receiver<Result<T, SendError>>],
182 sel: crossbeam_channel::Select<'a>,
183 },
184}
185
186impl<'a, T: Serialize + for<'de> Deserialize<'de>> Selector<'a, T> {
187 pub fn select(&mut self) -> SmallVec<[GenericSelectionResult<T>; 2]> {
192 match &mut self.inner {
193 SelectorInner::Ipc(ipc_receiver_set) => ipc_receiver_set
194 .select()
195 .map(|result_value| {
196 result_value
197 .into_iter()
198 .map(|selection_result| selection_result.into())
199 .collect()
200 })
201 .unwrap_or_else(|e| {
202 smallvec::smallvec![GenericSelectionResult::Error(e.to_string())]
203 }),
204 SelectorInner::Crossbeam { receivers, sel } => {
205 let selected = sel.select();
206 let index = selected.index();
207 let selection_result = match receivers.get(index) {
208 None => GenericSelectionResult::ChannelClosed(index as u64),
209 Some(receiver) => match selected.recv(receiver) {
210 Ok(Ok(value)) => {
211 GenericSelectionResult::MessageReceived(index as u64, value)
212 },
213 Ok(Err(error)) => GenericSelectionResult::Error(error.to_string()),
214 Err(_) => GenericSelectionResult::ChannelClosed(index as u64),
215 },
216 };
217 smallvec::smallvec![selection_result]
218 },
219 }
220 }
221}