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:
bors-servo 2016-10-14 10:42:10 -05:00 committed by GitHub
commit 0f4209644c
9 changed files with 134 additions and 9 deletions

View file

@ -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"

View file

@ -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"

View file

@ -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;

View 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
View file

@ -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"

View file

@ -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"

View file

@ -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"

View file

@ -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;

View 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");
}