script: Migrate swmanager to GenericChannel (#39076)

Migrate `ServiceWorkerMsg` and `SWManagerMsg` to GenericChannel

Testing: Covered by service worker wpt tests
Part of #38912

Signed-off-by: Jonathan Schwender <schwenderjonathan@gmail.com>
This commit is contained in:
Jonathan Schwender 2025-09-01 21:23:16 +02:00 committed by GitHub
parent 93aeac056b
commit ce8b05738c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 44 additions and 34 deletions

View file

@ -359,17 +359,17 @@ pub struct Constellation<STF, SWF> {
bluetooth_ipc_sender: IpcSender<BluetoothRequest>, bluetooth_ipc_sender: IpcSender<BluetoothRequest>,
/// A map of origin to sender to a Service worker manager. /// A map of origin to sender to a Service worker manager.
sw_managers: HashMap<ImmutableOrigin, IpcSender<ServiceWorkerMsg>>, sw_managers: HashMap<ImmutableOrigin, GenericSender<ServiceWorkerMsg>>,
/// An IPC channel for Service Worker Manager threads to send /// An IPC channel for Service Worker Manager threads to send
/// messages to the constellation. This is the SW Manager thread's /// messages to the constellation. This is the SW Manager thread's
/// view of `swmanager_receiver`. /// view of `swmanager_receiver`.
swmanager_ipc_sender: IpcSender<SWManagerMsg>, swmanager_ipc_sender: GenericSender<SWManagerMsg>,
/// A channel for the constellation to receive messages from the /// A channel for the constellation to receive messages from the
/// Service Worker Manager thread. This is the constellation's view of /// Service Worker Manager thread. This is the constellation's view of
/// `swmanager_sender`. /// `swmanager_sender`.
swmanager_receiver: Receiver<Result<SWManagerMsg, IpcError>>, swmanager_receiver: RoutedReceiver<SWManagerMsg>,
/// A channel for the constellation to send messages to the /// A channel for the constellation to send messages to the
/// time profiler thread. /// time profiler thread.
@ -607,7 +607,7 @@ where
// service worker manager to communicate with constellation // service worker manager to communicate with constellation
let (swmanager_ipc_sender, swmanager_ipc_receiver) = let (swmanager_ipc_sender, swmanager_ipc_receiver) =
ipc::channel().expect("ipc channel failure"); generic_channel::channel().expect("ipc channel failure");
thread::Builder::new() thread::Builder::new()
.name("Constellation".to_owned()) .name("Constellation".to_owned())
@ -653,10 +653,7 @@ where
) )
}; };
let swmanager_receiver = let swmanager_receiver = swmanager_ipc_receiver.route_preserving_errors();
route_ipc_receiver_to_new_crossbeam_receiver_preserving_errors(
swmanager_ipc_receiver,
);
// Zero is reserved for the embedder. // Zero is reserved for the embedder.
PipelineNamespace::install(PipelineNamespaceId(1)); PipelineNamespace::install(PipelineNamespaceId(1));
@ -2447,7 +2444,8 @@ where
let sw_manager = match self.sw_managers.entry(origin.clone()) { let sw_manager = match self.sw_managers.entry(origin.clone()) {
Entry::Occupied(entry) => entry.into_mut(), Entry::Occupied(entry) => entry.into_mut(),
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
let (own_sender, receiver) = ipc::channel().expect("Failed to create IPC channel!"); let (own_sender, receiver) =
generic_channel::channel().expect("Failed to create IPC channel!");
let sw_senders = SWManagerSenders { let sw_senders = SWManagerSenders {
swmanager_sender: self.swmanager_ipc_sender.clone(), swmanager_sender: self.swmanager_ipc_sender.clone(),

View file

@ -155,7 +155,7 @@ pub struct InitialPipelineState {
pub bluetooth_thread: IpcSender<BluetoothRequest>, pub bluetooth_thread: IpcSender<BluetoothRequest>,
/// A channel to the service worker manager thread /// A channel to the service worker manager thread
pub swmanager_thread: IpcSender<SWManagerMsg>, pub swmanager_thread: GenericSender<SWManagerMsg>,
/// A proxy to the system font service, responsible for managing the list of system fonts. /// A proxy to the system font service, responsible for managing the list of system fonts.
pub system_font_service: Arc<SystemFontServiceProxy>, pub system_font_service: Arc<SystemFontServiceProxy>,
@ -481,7 +481,7 @@ pub struct UnprivilegedPipelineContent {
devtools_ipc_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>, devtools_ipc_sender: Option<IpcSender<ScriptToDevtoolsControlMsg>>,
#[cfg(feature = "bluetooth")] #[cfg(feature = "bluetooth")]
bluetooth_thread: IpcSender<BluetoothRequest>, bluetooth_thread: IpcSender<BluetoothRequest>,
swmanager_thread: IpcSender<SWManagerMsg>, swmanager_thread: GenericSender<SWManagerMsg>,
system_font_service: SystemFontServiceProxySender, system_font_service: SystemFontServiceProxySender,
resource_threads: ResourceThreads, resource_threads: ResourceThreads,
time_profiler_chan: time::ProfilerChan, time_profiler_chan: time::ProfilerChan,

View file

@ -7,6 +7,7 @@ use std::sync::atomic::AtomicBool;
use std::thread::{self, JoinHandle}; use std::thread::{self, JoinHandle};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use base::generic_channel::GenericSender;
use base::id::PipelineId; use base::id::PipelineId;
use constellation_traits::{ use constellation_traits::{
ScopeThings, ServiceWorkerMsg, WorkerGlobalScopeInit, WorkerScriptLoadOrigin, ScopeThings, ServiceWorkerMsg, WorkerGlobalScopeInit, WorkerScriptLoadOrigin,
@ -15,7 +16,7 @@ use crossbeam_channel::{Receiver, Sender, after, unbounded};
use devtools_traits::DevtoolScriptControlMsg; use devtools_traits::DevtoolScriptControlMsg;
use dom_struct::dom_struct; use dom_struct::dom_struct;
use fonts::FontContext; use fonts::FontContext;
use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::ipc::IpcReceiver;
use ipc_channel::router::ROUTER; use ipc_channel::router::ROUTER;
use js::jsapi::{JS_AddInterruptCallback, JSContext}; use js::jsapi::{JS_AddInterruptCallback, JSContext};
use js::jsval::UndefinedValue; use js::jsval::UndefinedValue;
@ -161,7 +162,7 @@ pub(crate) struct ServiceWorkerGlobalScope {
#[ignore_malloc_size_of = "Defined in std"] #[ignore_malloc_size_of = "Defined in std"]
#[no_trace] #[no_trace]
swmanager_sender: IpcSender<ServiceWorkerMsg>, swmanager_sender: GenericSender<ServiceWorkerMsg>,
#[no_trace] #[no_trace]
scope_url: ServoUrl, scope_url: ServoUrl,
@ -224,7 +225,7 @@ impl ServiceWorkerGlobalScope {
own_sender: Sender<ServiceWorkerScriptMsg>, own_sender: Sender<ServiceWorkerScriptMsg>,
receiver: Receiver<ServiceWorkerScriptMsg>, receiver: Receiver<ServiceWorkerScriptMsg>,
time_out_port: Receiver<Instant>, time_out_port: Receiver<Instant>,
swmanager_sender: IpcSender<ServiceWorkerMsg>, swmanager_sender: GenericSender<ServiceWorkerMsg>,
scope_url: ServoUrl, scope_url: ServoUrl,
control_receiver: Receiver<ServiceWorkerControlMsg>, control_receiver: Receiver<ServiceWorkerControlMsg>,
closing: Arc<AtomicBool>, closing: Arc<AtomicBool>,
@ -263,7 +264,7 @@ impl ServiceWorkerGlobalScope {
own_sender: Sender<ServiceWorkerScriptMsg>, own_sender: Sender<ServiceWorkerScriptMsg>,
receiver: Receiver<ServiceWorkerScriptMsg>, receiver: Receiver<ServiceWorkerScriptMsg>,
time_out_port: Receiver<Instant>, time_out_port: Receiver<Instant>,
swmanager_sender: IpcSender<ServiceWorkerMsg>, swmanager_sender: GenericSender<ServiceWorkerMsg>,
scope_url: ServoUrl, scope_url: ServoUrl,
control_receiver: Receiver<ServiceWorkerControlMsg>, control_receiver: Receiver<ServiceWorkerControlMsg>,
closing: Arc<AtomicBool>, closing: Arc<AtomicBool>,
@ -293,7 +294,7 @@ impl ServiceWorkerGlobalScope {
own_sender: Sender<ServiceWorkerScriptMsg>, own_sender: Sender<ServiceWorkerScriptMsg>,
receiver: Receiver<ServiceWorkerScriptMsg>, receiver: Receiver<ServiceWorkerScriptMsg>,
devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>, devtools_receiver: IpcReceiver<DevtoolScriptControlMsg>,
swmanager_sender: IpcSender<ServiceWorkerMsg>, swmanager_sender: GenericSender<ServiceWorkerMsg>,
scope_url: ServoUrl, scope_url: ServoUrl,
control_receiver: Receiver<ServiceWorkerControlMsg>, control_receiver: Receiver<ServiceWorkerControlMsg>,
context_sender: Sender<ThreadSafeJSContext>, context_sender: Sender<ThreadSafeJSContext>,

View file

@ -12,14 +12,15 @@ use std::sync::Arc;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
use std::thread::{self, JoinHandle}; use std::thread::{self, JoinHandle};
use base::generic_channel::{self, GenericSender, ReceiveError, RoutedReceiver};
use base::id::{PipelineNamespace, ServiceWorkerId, ServiceWorkerRegistrationId}; use base::id::{PipelineNamespace, ServiceWorkerId, ServiceWorkerRegistrationId};
use constellation_traits::{ use constellation_traits::{
DOMMessage, Job, JobError, JobResult, JobResultValue, JobType, SWManagerMsg, SWManagerSenders, DOMMessage, Job, JobError, JobResult, JobResultValue, JobType, SWManagerMsg, SWManagerSenders,
ScopeThings, ServiceWorkerManagerFactory, ServiceWorkerMsg, ScopeThings, ServiceWorkerManagerFactory, ServiceWorkerMsg,
}; };
use crossbeam_channel::{Receiver, RecvError, Sender, select, unbounded}; use crossbeam_channel::{Receiver, Sender, select, unbounded};
use fonts::FontContext; use fonts::FontContext;
use ipc_channel::ipc::{self, IpcSender}; use ipc_channel::ipc;
use ipc_channel::router::ROUTER; use ipc_channel::router::ROUTER;
use net_traits::{CoreResourceMsg, CustomResponseMediator}; use net_traits::{CoreResourceMsg, CustomResponseMediator};
use servo_config::pref; use servo_config::pref;
@ -217,11 +218,11 @@ pub struct ServiceWorkerManager {
registrations: HashMap<ServoUrl, ServiceWorkerRegistration>, registrations: HashMap<ServoUrl, ServiceWorkerRegistration>,
// Will be useful to implement posting a message to a client. // Will be useful to implement posting a message to a client.
// See https://github.com/servo/servo/issues/24660 // See https://github.com/servo/servo/issues/24660
_constellation_sender: IpcSender<SWManagerMsg>, _constellation_sender: GenericSender<SWManagerMsg>,
// own sender to send messages here // own sender to send messages here
own_sender: IpcSender<ServiceWorkerMsg>, own_sender: GenericSender<ServiceWorkerMsg>,
// receiver to receive messages from constellation // receiver to receive messages from constellation
own_port: Receiver<ServiceWorkerMsg>, own_port: RoutedReceiver<ServiceWorkerMsg>,
// to receive resource messages // to receive resource messages
resource_receiver: Receiver<CustomResponseMediator>, resource_receiver: Receiver<CustomResponseMediator>,
/// A shared [`FontContext`] to use for all service workers spawned by this [`ServiceWorkerManager`]. /// A shared [`FontContext`] to use for all service workers spawned by this [`ServiceWorkerManager`].
@ -230,10 +231,10 @@ pub struct ServiceWorkerManager {
impl ServiceWorkerManager { impl ServiceWorkerManager {
fn new( fn new(
own_sender: IpcSender<ServiceWorkerMsg>, own_sender: GenericSender<ServiceWorkerMsg>,
from_constellation_receiver: Receiver<ServiceWorkerMsg>, from_constellation_receiver: RoutedReceiver<ServiceWorkerMsg>,
resource_port: Receiver<CustomResponseMediator>, resource_port: Receiver<CustomResponseMediator>,
constellation_sender: IpcSender<SWManagerMsg>, constellation_sender: GenericSender<SWManagerMsg>,
font_context: Arc<FontContext>, font_context: Arc<FontContext>,
) -> ServiceWorkerManager { ) -> ServiceWorkerManager {
// Install a pipeline-namespace in the current thread. // Install a pipeline-namespace in the current thread.
@ -289,10 +290,10 @@ impl ServiceWorkerManager {
true true
} }
fn receive_message(&mut self) -> Result<Message, RecvError> { fn receive_message(&mut self) -> generic_channel::ReceiveResult<Message> {
select! { select! {
recv(self.own_port) -> msg => msg.map(|m| Message::FromConstellation(Box::new(m))), recv(self.own_port) -> result_msg => generic_channel::to_receive_result::<ServiceWorkerMsg>(result_msg).map(|msg| Message::FromConstellation(Box::new(msg))),
recv(self.resource_receiver) -> msg => msg.map(Message::FromResource), recv(self.resource_receiver) -> msg => msg.map(Message::FromResource).map_err(|_e| ReceiveError::Disconnected),
} }
} }
@ -452,7 +453,7 @@ impl ServiceWorkerManager {
/// <https://w3c.github.io/ServiceWorker/#update-algorithm> /// <https://w3c.github.io/ServiceWorker/#update-algorithm>
fn update_serviceworker( fn update_serviceworker(
own_sender: IpcSender<ServiceWorkerMsg>, own_sender: GenericSender<ServiceWorkerMsg>,
scope_url: ServoUrl, scope_url: ServoUrl,
scope_things: ScopeThings, scope_things: ScopeThings,
font_context: Arc<FontContext>, font_context: Arc<FontContext>,
@ -510,7 +511,7 @@ impl ServiceWorkerManagerFactory for ServiceWorkerManager {
compositor_api, compositor_api,
} = sw_senders; } = sw_senders;
let from_constellation = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(receiver); let from_constellation = receiver.route_preserving_errors();
let resource_port = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(resource_port); let resource_port = ROUTER.route_ipc_receiver_to_new_crossbeam_receiver(resource_port);
let _ = resource_threads let _ = resource_threads
.core_thread .core_thread

View file

@ -252,6 +252,16 @@ impl From<crossbeam_channel::TryRecvError> for TryReceiveError {
pub type RoutedReceiver<T> = crossbeam_channel::Receiver<Result<T, ipc_channel::Error>>; pub type RoutedReceiver<T> = crossbeam_channel::Receiver<Result<T, ipc_channel::Error>>;
pub type ReceiveResult<T> = Result<T, ReceiveError>; pub type ReceiveResult<T> = Result<T, ReceiveError>;
pub type TryReceiveResult<T> = Result<T, TryReceiveError>; pub type TryReceiveResult<T> = Result<T, TryReceiveError>;
pub type RoutedReceiverReceiveResult<T> =
Result<Result<T, ipc_channel::Error>, crossbeam_channel::RecvError>;
pub fn to_receive_result<T>(receive_result: RoutedReceiverReceiveResult<T>) -> ReceiveResult<T> {
match receive_result {
Ok(Ok(msg)) => Ok(msg),
Err(_crossbeam_recv_err) => Err(ReceiveError::Disconnected),
Ok(Err(ipc_err)) => Err(ReceiveError::DeserializationFailed(ipc_err.to_string())),
}
}
pub struct GenericReceiver<T>(GenericReceiverVariants<T>) pub struct GenericReceiver<T>(GenericReceiverVariants<T>)
where where

View file

@ -8,7 +8,7 @@ use std::collections::HashMap;
use std::fmt; use std::fmt;
use base::Epoch; use base::Epoch;
use base::generic_channel::{GenericCallback, GenericSender, SendResult}; use base::generic_channel::{GenericCallback, GenericReceiver, GenericSender, SendResult};
use base::id::{ use base::id::{
BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId, BroadcastChannelRouterId, BrowsingContextId, HistoryStateId, MessagePortId,
MessagePortRouterId, PipelineId, ServiceWorkerId, ServiceWorkerRegistrationId, WebViewId, MessagePortRouterId, PipelineId, ServiceWorkerId, ServiceWorkerRegistrationId, WebViewId,
@ -24,7 +24,7 @@ use embedder_traits::{
use euclid::default::Size2D as UntypedSize2D; use euclid::default::Size2D as UntypedSize2D;
use fonts_traits::SystemFontServiceProxySender; use fonts_traits::SystemFontServiceProxySender;
use http::{HeaderMap, Method}; use http::{HeaderMap, Method};
use ipc_channel::ipc::{IpcReceiver, IpcSender}; use ipc_channel::ipc::IpcSender;
use malloc_size_of_derive::MallocSizeOf; use malloc_size_of_derive::MallocSizeOf;
use net_traits::policy_container::PolicyContainer; use net_traits::policy_container::PolicyContainer;
use net_traits::request::{Destination, InsecureRequestsPolicy, Referrer, RequestBody}; use net_traits::request::{Destination, InsecureRequestsPolicy, Referrer, RequestBody};
@ -206,7 +206,7 @@ pub struct DOMMessage {
#[derive(Deserialize, Serialize)] #[derive(Deserialize, Serialize)]
pub struct SWManagerSenders { pub struct SWManagerSenders {
/// Sender of messages to the constellation. /// Sender of messages to the constellation.
pub swmanager_sender: IpcSender<SWManagerMsg>, pub swmanager_sender: GenericSender<SWManagerMsg>,
/// [`ResourceThreads`] for initating fetches or using i/o. /// [`ResourceThreads`] for initating fetches or using i/o.
pub resource_threads: ResourceThreads, pub resource_threads: ResourceThreads,
/// [`CrossProcessCompositorApi`] for communicating with the compositor. /// [`CrossProcessCompositorApi`] for communicating with the compositor.
@ -214,9 +214,9 @@ pub struct SWManagerSenders {
/// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`. /// The [`SystemFontServiceProxy`] used to communicate with the `SystemFontService`.
pub system_font_service_sender: SystemFontServiceProxySender, pub system_font_service_sender: SystemFontServiceProxySender,
/// Sender of messages to the manager. /// Sender of messages to the manager.
pub own_sender: IpcSender<ServiceWorkerMsg>, pub own_sender: GenericSender<ServiceWorkerMsg>,
/// Receiver of messages from the constellation. /// Receiver of messages from the constellation.
pub receiver: IpcReceiver<ServiceWorkerMsg>, pub receiver: GenericReceiver<ServiceWorkerMsg>,
} }
/// Messages sent to Service Worker Manager thread /// Messages sent to Service Worker Manager thread