GenericChannel: Migrate compositor channels to GenericChannel (#38782)

Besides migrating the channel to GenericChannel, this PR adds
`routed_channel_with_local_sender()` to `generic_channel`. This is for
existing use-cases, where we want to provide both an IPC capable
GenericSender, as well as a crossbeam Sender, for efficient sending if
the sender is in the same process.

Testing: All of our channels should send / receive at least some
messages during WPT tests.

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
Jonathan Schwender 2025-08-25 13:05:21 +02:00 committed by GitHub
parent 7441944e36
commit fb1c0a4c48
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 98 additions and 43 deletions

View file

@ -395,6 +395,18 @@ where
}
}
/// A GenericChannel, which was routed via the Router.
pub struct GenericRoutedChannel<T: Serialize + for<'de> Deserialize<'de>> {
/// A GenericSender of the channel, i.e. it may be sent to other processes in multiprocess mode.
/// Connected to `local_receiver` via the [ROUTER].
pub generic_sender: GenericSender<T>,
/// A sender that directly sends to the local_receiver. Can only be used in the same process
/// as the `local_receiver`.
pub local_sender: crossbeam_channel::Sender<Result<T, ipc_channel::Error>>,
/// The receiving end of the channel. Only usable in the current process.
pub local_receiver: RoutedReceiver<T>,
}
/// Private helper function to create a crossbeam based channel.
///
/// Do NOT make this function public!
@ -435,6 +447,34 @@ where
}
}
/// Returns a [GenericRoutedChannel], where the receiver is usable in the current process,
/// and sending is possible both in remote and local process, via the generic_sender and the
/// local_sender.
pub fn routed_channel_with_local_sender<T>() -> Option<GenericRoutedChannel<T>>
where
T: for<'de> Deserialize<'de> + Serialize + Send + 'static,
{
let (crossbeam_sender, crossbeam_receiver) = crossbeam_channel::unbounded();
let generic_sender = if opts::get().multiprocess || opts::get().force_ipc {
let (ipc_sender, ipc_receiver) = ipc_channel::ipc::channel().ok()?;
let crossbeam_sender_clone = crossbeam_sender.clone();
ROUTER.add_typed_route(
ipc_receiver,
Box::new(move |message| {
let _ = crossbeam_sender_clone.send(message);
}),
);
GenericSender(GenericSenderVariants::Ipc(ipc_sender))
} else {
GenericSender(GenericSenderVariants::Crossbeam(crossbeam_sender.clone()))
};
Some(GenericRoutedChannel {
generic_sender,
local_sender: crossbeam_sender,
local_receiver: crossbeam_receiver,
})
}
#[cfg(test)]
mod single_process_channel_tests {
//! These unit-tests test that ipc_channel and crossbeam_channel Senders and Receivers