use crate::mux::error::MuxError;
use ipc_channel::ipc::{
IpcReceiver as RawIpcReceiver, IpcSender as RawIpcSender, OpaqueIpcReceiver, OpaqueIpcSender,
};
use serde::{Deserialize, Deserializer, Serialize, Serializer};
use std::cell::RefCell;
use std::marker::PhantomData;
pub struct SyncOpaqueIpcReceiver(OpaqueIpcReceiver);
unsafe impl Sync for SyncOpaqueIpcReceiver {}
impl SyncOpaqueIpcReceiver {
pub fn new(r: OpaqueIpcReceiver) -> Self {
Self(r)
}
pub fn into_inner(self) -> OpaqueIpcReceiver {
self.0
}
}
impl std::fmt::Debug for SyncOpaqueIpcReceiver {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_tuple("SyncOpaqueIpcReceiver").finish()
}
}
impl Serialize for SyncOpaqueIpcReceiver {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.0.serialize(serializer)
}
}
impl<'de> Deserialize<'de> for SyncOpaqueIpcReceiver {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
OpaqueIpcReceiver::deserialize(deserializer).map(SyncOpaqueIpcReceiver)
}
}
thread_local! {
static IPC_SENDERS_FOR_SER: RefCell<Vec<OpaqueIpcSender>> = const { RefCell::new(Vec::new()) };
static IPC_RECEIVERS_FOR_SER: RefCell<Vec<SyncOpaqueIpcReceiver>> = const { RefCell::new(Vec::new()) };
static IPC_SENDERS_FOR_DE: RefCell<Vec<Option<OpaqueIpcSender>>> = const { RefCell::new(Vec::new()) };
static IPC_RECEIVERS_FOR_DE: RefCell<Vec<Option<OpaqueIpcReceiver>>> = const { RefCell::new(Vec::new()) };
}
pub struct IpcSender<T>(OpaqueIpcSender, PhantomData<T>);
impl<T> Clone for IpcSender<T> {
fn clone(&self) -> Self {
IpcSender(self.0.clone(), PhantomData)
}
}
impl<T: Serialize + for<'de> Deserialize<'de>> From<RawIpcSender<T>> for IpcSender<T> {
fn from(sender: RawIpcSender<T>) -> Self {
IpcSender(sender.to_opaque(), PhantomData)
}
}
impl<T: Serialize + for<'de> Deserialize<'de>> IpcSender<T> {
pub fn into_inner(self) -> RawIpcSender<T> {
self.0.to::<T>()
}
}
impl<T> Serialize for IpcSender<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let index = IPC_SENDERS_FOR_SER.with(|senders| {
let mut senders = senders.borrow_mut();
let idx = senders.len();
senders.push(self.0.clone());
idx
});
index.serialize(serializer)
}
}
impl<'de, T: Serialize + Deserialize<'de>> Deserialize<'de> for IpcSender<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let index: usize = Deserialize::deserialize(deserializer)?;
let opaque = IPC_SENDERS_FOR_DE
.with(|senders| {
let mut senders = senders.borrow_mut();
senders
.get_mut(index)
.and_then(Option::take)
.ok_or_else(|| {
format!(
"IpcSender {index} not available \
(have {} senders)",
senders.len()
)
})
})
.map_err(serde::de::Error::custom)?;
Ok(IpcSender(opaque, PhantomData))
}
}
pub struct IpcReceiver<T>(RefCell<Option<OpaqueIpcReceiver>>, PhantomData<T>);
impl<T: Serialize + for<'de> Deserialize<'de>> From<RawIpcReceiver<T>> for IpcReceiver<T> {
fn from(receiver: RawIpcReceiver<T>) -> Self {
IpcReceiver(RefCell::new(Some(receiver.to_opaque())), PhantomData)
}
}
impl<T: Serialize + for<'de> Deserialize<'de>> IpcReceiver<T> {
pub fn into_inner(self) -> Result<RawIpcReceiver<T>, MuxError> {
self.0
.into_inner()
.ok_or_else(|| MuxError::InternalError("IpcReceiver already serialized".to_string()))
.map(OpaqueIpcReceiver::to::<T>)
}
}
impl<T> Serialize for IpcReceiver<T> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
let opaque = self
.0
.borrow_mut()
.take()
.ok_or_else(|| serde::ser::Error::custom("IpcReceiver already serialized"))?;
let index = IPC_RECEIVERS_FOR_SER.with(|receivers| {
let mut receivers = receivers.borrow_mut();
let idx = receivers.len();
receivers.push(SyncOpaqueIpcReceiver(opaque));
idx
});
index.serialize(serializer)
}
}
impl<'de, T: Serialize + Deserialize<'de>> Deserialize<'de> for IpcReceiver<T> {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
let index: usize = Deserialize::deserialize(deserializer)?;
let opaque = IPC_RECEIVERS_FOR_DE
.with(|receivers| {
let mut receivers = receivers.borrow_mut();
receivers
.get_mut(index)
.and_then(Option::take)
.ok_or_else(|| {
format!(
"IpcReceiver {index} not available \
(have {} receivers)",
receivers.len()
)
})
})
.map_err(serde::de::Error::custom)?;
Ok(IpcReceiver(RefCell::new(Some(opaque)), PhantomData))
}
}
pub fn clear_ipc_sender_serialization_context() {
IPC_SENDERS_FOR_SER.with(|s| s.borrow_mut().clear());
}
pub fn clear_ipc_receiver_serialization_context() {
IPC_RECEIVERS_FOR_SER.with(|r| r.borrow_mut().clear());
}
pub fn take_ipc_senders_for_send() -> Vec<OpaqueIpcSender> {
IPC_SENDERS_FOR_SER.with(|s| std::mem::take(&mut *s.borrow_mut()))
}
pub fn take_ipc_receivers_for_send() -> Vec<SyncOpaqueIpcReceiver> {
IPC_RECEIVERS_FOR_SER.with(|r| std::mem::take(&mut *r.borrow_mut()))
}
pub fn set_ipc_senders_for_recv(senders: Vec<OpaqueIpcSender>) {
IPC_SENDERS_FOR_DE.with(|s| {
*s.borrow_mut() = senders.into_iter().map(Some).collect();
});
}
pub fn set_ipc_receivers_for_recv(receivers: Vec<SyncOpaqueIpcReceiver>) {
IPC_RECEIVERS_FOR_DE.with(|r| {
*r.borrow_mut() = receivers.into_iter().map(|r| Some(r.0)).collect();
});
}
pub fn clear_ipc_sender_deserialization_context() {
IPC_SENDERS_FOR_DE.with(|s| s.borrow_mut().clear());
}
pub fn clear_ipc_receiver_deserialization_context() {
IPC_RECEIVERS_FOR_DE.with(|r| r.borrow_mut().clear());
}