mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-25 11:15:34 +00:00
80f56a2927
<!-- Please describe your changes on the following line: --> I've added a new tidy rule (no = in the beginning of line) + tests for it. Also cleaned up a few rust source files to accord with the new rule. --- <!-- Thank you for contributing to Servo! Please replace each `[ ]` by `[X]` when the step is complete, and replace `__` with appropriate data: --> - [X] `./mach build -d` does not report any errors - [X] `./mach test-tidy` does not report any errors - [X] These changes fix #14890 (github issue number if applicable). <!-- Either: --> - [X] There are tests for these changes OR - [ ] These changes do not require tests because _____ <!-- Pull requests that do not address these steps are welcome, but they will require additional verification as part of the review process. --> Source-Repo: https://github.com/servo/servo Source-Revision: b6c137b36f8b9f9cc5c0105bb94a4edeaf7d09be
124 lines
3.6 KiB
Rust
124 lines
3.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 debug builds about what sort of thread is
|
|
//! running and what state it's in.
|
|
//!
|
|
//! In release builds, `get` returns 0. All of the other functions inline
|
|
//! away to nothing.
|
|
|
|
#![deny(missing_docs)]
|
|
|
|
pub use self::imp::{enter, exit, get, initialize};
|
|
|
|
bitflags! {
|
|
/// A thread state flag, used for multiple assertions.
|
|
pub flags 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:ident ; )* ) => (
|
|
impl ThreadState {
|
|
/// Whether the current thread is a worker thread.
|
|
pub fn is_worker(self) -> bool {
|
|
self.contains(IN_WORKER)
|
|
}
|
|
|
|
$(
|
|
#[cfg(debug_assertions)]
|
|
#[allow(missing_docs)]
|
|
pub fn $fun(self) -> bool {
|
|
self.contains($flag)
|
|
}
|
|
#[cfg(not(debug_assertions))]
|
|
#[allow(missing_docs)]
|
|
pub fn $fun(self) -> bool {
|
|
true
|
|
}
|
|
)*
|
|
}
|
|
|
|
#[cfg(debug_assertions)]
|
|
static TYPES: &'static [ThreadState] =
|
|
&[ $( $flag ),* ];
|
|
));
|
|
|
|
thread_types! {
|
|
is_script = SCRIPT;
|
|
is_layout = LAYOUT;
|
|
}
|
|
|
|
#[cfg(debug_assertions)]
|
|
mod imp {
|
|
use std::cell::RefCell;
|
|
use super::{TYPES, ThreadState};
|
|
|
|
thread_local!(static STATE: RefCell<Option<ThreadState>> = RefCell::new(None));
|
|
|
|
/// Initialize the current thread state.
|
|
pub fn initialize(x: ThreadState) {
|
|
STATE.with(|ref k| {
|
|
if let Some(ref s) = *k.borrow() {
|
|
panic!("Thread state already initialized as {:?}", s);
|
|
}
|
|
*k.borrow_mut() = Some(x);
|
|
});
|
|
get(); // check the assertion below
|
|
}
|
|
|
|
/// Get the current thread state.
|
|
pub fn get() -> ThreadState {
|
|
let state = STATE.with(|ref k| {
|
|
match *k.borrow() {
|
|
// This is one of the layout threads, that use rayon.
|
|
None => super::LAYOUT | super::IN_WORKER,
|
|
Some(s) => s,
|
|
}
|
|
});
|
|
|
|
// Exactly one of the thread type flags should be set.
|
|
assert_eq!(1, TYPES.iter().filter(|&&ty| state.contains(ty)).count());
|
|
state
|
|
}
|
|
|
|
/// Enter into a given temporary state. Panics if re-entring.
|
|
pub fn enter(x: ThreadState) {
|
|
let state = get();
|
|
assert!(!state.intersects(x));
|
|
STATE.with(|ref k| {
|
|
*k.borrow_mut() = Some(state | x);
|
|
})
|
|
}
|
|
|
|
/// Exit a given temporary state.
|
|
pub fn exit(x: ThreadState) {
|
|
let state = get();
|
|
assert!(state.contains(x));
|
|
STATE.with(|ref k| {
|
|
*k.borrow_mut() = Some(state & !x);
|
|
})
|
|
}
|
|
}
|
|
|
|
#[cfg(not(debug_assertions))]
|
|
#[allow(missing_docs)]
|
|
mod imp {
|
|
use super::ThreadState;
|
|
#[inline(always)] pub fn initialize(_: ThreadState) { }
|
|
#[inline(always)] pub fn get() -> ThreadState { ThreadState::empty() }
|
|
#[inline(always)] pub fn enter(_: ThreadState) { }
|
|
#[inline(always)] pub fn exit(_: ThreadState) { }
|
|
}
|