mirror of
https://github.com/servo/servo.git
synced 2025-09-27 23:30:08 +01:00
base: Allow sending GenericReceiver (#38636)
Implement Serialize and Deserialize for GenericReceiver to also allow the Receiver to be sent across ipc channels. This is necessary to allow using the GenericChannel in more places. Testing: Manually tested on follow-up feature branch. Does not require new tests. --------- Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com> Signed-off-by: Jonathan Schwender <55576758+jschwe@users.noreply.github.com> Co-authored-by: Martin Robinson <mrobinson@igalia.com>
This commit is contained in:
parent
b5932e5abf
commit
f492cbf8c1
1 changed files with 35 additions and 3 deletions
|
@ -9,6 +9,10 @@ use std::fmt;
|
|||
use ipc_channel::router::ROUTER;
|
||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||
|
||||
static GENERIC_CHANNEL_USAGE_ERROR_PANIC_MSG: &str = "May not send a crossbeam channel over an IPC channel. \
|
||||
Please also convert the ipc-channel you want to send this GenericReceiver over \
|
||||
into a GenericChannel.";
|
||||
|
||||
pub enum GenericSender<T: Serialize> {
|
||||
Ipc(ipc_channel::ipc::IpcSender<T>),
|
||||
Crossbeam(crossbeam_channel::Sender<T>),
|
||||
|
@ -18,7 +22,7 @@ impl<T: Serialize> Serialize for GenericSender<T> {
|
|||
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
||||
match self {
|
||||
GenericSender::Ipc(i) => i.serialize(s),
|
||||
GenericSender::Crossbeam(_) => unreachable!(),
|
||||
GenericSender::Crossbeam(_) => panic!("{GENERIC_CHANNEL_USAGE_ERROR_PANIC_MSG}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -28,8 +32,8 @@ impl<'a, T: Serialize> Deserialize<'a> for GenericSender<T> {
|
|||
where
|
||||
D: Deserializer<'a>,
|
||||
{
|
||||
// Only ipc_channle will encounter deserialize scenario.
|
||||
ipc_channel::ipc::IpcSender::<T>::deserialize(d).map(|s| GenericSender::Ipc(s))
|
||||
// Only ipc_channel will encounter deserialize scenario.
|
||||
ipc_channel::ipc::IpcSender::<T>::deserialize(d).map(GenericSender::Ipc)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -81,6 +85,7 @@ impl<T> GenericReceiver<T>
|
|||
where
|
||||
T: for<'de> Deserialize<'de> + Serialize,
|
||||
{
|
||||
#[inline]
|
||||
pub fn recv(&self) -> ReceiveResult<T> {
|
||||
match *self {
|
||||
GenericReceiver::Ipc(ref receiver) => receiver.recv().map_err(|_| ReceiveError),
|
||||
|
@ -88,6 +93,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn try_recv(&self) -> ReceiveResult<T> {
|
||||
match *self {
|
||||
GenericReceiver::Ipc(ref receiver) => receiver.try_recv().map_err(|_| ReceiveError),
|
||||
|
@ -97,6 +103,7 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn into_inner(self) -> crossbeam_channel::Receiver<T>
|
||||
where
|
||||
T: Send + 'static,
|
||||
|
@ -110,6 +117,31 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
impl<T> Serialize for GenericReceiver<T>
|
||||
where
|
||||
T: for<'de> Deserialize<'de> + Serialize,
|
||||
{
|
||||
fn serialize<S: Serializer>(&self, s: S) -> Result<S::Ok, S::Error> {
|
||||
match self {
|
||||
GenericReceiver::Ipc(receiver) => receiver.serialize(s),
|
||||
GenericReceiver::Crossbeam(_) => panic!("{GENERIC_CHANNEL_USAGE_ERROR_PANIC_MSG}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T> Deserialize<'a> for GenericReceiver<T>
|
||||
where
|
||||
T: for<'de> Deserialize<'de> + Serialize,
|
||||
{
|
||||
fn deserialize<D>(d: D) -> Result<GenericReceiver<T>, D::Error>
|
||||
where
|
||||
D: Deserializer<'a>,
|
||||
{
|
||||
// Only ipc_channel will encounter deserialize scenario.
|
||||
ipc_channel::ipc::IpcReceiver::<T>::deserialize(d).map(GenericReceiver::Ipc)
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates a Servo channel that can select different channel implementations based on multiprocess
|
||||
/// mode or not. If the scenario doesn't require message to pass process boundary, a simple
|
||||
/// crossbeam channel is preferred.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue