Move RacyCell to std::comm

RacyCell is not exactly what we'd like as a final implementation for
this. Therefore, we're moving it under `std::comm` and also making it
private.
This commit is contained in:
Flavio Percoco
2014-12-22 12:29:46 +01:00
parent f436f9ca29
commit e2116c8fba
8 changed files with 61 additions and 47 deletions

View File

@@ -14,33 +14,43 @@
pub use self::Ordering::*; pub use self::Ordering::*;
use kinds::Sync;
use intrinsics; use intrinsics;
use cell::{UnsafeCell, RacyCell}; use cell::UnsafeCell;
/// A boolean type which can be safely shared between threads. /// A boolean type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicBool { pub struct AtomicBool {
v: RacyCell<uint>, v: UnsafeCell<uint>,
} }
unsafe impl Sync for AtomicBool {}
/// A signed integer type which can be safely shared between threads. /// A signed integer type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicInt { pub struct AtomicInt {
v: RacyCell<int>, v: UnsafeCell<int>,
} }
unsafe impl Sync for AtomicInt {}
/// An unsigned integer type which can be safely shared between threads. /// An unsigned integer type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicUint { pub struct AtomicUint {
v: RacyCell<uint>, v: UnsafeCell<uint>,
} }
unsafe impl Sync for AtomicUint {}
/// A raw pointer type which can be safely shared between threads. /// A raw pointer type which can be safely shared between threads.
#[stable] #[stable]
pub struct AtomicPtr<T> { pub struct AtomicPtr<T> {
p: RacyCell<uint>, p: UnsafeCell<uint>,
} }
unsafe impl<T> Sync for AtomicPtr<T> {}
/// Atomic memory orderings /// Atomic memory orderings
/// ///
/// Memory orderings limit the ways that both the compiler and CPU may reorder /// Memory orderings limit the ways that both the compiler and CPU may reorder
@@ -80,15 +90,15 @@ pub enum Ordering {
/// An `AtomicBool` initialized to `false`. /// An `AtomicBool` initialized to `false`.
#[unstable = "may be renamed, pending conventions for static initalizers"] #[unstable = "may be renamed, pending conventions for static initalizers"]
pub const INIT_ATOMIC_BOOL: AtomicBool = pub const INIT_ATOMIC_BOOL: AtomicBool =
AtomicBool { v: RacyCell(UnsafeCell { value: 0 }) }; AtomicBool { v: UnsafeCell { value: 0 } };
/// An `AtomicInt` initialized to `0`. /// An `AtomicInt` initialized to `0`.
#[unstable = "may be renamed, pending conventions for static initalizers"] #[unstable = "may be renamed, pending conventions for static initalizers"]
pub const INIT_ATOMIC_INT: AtomicInt = pub const INIT_ATOMIC_INT: AtomicInt =
AtomicInt { v: RacyCell(UnsafeCell { value: 0 }) }; AtomicInt { v: UnsafeCell { value: 0 } };
/// An `AtomicUint` initialized to `0`. /// An `AtomicUint` initialized to `0`.
#[unstable = "may be renamed, pending conventions for static initalizers"] #[unstable = "may be renamed, pending conventions for static initalizers"]
pub const INIT_ATOMIC_UINT: AtomicUint = pub const INIT_ATOMIC_UINT: AtomicUint =
AtomicUint { v: RacyCell(UnsafeCell { value: 0 }) }; AtomicUint { v: UnsafeCell { value: 0, } };
// NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly // NB: Needs to be -1 (0b11111111...) to make fetch_nand work correctly
const UINT_TRUE: uint = -1; const UINT_TRUE: uint = -1;
@@ -108,7 +118,7 @@ impl AtomicBool {
#[stable] #[stable]
pub fn new(v: bool) -> AtomicBool { pub fn new(v: bool) -> AtomicBool {
let val = if v { UINT_TRUE } else { 0 }; let val = if v { UINT_TRUE } else { 0 };
AtomicBool { v: RacyCell::new(val) } AtomicBool { v: UnsafeCell::new(val) }
} }
/// Loads a value from the bool. /// Loads a value from the bool.
@@ -348,7 +358,7 @@ impl AtomicInt {
#[inline] #[inline]
#[stable] #[stable]
pub fn new(v: int) -> AtomicInt { pub fn new(v: int) -> AtomicInt {
AtomicInt {v: RacyCell::new(v)} AtomicInt {v: UnsafeCell::new(v)}
} }
/// Loads a value from the int. /// Loads a value from the int.
@@ -534,7 +544,7 @@ impl AtomicUint {
#[inline] #[inline]
#[stable] #[stable]
pub fn new(v: uint) -> AtomicUint { pub fn new(v: uint) -> AtomicUint {
AtomicUint { v: RacyCell::new(v) } AtomicUint { v: UnsafeCell::new(v) }
} }
/// Loads a value from the uint. /// Loads a value from the uint.
@@ -721,7 +731,7 @@ impl<T> AtomicPtr<T> {
#[inline] #[inline]
#[stable] #[stable]
pub fn new(p: *mut T) -> AtomicPtr<T> { pub fn new(p: *mut T) -> AtomicPtr<T> {
AtomicPtr { p: RacyCell::new(p as uint) } AtomicPtr { p: UnsafeCell::new(p as uint) }
} }
/// Loads a value from the pointer. /// Loads a value from the pointer.

View File

@@ -158,7 +158,7 @@
use clone::Clone; use clone::Clone;
use cmp::PartialEq; use cmp::PartialEq;
use default::Default; use default::Default;
use kinds::{marker, Copy, Send, Sync}; use kinds::{marker, Copy};
use ops::{Deref, DerefMut, Drop}; use ops::{Deref, DerefMut, Drop};
use option::Option; use option::Option;
use option::Option::{None, Some}; use option::Option::{None, Some};
@@ -555,28 +555,3 @@ impl<T> UnsafeCell<T> {
#[deprecated = "renamed to into_inner()"] #[deprecated = "renamed to into_inner()"]
pub unsafe fn unwrap(self) -> T { self.into_inner() } pub unsafe fn unwrap(self) -> T { self.into_inner() }
} }
/// A version of `UnsafeCell` intended for use in concurrent data
/// structures (for example, you might put it in an `Arc`).
pub struct RacyCell<T>(pub UnsafeCell<T>);
impl<T> RacyCell<T> {
/// DOX
pub fn new(value: T) -> RacyCell<T> {
RacyCell(UnsafeCell { value: value })
}
/// DOX
pub unsafe fn get(&self) -> *mut T {
self.0.get()
}
/// DOX
pub unsafe fn into_inner(self) -> T {
self.0.into_inner()
}
}
unsafe impl<T:Send> Send for RacyCell<T> { }
unsafe impl<T> Sync for RacyCell<T> { } // Oh dear

View File

@@ -319,9 +319,10 @@ pub use self::TrySendError::*;
use self::Flavor::*; use self::Flavor::*;
use alloc::arc::Arc; use alloc::arc::Arc;
use core::kinds;
use core::kinds::marker; use core::kinds::marker;
use core::mem; use core::mem;
use core::cell::{UnsafeCell, RacyCell}; use core::cell::UnsafeCell;
pub use self::select::{Select, Handle}; pub use self::select::{Select, Handle};
use self::select::StartResult; use self::select::StartResult;
@@ -1024,6 +1025,32 @@ impl<T: Send> Drop for Receiver<T> {
} }
} }
/// A version of `UnsafeCell` intended for use in concurrent data
/// structures (for example, you might put it in an `Arc`).
pub struct RacyCell<T>(pub UnsafeCell<T>);
impl<T> RacyCell<T> {
/// DOX
pub fn new(value: T) -> RacyCell<T> {
RacyCell(UnsafeCell { value: value })
}
/// DOX
pub unsafe fn get(&self) -> *mut T {
self.0.get()
}
/// DOX
pub unsafe fn into_inner(self) -> T {
self.0.into_inner()
}
}
unsafe impl<T:Send> Send for RacyCell<T> { }
unsafe impl<T> kinds::Sync for RacyCell<T> { } // Oh dear
#[cfg(test)] #[cfg(test)]
mod test { mod test {
use prelude::*; use prelude::*;

View File

@@ -10,8 +10,9 @@
use prelude::*; use prelude::*;
use cell::{UnsafeCell, RacyCell}; use comm::RacyCell;
use kinds::{marker, Sync}; use cell::UnsafeCell;
use kinds::marker;
use sync::{poison, AsMutexGuard}; use sync::{poison, AsMutexGuard};
use sys_common::mutex as sys; use sys_common::mutex as sys;

View File

@@ -8,8 +8,9 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use comm::RacyCell;
use cell::UnsafeCell;
use kinds::Sync; use kinds::Sync;
use cell::{UnsafeCell, RacyCell};
use sys::sync as ffi; use sys::sync as ffi;
use sys_common::mutex; use sys_common::mutex;

View File

@@ -127,7 +127,7 @@
use any::Any; use any::Any;
use borrow::IntoCow; use borrow::IntoCow;
use boxed::Box; use boxed::Box;
use cell::RacyCell; use comm::RacyCell;
use clone::Clone; use clone::Clone;
use kinds::{Send, Sync}; use kinds::{Send, Sync};
use ops::{Drop, FnOnce}; use ops::{Drop, FnOnce};

View File

@@ -196,11 +196,10 @@ impl<T> Key<T> {
#[cfg(not(any(windows, target_os = "android", target_os = "ios")))] #[cfg(not(any(windows, target_os = "android", target_os = "ios")))]
mod imp { mod imp {
use std::cell::UnsafeCell; use std::comm::RacyCell;
// SNAP c9f6d69 switch to `Cell`
#[doc(hidden)] #[doc(hidden)]
pub struct KeyInner<T> { pub inner: UnsafeCell<*mut T> } pub struct KeyInner<T> { pub inner: RacyCell<*mut T> }
unsafe impl<T> ::kinds::Sync for KeyInner<T> { } unsafe impl<T> ::kinds::Sync for KeyInner<T> { }

View File

@@ -9,7 +9,8 @@
// except according to those terms. // except according to those terms.
use std::kinds::marker; use std::kinds::marker;
use std::cell::{UnsafeCell, RacyCell}; use std::comm::RacyCell;
use std::cell::UnsafeCell;
struct MyUnsafe<T> { struct MyUnsafe<T> {
value: RacyCell<T> value: RacyCell<T>