mirror of
https://github.com/servo/servo.git
synced 2025-09-08 14:08:22 +01:00
fix: Store channel reference in CookieStore to prevent panic on unload (#39171)
CookieStore sets up a route with the resource threads to handle async communication and needs to later unregister itself when the page unloads. When attempting to do this in the `Drop` of CookieStore we panic attempting to retrieve the channel via `self.global().resource_threads()` because global is already null. This change stores a reference to the core resource thread in the object to send the unregister on `Drop`. Testing: manual testing for crash fix, behavior should be unchanged Signed-off-by: Sebastian C <sebsebmc@gmail.com>
This commit is contained in:
parent
7ce0bd8575
commit
d3809c1024
1 changed files with 14 additions and 4 deletions
|
@ -11,6 +11,7 @@ use cookie::{Cookie, SameSite};
|
||||||
use dom_struct::dom_struct;
|
use dom_struct::dom_struct;
|
||||||
use hyper_serde::Serde;
|
use hyper_serde::Serde;
|
||||||
use ipc_channel::ipc;
|
use ipc_channel::ipc;
|
||||||
|
use ipc_channel::ipc::IpcSender;
|
||||||
use ipc_channel::router::ROUTER;
|
use ipc_channel::router::ROUTER;
|
||||||
use itertools::Itertools;
|
use itertools::Itertools;
|
||||||
use js::jsval::NullValue;
|
use js::jsval::NullValue;
|
||||||
|
@ -46,6 +47,9 @@ pub(crate) struct CookieStore {
|
||||||
// Store an id so that we can send it with requests and the resource thread knows who to respond to
|
// Store an id so that we can send it with requests and the resource thread knows who to respond to
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
store_id: CookieStoreId,
|
store_id: CookieStoreId,
|
||||||
|
#[ignore_malloc_size_of = "Channels are hard"]
|
||||||
|
#[no_trace]
|
||||||
|
unregister_channel: IpcSender<CoreResourceMsg>,
|
||||||
}
|
}
|
||||||
|
|
||||||
struct CookieListener {
|
struct CookieListener {
|
||||||
|
@ -92,16 +96,23 @@ impl CookieListener {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CookieStore {
|
impl CookieStore {
|
||||||
fn new_inherited() -> CookieStore {
|
fn new_inherited(unregister_channel: IpcSender<CoreResourceMsg>) -> CookieStore {
|
||||||
CookieStore {
|
CookieStore {
|
||||||
eventtarget: EventTarget::new_inherited(),
|
eventtarget: EventTarget::new_inherited(),
|
||||||
in_flight: Default::default(),
|
in_flight: Default::default(),
|
||||||
store_id: CookieStoreId::new(),
|
store_id: CookieStoreId::new(),
|
||||||
|
unregister_channel,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<CookieStore> {
|
pub(crate) fn new(global: &GlobalScope, can_gc: CanGc) -> DomRoot<CookieStore> {
|
||||||
let store = reflect_dom_object(Box::new(CookieStore::new_inherited()), global, can_gc);
|
let store = reflect_dom_object(
|
||||||
|
Box::new(CookieStore::new_inherited(
|
||||||
|
global.resource_threads().core_thread.clone(),
|
||||||
|
)),
|
||||||
|
global,
|
||||||
|
can_gc,
|
||||||
|
);
|
||||||
store.setup_route();
|
store.setup_route();
|
||||||
store
|
store
|
||||||
}
|
}
|
||||||
|
@ -567,8 +578,7 @@ impl CookieStoreMethods<crate::DomTypeHolder> for CookieStore {
|
||||||
impl Drop for CookieStore {
|
impl Drop for CookieStore {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let res = self
|
let res = self
|
||||||
.global()
|
.unregister_channel
|
||||||
.resource_threads()
|
|
||||||
.send(CoreResourceMsg::RemoveCookieListener(self.store_id));
|
.send(CoreResourceMsg::RemoveCookieListener(self.store_id));
|
||||||
if res.is_err() {
|
if res.is_err() {
|
||||||
error!("Failed to send cookiestore message to resource threads");
|
error!("Failed to send cookiestore message to resource threads");
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue