mirror of
https://github.com/servo/servo.git
synced 2025-08-05 21:50:18 +01:00
Extract some thread local use from generic code.
This commit is contained in:
parent
ec0b5d55d7
commit
a5d0e0b1c1
1 changed files with 37 additions and 21 deletions
|
@ -50,12 +50,15 @@ mod dummy {
|
||||||
pub use self::dummy::LIVE_REFERENCES;
|
pub use self::dummy::LIVE_REFERENCES;
|
||||||
|
|
||||||
/// A pointer to a Rust DOM object that needs to be destroyed.
|
/// A pointer to a Rust DOM object that needs to be destroyed.
|
||||||
pub struct TrustedReference(*const libc::c_void);
|
struct TrustedReference(*const libc::c_void);
|
||||||
unsafe impl Send for TrustedReference {}
|
unsafe impl Send for TrustedReference {}
|
||||||
|
|
||||||
impl TrustedReference {
|
impl TrustedReference {
|
||||||
fn new<T: DomObject>(ptr: *const T) -> TrustedReference {
|
/// Creates a new TrustedReference from a pointer to a value that impements DOMObject.
|
||||||
TrustedReference(ptr as *const libc::c_void)
|
/// This is not enforced by the type system to reduce duplicated generic code,
|
||||||
|
/// which is acceptable since this method is internal to this module.
|
||||||
|
unsafe fn new(ptr: *const libc::c_void) -> TrustedReference {
|
||||||
|
TrustedReference(ptr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,7 +159,7 @@ pub struct Trusted<T: DomObject> {
|
||||||
/// A pointer to the Rust DOM object of type T, but void to allow
|
/// A pointer to the Rust DOM object of type T, but void to allow
|
||||||
/// sending `Trusted<T>` between threads, regardless of T's sendability.
|
/// sending `Trusted<T>` between threads, regardless of T's sendability.
|
||||||
refcount: Arc<TrustedReference>,
|
refcount: Arc<TrustedReference>,
|
||||||
owner_thread: *const libc::c_void,
|
owner_thread: *const LiveDOMReferences,
|
||||||
phantom: PhantomData<T>,
|
phantom: PhantomData<T>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -167,27 +170,37 @@ impl<T: DomObject> Trusted<T> {
|
||||||
/// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's
|
/// be prevented from being GCed for the duration of the resulting `Trusted<T>` object's
|
||||||
/// lifetime.
|
/// lifetime.
|
||||||
pub fn new(ptr: &T) -> Trusted<T> {
|
pub fn new(ptr: &T) -> Trusted<T> {
|
||||||
LIVE_REFERENCES.with(|ref r| {
|
fn add_live_reference(
|
||||||
let r = r.borrow();
|
ptr: *const libc::c_void,
|
||||||
let live_references = r.as_ref().unwrap();
|
) -> (Arc<TrustedReference>, *const LiveDOMReferences) {
|
||||||
let refcount = live_references.addref(&*ptr as *const T);
|
LIVE_REFERENCES.with(|ref r| {
|
||||||
Trusted {
|
let r = r.borrow();
|
||||||
refcount: refcount,
|
let live_references = r.as_ref().unwrap();
|
||||||
owner_thread: (&*live_references) as *const _ as *const libc::c_void,
|
let refcount = unsafe { live_references.addref(ptr) };
|
||||||
phantom: PhantomData,
|
(refcount, live_references as *const _)
|
||||||
}
|
})
|
||||||
})
|
}
|
||||||
|
|
||||||
|
let (refcount, owner_thread) = add_live_reference(ptr as *const T as *const _);
|
||||||
|
Trusted {
|
||||||
|
refcount,
|
||||||
|
owner_thread,
|
||||||
|
phantom: PhantomData,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on
|
/// Obtain a usable DOM pointer from a pinned `Trusted<T>` value. Fails if used on
|
||||||
/// a different thread than the original value from which this `Trusted<T>` was
|
/// a different thread than the original value from which this `Trusted<T>` was
|
||||||
/// obtained.
|
/// obtained.
|
||||||
pub fn root(&self) -> DomRoot<T> {
|
pub fn root(&self) -> DomRoot<T> {
|
||||||
assert!(LIVE_REFERENCES.with(|ref r| {
|
fn validate(owner_thread: *const LiveDOMReferences) {
|
||||||
let r = r.borrow();
|
assert!(LIVE_REFERENCES.with(|ref r| {
|
||||||
let live_references = r.as_ref().unwrap();
|
let r = r.borrow();
|
||||||
self.owner_thread == (&*live_references) as *const _ as *const libc::c_void
|
let live_references = r.as_ref().unwrap();
|
||||||
}));
|
owner_thread == live_references
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
validate(self.owner_thread);
|
||||||
unsafe { DomRoot::from_ref(&*(self.refcount.0 as *const T)) }
|
unsafe { DomRoot::from_ref(&*(self.refcount.0 as *const T)) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -234,7 +247,10 @@ impl LiveDOMReferences {
|
||||||
table.entry(&*promise).or_insert(vec![]).push(promise)
|
table.entry(&*promise).or_insert(vec![]).push(promise)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn addref<T: DomObject>(&self, ptr: *const T) -> Arc<TrustedReference> {
|
/// ptr must be a pointer to a type that implements DOMObject.
|
||||||
|
/// This is not enforced by the type system to reduce duplicated generic code,
|
||||||
|
/// which is acceptable since this method is internal to this module.
|
||||||
|
unsafe fn addref(&self, ptr: *const libc::c_void) -> Arc<TrustedReference> {
|
||||||
let mut table = self.reflectable_table.borrow_mut();
|
let mut table = self.reflectable_table.borrow_mut();
|
||||||
let capacity = table.capacity();
|
let capacity = table.capacity();
|
||||||
let len = table.len();
|
let len = table.len();
|
||||||
|
@ -243,7 +259,7 @@ impl LiveDOMReferences {
|
||||||
remove_nulls(&mut table);
|
remove_nulls(&mut table);
|
||||||
table.reserve(len);
|
table.reserve(len);
|
||||||
}
|
}
|
||||||
match table.entry(ptr as *const libc::c_void) {
|
match table.entry(ptr) {
|
||||||
Occupied(mut entry) => match entry.get().upgrade() {
|
Occupied(mut entry) => match entry.get().upgrade() {
|
||||||
Some(refcount) => refcount,
|
Some(refcount) => refcount,
|
||||||
None => {
|
None => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue