mirror of
https://github.com/servo/servo.git
synced 2025-08-28 08:38:20 +01:00
Refactor StylesheetLoader so impls do not need to acquire a shared lock.
This fixes a deadlock: https://github.com/servo/servo/pull/16014#issuecomment-287527067
This commit is contained in:
parent
1bacd0eb15
commit
1e38013783
4 changed files with 84 additions and 59 deletions
|
@ -3,10 +3,10 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use std::sync::Arc;
|
||||
use style::gecko::global_style_data::GLOBAL_STYLE_DATA;
|
||||
use style::gecko_bindings::bindings::Gecko_LoadStyleSheet;
|
||||
use style::gecko_bindings::structs::{Loader, ServoStyleSheet};
|
||||
use style::gecko_bindings::sugar::ownership::HasArcFFI;
|
||||
use style::media_queries::MediaList;
|
||||
use style::shared_lock::Locked;
|
||||
use style::stylesheets::{ImportRule, StylesheetLoader as StyleStylesheetLoader};
|
||||
use style_traits::ToCss;
|
||||
|
@ -20,13 +20,12 @@ impl StylesheetLoader {
|
|||
}
|
||||
|
||||
impl StyleStylesheetLoader for StylesheetLoader {
|
||||
fn request_stylesheet(&self, import_rule: &Arc<Locked<ImportRule>>) {
|
||||
let global_style_data = &*GLOBAL_STYLE_DATA;
|
||||
let guard = global_style_data.shared_lock.read();
|
||||
let import = import_rule.read_with(&guard);
|
||||
let (spec_bytes, spec_len) = import.url.as_slice_components()
|
||||
.expect("Import only loads valid URLs");
|
||||
|
||||
fn request_stylesheet(
|
||||
&self,
|
||||
media: MediaList,
|
||||
make_import: &mut FnMut(MediaList) -> ImportRule,
|
||||
make_arc: &mut FnMut(ImportRule) -> Arc<Locked<ImportRule>>,
|
||||
) -> Arc<Locked<ImportRule>> {
|
||||
// TODO(emilio): We probably want to share media representation with
|
||||
// Gecko in Stylo.
|
||||
//
|
||||
|
@ -35,16 +34,27 @@ impl StyleStylesheetLoader for StylesheetLoader {
|
|||
// evaluate them on the main thread.
|
||||
//
|
||||
// Meanwhile, this works.
|
||||
let media = import.stylesheet.media.read_with(&guard).to_css_string();
|
||||
let media_string = media.to_css_string();
|
||||
|
||||
let import = make_import(media);
|
||||
|
||||
// After we get this raw pointer ImportRule will be moved into a lock and Arc
|
||||
// and so the Arc<Url> pointer inside will also move,
|
||||
// but the Url it points to or the allocating backing the String inside that Url won’t,
|
||||
// so this raw pointer will still be valid.
|
||||
let (spec_bytes, spec_len): (*const u8, usize) = import.url.as_slice_components()
|
||||
.expect("Import only loads valid URLs");
|
||||
|
||||
let arc = make_arc(import);
|
||||
unsafe {
|
||||
Gecko_LoadStyleSheet(self.0,
|
||||
self.1,
|
||||
HasArcFFI::arc_as_borrowed(import_rule),
|
||||
HasArcFFI::arc_as_borrowed(&arc),
|
||||
spec_bytes,
|
||||
spec_len as u32,
|
||||
media.as_bytes().as_ptr(),
|
||||
media.len() as u32);
|
||||
media_string.as_bytes().as_ptr(),
|
||||
media_string.len() as u32);
|
||||
}
|
||||
arc
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue