mirror of
https://github.com/servo/servo.git
synced 2025-08-03 12:40:06 +01:00
Auto merge of #13759 - bholley:owning_handle, r=SimonSapin
Implement OwningHandle in style I've also PR-ed this against upstream [1], but I don't want to block on that in case it takes a while to be merged / published. [1] https://github.com/Kimundi/owning-ref-rs/pull/15 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="34" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/servo/servo/13759) <!-- Reviewable:end -->
This commit is contained in:
commit
0f4209644c
9 changed files with 134 additions and 9 deletions
8
components/servo/Cargo.lock
generated
8
components/servo/Cargo.lock
generated
|
@ -1727,7 +1727,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -1735,7 +1735,7 @@ name = "parking_lot"
|
|||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -2320,6 +2320,7 @@ dependencies = [
|
|||
"num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plugins 0.0.1",
|
||||
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2344,6 +2345,7 @@ dependencies = [
|
|||
"app_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"cssparser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"euclid 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"selectors 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2960,7 +2962,7 @@ dependencies = [
|
|||
"checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>"
|
||||
"checksum osmesa-sys 0.1.2 (git+https://github.com/daggerbot/osmesa-rs)" = "<none>"
|
||||
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
||||
"checksum owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88084505837507cbec6a9f39b5d3b985db3c84e9a741c80200b619001283293d"
|
||||
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
|
||||
"checksum parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3562f3de7bdff194212be82366abf5c6565aff8a433b71c53c63d0e7c9913878"
|
||||
"checksum parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06f24c980718110494e9cfb7db7438895c3f54505101bb6170329d5e43a53f64"
|
||||
"checksum phf 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f02853ab706e88121d7ad33ed06bedce0a7cdb96136be7c20ff0dce7b4adb9ef"
|
||||
|
|
|
@ -41,6 +41,7 @@ num-integer = "0.1.32"
|
|||
num-traits = "0.1.32"
|
||||
num_cpus = "0.2.2"
|
||||
ordered-float = "0.2.2"
|
||||
owning_ref = "0.2.2"
|
||||
parking_lot = "0.3.3"
|
||||
quickersort = "2.0.0"
|
||||
rand = "0.3"
|
||||
|
|
|
@ -73,6 +73,7 @@ extern crate num_integer;
|
|||
extern crate num_traits;
|
||||
#[cfg(feature = "gecko")] extern crate num_cpus;
|
||||
extern crate ordered_float;
|
||||
extern crate owning_ref;
|
||||
extern crate parking_lot;
|
||||
extern crate quickersort;
|
||||
extern crate rand;
|
||||
|
@ -112,6 +113,7 @@ pub mod keyframes;
|
|||
pub mod logical_geometry;
|
||||
pub mod matching;
|
||||
pub mod media_queries;
|
||||
pub mod owning_handle;
|
||||
pub mod parallel;
|
||||
pub mod parser;
|
||||
pub mod refcell;
|
||||
|
|
81
components/style/owning_handle.rs
Normal file
81
components/style/owning_handle.rs
Normal file
|
@ -0,0 +1,81 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#![allow(unsafe_code)]
|
||||
|
||||
use owning_ref::StableAddress;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
|
||||
/// `OwningHandle` is a complement to `OwningRef`. Where `OwningRef` allows
|
||||
/// consumers to pass around an owned object and a dependent reference,
|
||||
/// `OwningHandle` contains an owned object and a dependent _object_.
|
||||
///
|
||||
/// `OwningHandle` can encapsulate a `RefMut` along with its associated
|
||||
/// `RefCell`, or an `RwLockReadGuard` along with its associated `RwLock`.
|
||||
/// However, the API is completely generic and there are no restrictions on
|
||||
/// what types of owning and dependent objects may be used.
|
||||
///
|
||||
/// `OwningHandle` is created by passing an owner object (which dereferences
|
||||
/// to a stable address) along with a callback which receives a pointer to
|
||||
/// that stable location. The callback may then dereference the pointer and
|
||||
/// mint a dependent object, with the guarantee that the returned object will
|
||||
/// not outlive the referent of the pointer.
|
||||
///
|
||||
/// This does foist some unsafety onto the callback, which needs an `unsafe`
|
||||
/// block to dereference the pointer. It would be almost good enough for
|
||||
/// OwningHandle to pass a transmuted &'statc reference to the callback
|
||||
/// since the lifetime is infinite as far as the minted handle is concerned.
|
||||
/// However, even an `Fn` callback can still allow the reference to escape
|
||||
/// via a `StaticMutex` or similar, which technically violates the safety
|
||||
/// contract. Some sort of language support in the lifetime system could
|
||||
/// make this API a bit nicer.
|
||||
pub struct OwningHandle<O, H>
|
||||
where O: StableAddress, H: Deref,
|
||||
{
|
||||
handle: H,
|
||||
_owner: O,
|
||||
}
|
||||
|
||||
impl<O, H> Deref for OwningHandle<O, H>
|
||||
where O: StableAddress, H: Deref,
|
||||
{
|
||||
type Target = H::Target;
|
||||
fn deref(&self) -> &H::Target {
|
||||
self.handle.deref()
|
||||
}
|
||||
}
|
||||
|
||||
unsafe impl<O, H> StableAddress for OwningHandle<O, H>
|
||||
where O: StableAddress, H: StableAddress,
|
||||
{}
|
||||
|
||||
impl<O, H> DerefMut for OwningHandle<O, H>
|
||||
where O: StableAddress, H: DerefMut,
|
||||
{
|
||||
fn deref_mut(&mut self) -> &mut H::Target {
|
||||
self.handle.deref_mut()
|
||||
}
|
||||
}
|
||||
|
||||
impl<O, H> OwningHandle<O, H>
|
||||
where O: StableAddress, H: Deref,
|
||||
{
|
||||
/// Create a new OwningHandle. The provided callback will be invoked with
|
||||
/// a pointer to the object owned by `o`, and the returned value is stored
|
||||
/// as the object to which this `OwningHandle` will forward `Deref` and
|
||||
/// `DerefMut`.
|
||||
pub fn new<F>(o: O, f: F) -> Self
|
||||
where F: Fn(*const O::Target) -> H
|
||||
{
|
||||
let h: H;
|
||||
{
|
||||
h = f(o.deref() as *const O::Target);
|
||||
}
|
||||
|
||||
OwningHandle {
|
||||
handle: h,
|
||||
_owner: o,
|
||||
}
|
||||
}
|
||||
}
|
7
ports/cef/Cargo.lock
generated
7
ports/cef/Cargo.lock
generated
|
@ -1598,7 +1598,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -1606,7 +1606,7 @@ name = "parking_lot"
|
|||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -2203,6 +2203,7 @@ dependencies = [
|
|||
"num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"plugins 0.0.1",
|
||||
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -2813,7 +2814,7 @@ dependencies = [
|
|||
"checksum osmesa-src 12.0.1 (git+https://github.com/servo/osmesa-src)" = "<none>"
|
||||
"checksum osmesa-sys 0.1.2 (git+https://github.com/daggerbot/osmesa-rs)" = "<none>"
|
||||
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
|
||||
"checksum owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88084505837507cbec6a9f39b5d3b985db3c84e9a741c80200b619001283293d"
|
||||
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
|
||||
"checksum parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3562f3de7bdff194212be82366abf5c6565aff8a433b71c53c63d0e7c9913878"
|
||||
"checksum parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06f24c980718110494e9cfb7db7438895c3f54505101bb6170329d5e43a53f64"
|
||||
"checksum phf 0.7.17 (registry+https://github.com/rust-lang/crates.io-index)" = "f02853ab706e88121d7ad33ed06bedce0a7cdb96136be7c20ff0dce7b4adb9ef"
|
||||
|
|
7
ports/geckolib/Cargo.lock
generated
7
ports/geckolib/Cargo.lock
generated
|
@ -251,7 +251,7 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "owning_ref"
|
||||
version = "0.2.1"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
|
||||
[[package]]
|
||||
|
@ -259,7 +259,7 @@ name = "parking_lot"
|
|||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
|
@ -385,6 +385,7 @@ dependencies = [
|
|||
"num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"quickersort 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"rand 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -567,7 +568,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum num-traits 0.1.35 (registry+https://github.com/rust-lang/crates.io-index)" = "8359ea48994f253fa958b5b90b013728b06f54872e5a58bce39540fcdd0f2527"
|
||||
"checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
|
||||
"checksum ordered-float 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cc511538298611a79d5a4ddfbb75315b866d942ed26a00bdc3590795c68b7279"
|
||||
"checksum owning_ref 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88084505837507cbec6a9f39b5d3b985db3c84e9a741c80200b619001283293d"
|
||||
"checksum owning_ref 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8d91377085359426407a287ab16884a0111ba473aa6844ff01d4ec20ce3d75e7"
|
||||
"checksum parking_lot 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3562f3de7bdff194212be82366abf5c6565aff8a433b71c53c63d0e7c9913878"
|
||||
"checksum parking_lot_core 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "06f24c980718110494e9cfb7db7438895c3f54505101bb6170329d5e43a53f64"
|
||||
"checksum phf_generator 0.7.16 (registry+https://github.com/rust-lang/crates.io-index)" = "04b5ea825e28cb6efd89d9133b129b2003b45a221aeda025509b125b00ecb7c4"
|
||||
|
|
|
@ -13,6 +13,7 @@ doctest = false
|
|||
app_units = "0.3"
|
||||
cssparser = {version = "0.7", features = ["heap_size"]}
|
||||
euclid = "0.10.1"
|
||||
owning_ref = "0.2.2"
|
||||
parking_lot = "0.3"
|
||||
rustc-serialize = "0.3"
|
||||
selectors = "0.13"
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
extern crate app_units;
|
||||
extern crate cssparser;
|
||||
extern crate euclid;
|
||||
extern crate owning_ref;
|
||||
extern crate parking_lot;
|
||||
extern crate rustc_serialize;
|
||||
extern crate selectors;
|
||||
|
@ -22,6 +23,7 @@ mod attr;
|
|||
mod cache;
|
||||
mod logical_geometry;
|
||||
mod media_queries;
|
||||
mod owning_handle;
|
||||
mod parsing;
|
||||
mod properties;
|
||||
mod selector_matching;
|
||||
|
|
34
tests/unit/style/owning_handle.rs
Normal file
34
tests/unit/style/owning_handle.rs
Normal file
|
@ -0,0 +1,34 @@
|
|||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
use owning_ref::RcRef;
|
||||
use std::cell::RefCell;
|
||||
use std::rc::Rc;
|
||||
use std::sync::{Arc, RwLock};
|
||||
use style::owning_handle::OwningHandle;
|
||||
|
||||
#[test]
|
||||
fn owning_handle() {
|
||||
use std::cell::RefCell;
|
||||
let cell = Rc::new(RefCell::new(2));
|
||||
let cell_ref = RcRef::new(cell);
|
||||
let mut handle = OwningHandle::new(cell_ref, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
|
||||
assert_eq!(*handle, 2);
|
||||
*handle = 3;
|
||||
assert_eq!(*handle, 3);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn nested() {
|
||||
let result = {
|
||||
let complex = Rc::new(RefCell::new(Arc::new(RwLock::new("someString"))));
|
||||
let curr = RcRef::new(complex);
|
||||
let curr = OwningHandle::new(curr, |x| unsafe { x.as_ref() }.unwrap().borrow_mut());
|
||||
let mut curr = OwningHandle::new(curr, |x| unsafe { x.as_ref() }.unwrap().try_write().unwrap());
|
||||
assert_eq!(*curr, "someString");
|
||||
*curr = "someOtherString";
|
||||
curr
|
||||
};
|
||||
assert_eq!(*result, "someOtherString");
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue