diff options
| author | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-04-01 09:43:19 +0200 |
|---|---|---|
| committer | John Kåre Alsaker <john.kare.alsaker@gmail.com> | 2018-04-10 14:39:33 +0200 |
| commit | e5a602e364d5083a4c475747ad08c81ef29897bf (patch) | |
| tree | d134fde8d1760faea24523e217afe4e5f9ef9a57 /src/librustc_data_structures | |
| parent | 67712d79451b042b6fca2167c1a57d91d86f663b (diff) | |
| download | rust-e5a602e364d5083a4c475747ad08c81ef29897bf.tar.gz rust-e5a602e364d5083a4c475747ad08c81ef29897bf.zip | |
Add OneThread which only allows its inner value to be used in one thread
Diffstat (limited to 'src/librustc_data_structures')
| -rw-r--r-- | src/librustc_data_structures/sync.rs | 55 |
1 files changed, 55 insertions, 0 deletions
diff --git a/src/librustc_data_structures/sync.rs b/src/librustc_data_structures/sync.rs index 0f534f0adec..ad524916f0c 100644 --- a/src/librustc_data_structures/sync.rs +++ b/src/librustc_data_structures/sync.rs @@ -33,6 +33,8 @@ use std::cmp::Ordering; use std::fmt::Debug; use std::fmt::Formatter; use std::fmt; +use std; +use std::ops::{Deref, DerefMut}; use owning_ref::{Erased, OwningRef}; cfg_if! { @@ -161,6 +163,8 @@ cfg_if! { use parking_lot::Mutex as InnerLock; use parking_lot::RwLock as InnerRwLock; + use std::thread; + pub type MetadataRef = OwningRef<Box<Erased + Send + Sync>, [u8]>; /// This makes locks panic if they are already held. @@ -439,3 +443,54 @@ impl<T: Clone> Clone for RwLock<T> { RwLock::new(self.borrow().clone()) } } + +/// A type which only allows its inner value to be used in one thread. +/// It will panic if it is used on multiple threads. +#[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)] +pub struct OneThread<T> { + #[cfg(parallel_queries)] + thread: thread::ThreadId, + inner: T, +} + +unsafe impl<T> std::marker::Sync for OneThread<T> {} +unsafe impl<T> std::marker::Send for OneThread<T> {} + +impl<T> OneThread<T> { + #[inline(always)] + fn check(&self) { + #[cfg(parallel_queries)] + assert_eq!(thread::current().id(), self.thread); + } + + #[inline(always)] + pub fn new(inner: T) -> Self { + OneThread { + #[cfg(parallel_queries)] + thread: thread::current().id(), + inner, + } + } + + #[inline(always)] + pub fn into_inner(value: Self) -> T { + value.check(); + value.inner + } +} + +impl<T> Deref for OneThread<T> { + type Target = T; + + fn deref(&self) -> &T { + self.check(); + &self.inner + } +} + +impl<T> DerefMut for OneThread<T> { + fn deref_mut(&mut self) -> &mut T { + self.check(); + &mut self.inner + } +} |
