EmbedderMsg: port reply channels to GenericChannel (#39018)

This change ports all `EmbedderMsg` reply channels that don't use the
`ROUTER` to GenericChannel.
The remaining reply channels that use the router are blocked until
#38973 is merged.
This is a breaking change in the API between libservo and embedders.

Future work: A lot of the reply channels in this PR look like they
conceptually should be oneshot ipc channels. It might make sense to
provide a `OneshotGenericChannel` abstraction that encodes this.

Testing: No functional changes - covered by existing tests. None of the
channels changed here uses the Router
Part of #38912

---------

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
Jonathan Schwender 2025-08-29 14:44:21 +02:00 committed by GitHub
parent 89e1357c75
commit 66d9f957e6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 107 additions and 95 deletions

View file

@ -12,9 +12,9 @@ use std::str::FromStr;
use std::sync::{LazyLock, Mutex};
use std::time::Duration;
use base::Epoch;
use base::cross_process_instant::CrossProcessInstant;
use base::id::WebViewId;
use base::{Epoch, generic_channel};
use canvas_traits::canvas::CanvasId;
use canvas_traits::webgl::{WebGLContextId, WebGLMsg};
use chrono::Local;
@ -32,7 +32,6 @@ use euclid::default::{Rect, Size2D};
use fnv::FnvHashMap;
use html5ever::{LocalName, Namespace, QualName, local_name, ns};
use hyper_serde::Serde;
use ipc_channel::ipc;
use js::rust::{HandleObject, HandleValue, MutableHandleValue};
use layout_api::{PendingRestyle, ReflowGoal, ReflowPhasesRun, RestyleReason, TrustedNodeAddress};
use metrics::{InteractiveFlag, InteractiveWindow, ProgressiveWebMetrics};
@ -1929,7 +1928,7 @@ impl Document {
.ReturnValue()
.is_empty();
if default_prevented || return_value_not_empty {
let (chan, port) = ipc::channel().expect("Failed to create IPC channel!");
let (chan, port) = generic_channel::channel().expect("Failed to create IPC channel!");
let msg = EmbedderMsg::AllowUnload(self.webview_id(), chan);
self.send_to_embedder(msg);
can_unload = port.recv().unwrap() == AllowOrDeny::Allow;

View file

@ -9,6 +9,7 @@ use std::mem;
use std::rc::Rc;
use std::time::{Duration, Instant};
use base::generic_channel;
use constellation_traits::ScriptToConstellationMessage;
use embedder_traits::{
Cursor, EditingActionEvent, EmbedderMsg, GamepadEvent as EmbedderGamepadEvent,
@ -689,7 +690,8 @@ impl DocumentEventHandler {
// Step 4. If result is true, then show the UA context menu
if result {
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel.");
let (sender, receiver) =
generic_channel::channel().expect("Failed to create IPC channel.");
self.window.send_to_embedder(EmbedderMsg::ShowContextMenu(
self.window.webview_id(),
sender,

View file

@ -11,6 +11,7 @@ use std::ptr::NonNull;
use std::str::FromStr;
use std::{f64, ptr};
use base::generic_channel;
use dom_struct::dom_struct;
use embedder_traits::{
EmbedderMsg, FilterPattern, FormControl as EmbedderFormControl, InputMethodType, RgbColor,
@ -18,7 +19,6 @@ use embedder_traits::{
use encoding_rs::Encoding;
use euclid::{Point2D, Rect, Size2D};
use html5ever::{LocalName, Prefix, local_name, ns};
use ipc_channel::ipc;
use js::jsapi::{
ClippedTime, DateGetMsecSinceEpoch, Handle, JS_ClearPendingException, JSObject, NewDateObject,
NewUCRegExpObject, ObjectIsDate, RegExpFlag_UnicodeSets, RegExpFlags,
@ -2786,8 +2786,8 @@ impl HTMLInputElement {
// Step 6. Otherwise, the user agent should show the relevant user interface for selecting a value for element,
// in the way it normally would when the user interacts with the control.
if self.input_type() == InputType::Color {
let (ipc_sender, ipc_receiver) =
ipc::channel::<Option<RgbColor>>().expect("Failed to create IPC channel!");
let (ipc_sender, ipc_receiver) = generic_channel::channel::<Option<RgbColor>>()
.expect("Failed to create IPC channel!");
let document = self.owner_document();
let rect = self.upcast::<Node>().border_box().unwrap_or_default();
let rect = Rect::new(

View file

@ -10,12 +10,11 @@ use embedder_traits::{EmbedderMsg, FormControl as EmbedderFormControl};
use embedder_traits::{SelectElementOption, SelectElementOptionOrOptgroup};
use euclid::{Point2D, Rect, Size2D};
use html5ever::{LocalName, Prefix, local_name};
use ipc_channel::ipc;
use js::rust::HandleObject;
use style::attr::AttrValue;
use stylo_dom::ElementState;
use webrender_api::units::DeviceIntRect;
use base::generic_channel;
use crate::dom::bindings::refcounted::Trusted;
use crate::dom::event::{EventBubbles, EventCancelable, EventComposed};
use crate::dom::bindings::codegen::GenericBindings::HTMLOptGroupElementBinding::HTMLOptGroupElement_Binding::HTMLOptGroupElementMethods;
@ -340,7 +339,8 @@ impl HTMLSelectElement {
}
pub(crate) fn show_menu(&self) -> Option<usize> {
let (ipc_sender, ipc_receiver) = ipc::channel().expect("Failed to create IPC channel!");
let (ipc_sender, ipc_receiver) =
generic_channel::channel().expect("Failed to create IPC channel!");
// Collect list of optgroups and options
let mut index = 0;

View file

@ -4,9 +4,9 @@
use std::rc::Rc;
use base::generic_channel;
use dom_struct::dom_struct;
use embedder_traits::{self, AllowOrDeny, EmbedderMsg, PermissionFeature};
use ipc_channel::ipc;
use js::conversions::ConversionResult;
use js::jsapi::JSObject;
use js::jsval::{ObjectValue, UndefinedValue};
@ -350,7 +350,7 @@ fn prompt_user_from_embedder(name: PermissionName, global_scope: &GlobalScope) -
warn!("Requesting permissions from non-webview-associated global scope");
return PermissionState::Denied;
};
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel!");
global_scope.send_to_embedder(EmbedderMsg::PromptPermission(
webview_id,
name.convert(),

View file

@ -2,9 +2,9 @@
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
use base::generic_channel;
use dom_struct::dom_struct;
use embedder_traits::{EmbedderMsg, ScreenMetrics};
use ipc_channel::ipc;
use crate::dom::bindings::codegen::Bindings::ScreenBinding::ScreenMethods;
use crate::dom::bindings::num::Finite;
@ -33,7 +33,7 @@ impl Screen {
/// Retrives [`ScreenMetrics`] from the embedder.
fn screen_metrics(&self) -> ScreenMetrics {
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel!");
self.window.send_to_embedder(EmbedderMsg::GetScreenMetrics(
self.window.webview_id(),

View file

@ -17,6 +17,7 @@ use std::time::{Duration, Instant};
use app_units::Au;
use backtrace::Backtrace;
use base::cross_process_instant::CrossProcessInstant;
use base::generic_channel;
use base::generic_channel::GenericSender;
use base::id::{BrowsingContextId, PipelineId, WebViewId};
use base64::Engine;
@ -67,7 +68,7 @@ use net_traits::image_cache::{
};
use net_traits::storage_thread::StorageType;
use num_traits::ToPrimitive;
use profile_traits::ipc as ProfiledIpc;
use profile_traits::generic_channel as ProfiledGenericChannel;
use profile_traits::mem::ProfilerChan as MemProfilerChan;
use profile_traits::time::ProfilerChan as TimeProfilerChan;
use script_bindings::conversions::SafeToJSValConvertible;
@ -862,7 +863,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
stderr.flush().unwrap();
}
let (sender, receiver) =
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
ProfiledGenericChannel::channel(self.global().time_profiler_chan().clone()).unwrap();
let dialog = SimpleDialog::Alert {
message: s.to_string(),
response_sender: sender,
@ -879,7 +880,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
// https://html.spec.whatwg.org/multipage/#dom-confirm
fn Confirm(&self, s: DOMString) -> bool {
let (sender, receiver) =
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
ProfiledGenericChannel::channel(self.global().time_profiler_chan().clone()).unwrap();
let dialog = SimpleDialog::Confirm {
message: s.to_string(),
response_sender: sender,
@ -899,7 +900,7 @@ impl WindowMethods<crate::DomTypeHolder> for Window {
// https://html.spec.whatwg.org/multipage/#dom-prompt
fn Prompt(&self, message: DOMString, default: DOMString) -> Option<DOMString> {
let (sender, receiver) =
ProfiledIpc::channel(self.global().time_profiler_chan().clone()).unwrap();
ProfiledGenericChannel::channel(self.global().time_profiler_chan().clone()).unwrap();
let dialog = SimpleDialog::Prompt {
message: message.to_string(),
default: default.to_string(),
@ -2137,7 +2138,7 @@ impl Window {
}
fn client_window(&self) -> DeviceIndependentIntRect {
let (sender, receiver) = ipc::channel().expect("Failed to create IPC channel!");
let (sender, receiver) = generic_channel::channel().expect("Failed to create IPC channel!");
self.send_to_embedder(EmbedderMsg::GetWindowRect(self.webview_id(), sender));