gecko-dev/servo/components/style/thread_state.rs
Bastien Orivel b5ec6408a9 servo: Merge #18967 - Bump bitflags to 1.0 (from Eijebong:bitflags2.0); r=mbrubeck
See #18809

Still haven't had time to test it but it should fix the tests failures that appeared in m-c

Source-Repo: https://github.com/servo/servo
Source-Revision: fe4139b779b3af749ec1426ddf4e1393c7b85442

--HG--
extra : subtree_source : https%3A//hg.mozilla.org/projects/converted-servo-linear
extra : subtree_revision : 9a0549d7dd8a99315ba3f8eec5d0f9fdf9eb4c0f
2017-10-30 18:25:45 -05:00

98 lines
2.6 KiB
Rust

/* 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/. */
//! Supports dynamic assertions in about what sort of thread is running and
//! what state it's in.
#![deny(missing_docs)]
use std::cell::RefCell;
bitflags! {
/// A thread state flag, used for multiple assertions.
pub struct ThreadState: u32 {
/// Whether we're in a script thread.
const SCRIPT = 0x01;
/// Whether we're in a layout thread.
const LAYOUT = 0x02;
/// Whether we're in a script worker thread (actual web workers), or in
/// a layout worker thread.
const IN_WORKER = 0x0100;
/// Whether the current thread is going through a GC.
const IN_GC = 0x0200;
}
}
macro_rules! thread_types ( ( $( $fun:ident = $flag:path ; )* ) => (
impl ThreadState {
/// Whether the current thread is a worker thread.
pub fn is_worker(self) -> bool {
self.contains(ThreadState::IN_WORKER)
}
$(
#[allow(missing_docs)]
pub fn $fun(self) -> bool {
self.contains($flag)
}
)*
}
));
thread_types! {
is_script = ThreadState::SCRIPT;
is_layout = ThreadState::LAYOUT;
}
thread_local!(static STATE: RefCell<Option<ThreadState>> = RefCell::new(None));
/// Initializes the current thread state.
pub fn initialize(x: ThreadState) {
STATE.with(|ref k| {
if let Some(ref s) = *k.borrow() {
if x != *s {
panic!("Thread state already initialized as {:?}", s);
}
}
*k.borrow_mut() = Some(x);
});
}
/// Initializes the current thread as a layout worker thread.
pub fn initialize_layout_worker_thread() {
initialize(ThreadState::LAYOUT | ThreadState::IN_WORKER);
}
/// Gets the current thread state.
pub fn get() -> ThreadState {
let state = STATE.with(|ref k| {
match *k.borrow() {
None => ThreadState::empty(), // Unknown thread.
Some(s) => s,
}
});
state
}
/// Enters into a given temporary state. Panics if re-entring.
pub fn enter(x: ThreadState) {
let state = get();
debug_assert!(!state.intersects(x));
STATE.with(|ref k| {
*k.borrow_mut() = Some(state | x);
})
}
/// Exits a given temporary state.
pub fn exit(x: ThreadState) {
let state = get();
debug_assert!(state.contains(x));
STATE.with(|ref k| {
*k.borrow_mut() = Some(state & !x);
})
}