Skip to content

Commit e5a602e

Browse files
committed
Add OneThread which only allows its inner value to be used in one thread
1 parent 67712d7 commit e5a602e

File tree

1 file changed

+55
-0
lines changed
  • src/librustc_data_structures

1 file changed

+55
-0
lines changed

src/librustc_data_structures/sync.rs

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ use std::cmp::Ordering;
3333
use std::fmt::Debug;
3434
use std::fmt::Formatter;
3535
use std::fmt;
36+
use std;
37+
use std::ops::{Deref, DerefMut};
3638
use owning_ref::{Erased, OwningRef};
3739

3840
cfg_if! {
@@ -161,6 +163,8 @@ cfg_if! {
161163
use parking_lot::Mutex as InnerLock;
162164
use parking_lot::RwLock as InnerRwLock;
163165

166+
use std::thread;
167+
164168
pub type MetadataRef = OwningRef<Box<Erased + Send + Sync>, [u8]>;
165169

166170
/// This makes locks panic if they are already held.
@@ -439,3 +443,54 @@ impl<T: Clone> Clone for RwLock<T> {
439443
RwLock::new(self.borrow().clone())
440444
}
441445
}
446+
447+
/// A type which only allows its inner value to be used in one thread.
448+
/// It will panic if it is used on multiple threads.
449+
#[derive(Copy, Clone, Hash, Debug, Eq, PartialEq)]
450+
pub struct OneThread<T> {
451+
#[cfg(parallel_queries)]
452+
thread: thread::ThreadId,
453+
inner: T,
454+
}
455+
456+
unsafe impl<T> std::marker::Sync for OneThread<T> {}
457+
unsafe impl<T> std::marker::Send for OneThread<T> {}
458+
459+
impl<T> OneThread<T> {
460+
#[inline(always)]
461+
fn check(&self) {
462+
#[cfg(parallel_queries)]
463+
assert_eq!(thread::current().id(), self.thread);
464+
}
465+
466+
#[inline(always)]
467+
pub fn new(inner: T) -> Self {
468+
OneThread {
469+
#[cfg(parallel_queries)]
470+
thread: thread::current().id(),
471+
inner,
472+
}
473+
}
474+
475+
#[inline(always)]
476+
pub fn into_inner(value: Self) -> T {
477+
value.check();
478+
value.inner
479+
}
480+
}
481+
482+
impl<T> Deref for OneThread<T> {
483+
type Target = T;
484+
485+
fn deref(&self) -> &T {
486+
self.check();
487+
&self.inner
488+
}
489+
}
490+
491+
impl<T> DerefMut for OneThread<T> {
492+
fn deref_mut(&mut self) -> &mut T {
493+
self.check();
494+
&mut self.inner
495+
}
496+
}

0 commit comments

Comments
 (0)