/* 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 https://mozilla.org/MPL/2.0/. */ use std::sync::OnceLock; /// A OnceLock wrapping a type that is not considered threadsafe by the Rust compiler, but /// will be used in a threadsafe manner (it will not be mutated, after being initialized). /// /// This is needed to allow using JS API types (which usually involve raw pointers) in static initializers, /// when Servo guarantees through the use of OnceLock that only one thread will ever initialize /// the value. pub struct ThreadUnsafeOnceLock(OnceLock); impl ThreadUnsafeOnceLock { #[allow(clippy::new_without_default)] pub const fn new() -> Self { Self(OnceLock::new()) } /// Initialize the value inside this lock. Panics if the lock has been previously initialized. pub fn set(&self, val: T) { assert!(self.0.set(val).is_ok()); } /// Get a reference to the value inside this lock. Panics if the lock has not been initialized. /// /// # Safety /// The caller must ensure that it does not mutate value contained inside this lock /// (using interior mutability). pub unsafe fn get(&self) -> &T { self.0.get().unwrap() } } unsafe impl Sync for ThreadUnsafeOnceLock {} unsafe impl Send for ThreadUnsafeOnceLock {}