diff --git a/components/style/atomic_refcell.rs b/components/style/atomic_refcell.rs new file mode 100644 index 00000000000..a45a682b638 --- /dev/null +++ b/components/style/atomic_refcell.rs @@ -0,0 +1,41 @@ +/* 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 parking_lot::{RwLock, RwLockReadGuard, RwLockWriteGuard}; + +/// Container type providing RefCell-like semantics for objects shared across +/// threads. +/// +/// RwLock is traditionally considered to be the |Sync| analogue of RefCell. +/// However, for consumers that can guarantee that they will never mutably +/// borrow the contents concurrently with immutable borrows, an RwLock feels +/// like overkill. +/// +/// The RwLock in the standard library is indeed heavyweight, since it heap- +/// allocates an OS-specific primitive and delegates operations to it. However, +/// parking_lot provides a pure-rust implementation of the standard +/// synchronization primitives, with uncontended borrows compiling down to a +/// single atomic operation. This is exactly how we would build an atomic +/// RefCell, so we newtype it with some API sugar. +pub struct AtomicRefCell(RwLock); + +pub type AtomicRef<'a, T> = RwLockReadGuard<'a, T>; +pub type AtomicRefMut<'a, T> = RwLockWriteGuard<'a, T>; +impl AtomicRefCell { + pub fn new(value: T) -> Self { + AtomicRefCell(RwLock::new(value)) + } + pub fn borrow(&self) -> AtomicRef { + self.0.try_read().unwrap() + } + pub fn borrow_mut(&self) -> AtomicRefMut { + self.0.try_write().unwrap() + } +} + +impl Default for AtomicRefCell { + fn default() -> Self { + Self::new(T::default()) + } +} diff --git a/components/style/lib.rs b/components/style/lib.rs index 138c8a04cb9..51ee0e122e5 100644 --- a/components/style/lib.rs +++ b/components/style/lib.rs @@ -81,6 +81,7 @@ extern crate util; #[macro_use] pub mod string_cache; pub mod animation; +pub mod atomic_refcell; pub mod attr; pub mod bezier; pub mod cache;