base/generic_channel/
oneshot.rs1use std::fmt;
6use std::marker::PhantomData;
7
8use serde::{Deserialize, Deserializer, Serialize, Serializer};
9
10use crate::generic_channel::{
11 GenericReceiverVariants, GenericSenderVariants, GenericSenderVisitor, ReceiveResult, SendError,
12 SendResult, serialize_generic_sender_variants,
13};
14
15pub struct GenericOneshotSender<T: Serialize>(GenericSenderVariants<T>);
17
18impl<T: Serialize> GenericOneshotSender<T> {
19 #[inline]
20 pub fn send(self, msg: T) -> SendResult {
22 match self.0 {
23 GenericSenderVariants::Ipc(ref sender) => sender
24 .send(msg)
25 .map_err(|e| SendError::SerializationError(format!("{e}"))),
26 GenericSenderVariants::Crossbeam(ref sender) => {
27 sender.send(Ok(msg)).map_err(|_| SendError::Disconnected)
28 },
29 }
30 }
31}
32
33impl<T> GenericOneshotReceiver<T>
34where
35 T: for<'de> Deserialize<'de> + Serialize,
36{
37 #[inline]
38 pub fn recv(self) -> ReceiveResult<T> {
40 match self.0 {
41 GenericReceiverVariants::Ipc(ref receiver) => Ok(receiver.recv()?),
42 GenericReceiverVariants::Crossbeam(ref receiver) => {
43 let msg = receiver.recv()?;
45 Ok(msg.expect("Infallible"))
48 },
49 }
50 }
51}
52
53pub struct GenericOneshotReceiver<T: Serialize + for<'de> Deserialize<'de>>(
55 GenericReceiverVariants<T>,
56);
57
58pub fn oneshot<T>() -> Option<(GenericOneshotSender<T>, GenericOneshotReceiver<T>)>
62where
63 T: for<'de> Deserialize<'de> + Serialize,
64{
65 if servo_config::opts::get().multiprocess || servo_config::opts::get().force_ipc {
66 ipc_channel::ipc::channel()
67 .map(|(tx, rx)| {
68 (
69 GenericOneshotSender(GenericSenderVariants::Ipc(tx)),
70 GenericOneshotReceiver(GenericReceiverVariants::Ipc(rx)),
71 )
72 })
73 .ok()
74 } else {
75 let (rx, tx) = crossbeam_channel::bounded(1);
76 Some((
77 GenericOneshotSender(GenericSenderVariants::Crossbeam(rx)),
78 GenericOneshotReceiver(GenericReceiverVariants::Crossbeam(tx)),
79 ))
80 }
81}
82
83impl<T: Serialize> Serialize for GenericOneshotSender<T> {
84 fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
85 serialize_generic_sender_variants(&self.0, s)
86 }
87}
88
89impl<'a, T: Serialize + Deserialize<'a>> Deserialize<'a> for GenericOneshotSender<T> {
90 fn deserialize<D>(d: D) -> Result<GenericOneshotSender<T>, D::Error>
91 where
92 D: Deserializer<'a>,
93 {
94 d.deserialize_enum(
95 "GenericSender",
96 &["Ipc", "Crossbeam"],
97 GenericSenderVisitor {
98 marker: PhantomData,
99 },
100 )
101 .map(|variant| GenericOneshotSender(variant))
102 }
103}
104
105impl<T: Serialize> fmt::Debug for GenericOneshotSender<T> {
106 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
107 write!(f, "Sender(..)")
108 }
109}