mirror of
https://github.com/rust-lang/rust
synced 2024-11-05 20:45:15 +00:00
Relax Arc
bounds don't require Sync+Send
Besides the above making sense, it'll also allow us to make `RacyCell` private and use UnsafeCell instead.
This commit is contained in:
parent
7df17a2868
commit
8818693496
7 changed files with 37 additions and 36 deletions
|
@ -139,7 +139,7 @@ struct ArcInner<T> {
|
|||
data: T,
|
||||
}
|
||||
|
||||
impl<T: Sync + Send> Arc<T> {
|
||||
impl<T> Arc<T> {
|
||||
/// Constructs a new `Arc<T>`.
|
||||
///
|
||||
/// # Examples
|
||||
|
|
|
@ -1027,23 +1027,18 @@ fn drop(&mut self) {
|
|||
|
||||
/// 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>);
|
||||
struct RacyCell<T>(pub UnsafeCell<T>);
|
||||
|
||||
impl<T> RacyCell<T> {
|
||||
/// DOX
|
||||
pub fn new(value: T) -> RacyCell<T> {
|
||||
|
||||
fn new(value: T) -> RacyCell<T> {
|
||||
RacyCell(UnsafeCell { value: value })
|
||||
}
|
||||
|
||||
/// DOX
|
||||
pub unsafe fn get(&self) -> *mut T {
|
||||
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> { }
|
||||
|
|
|
@ -10,7 +10,6 @@
|
|||
|
||||
use prelude::*;
|
||||
|
||||
use comm::RacyCell;
|
||||
use cell::UnsafeCell;
|
||||
use kinds::marker;
|
||||
use sync::{poison, AsMutexGuard};
|
||||
|
@ -71,7 +70,7 @@ pub struct Mutex<T> {
|
|||
// time, so to ensure that the native mutex is used correctly we box the
|
||||
// inner lock to give it a constant address.
|
||||
inner: Box<StaticMutex>,
|
||||
data: RacyCell<T>,
|
||||
data: UnsafeCell<T>,
|
||||
}
|
||||
|
||||
unsafe impl<T:Send> Send for Mutex<T> { }
|
||||
|
@ -101,7 +100,7 @@ unsafe impl<T:Send> Sync for Mutex<T> { }
|
|||
/// ```
|
||||
pub struct StaticMutex {
|
||||
lock: sys::Mutex,
|
||||
poison: RacyCell<poison::Flag>,
|
||||
poison: UnsafeCell<poison::Flag>,
|
||||
}
|
||||
|
||||
unsafe impl Sync for StaticMutex {}
|
||||
|
@ -132,7 +131,7 @@ pub struct StaticMutexGuard {
|
|||
/// other mutex constants.
|
||||
pub const MUTEX_INIT: StaticMutex = StaticMutex {
|
||||
lock: sys::MUTEX_INIT,
|
||||
poison: RacyCell(UnsafeCell { value: poison::Flag { failed: false } }),
|
||||
poison: UnsafeCell { value: poison::Flag { failed: false } },
|
||||
};
|
||||
|
||||
impl<T: Send> Mutex<T> {
|
||||
|
@ -140,7 +139,7 @@ impl<T: Send> Mutex<T> {
|
|||
pub fn new(t: T) -> Mutex<T> {
|
||||
Mutex {
|
||||
inner: box MUTEX_INIT,
|
||||
data: RacyCell::new(t),
|
||||
data: UnsafeCell::new(t),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,13 +8,12 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use comm::RacyCell;
|
||||
use cell::UnsafeCell;
|
||||
use kinds::Sync;
|
||||
use sys::sync as ffi;
|
||||
use sys_common::mutex;
|
||||
|
||||
pub struct Mutex { inner: RacyCell<ffi::pthread_mutex_t> }
|
||||
pub struct Mutex { inner: UnsafeCell<ffi::pthread_mutex_t> }
|
||||
|
||||
#[inline]
|
||||
pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t {
|
||||
|
@ -22,7 +21,7 @@ pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t {
|
|||
}
|
||||
|
||||
pub const MUTEX_INIT: Mutex = Mutex {
|
||||
inner: RacyCell(UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER }),
|
||||
inner: UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER },
|
||||
};
|
||||
|
||||
unsafe impl Sync for Mutex {}
|
||||
|
|
|
@ -127,7 +127,7 @@
|
|||
use any::Any;
|
||||
use borrow::IntoCow;
|
||||
use boxed::Box;
|
||||
use comm::RacyCell;
|
||||
use cell::UnsafeCell;
|
||||
use clone::Clone;
|
||||
use kinds::{Send, Sync};
|
||||
use ops::{Drop, FnOnce};
|
||||
|
@ -211,8 +211,8 @@ pub fn spawn<T, F>(self, f: F) -> JoinGuard<T> where
|
|||
}
|
||||
|
||||
fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> JoinGuard<T> {
|
||||
let my_packet = Arc::new(RacyCell::new(None));
|
||||
let their_packet = my_packet.clone();
|
||||
let my_packet = Packet(Arc::new(UnsafeCell::new(None)));
|
||||
let their_packet = Packet(my_packet.0.clone());
|
||||
|
||||
let Builder { name, stack_size, stdout, stderr } = self;
|
||||
|
||||
|
@ -266,7 +266,7 @@ fn spawn_inner<T: Send>(self, f: Thunk<(), T>) -> JoinGuard<T> {
|
|||
}
|
||||
};
|
||||
unsafe {
|
||||
*their_packet.get() = Some(match (output, try_result) {
|
||||
*their_packet.0.get() = Some(match (output, try_result) {
|
||||
(Some(data), Ok(_)) => Ok(data),
|
||||
(None, Err(cause)) => Err(cause),
|
||||
_ => unreachable!()
|
||||
|
@ -383,6 +383,11 @@ fn new(name: Option<String>) -> Thread { Thread::new(name) }
|
|||
/// A thread that completes without panicking is considered to exit successfully.
|
||||
pub type Result<T> = ::result::Result<T, Box<Any + Send>>;
|
||||
|
||||
struct Packet<T>(Arc<UnsafeCell<Option<Result<T>>>>);
|
||||
|
||||
unsafe impl<T:'static+Send> Send for Packet<T> {}
|
||||
unsafe impl<T> Sync for Packet<T> {}
|
||||
|
||||
#[must_use]
|
||||
/// An RAII-style guard that will block until thread termination when dropped.
|
||||
///
|
||||
|
@ -391,9 +396,11 @@ pub struct JoinGuard<T> {
|
|||
native: imp::rust_thread,
|
||||
thread: Thread,
|
||||
joined: bool,
|
||||
packet: Arc<RacyCell<Option<Result<T>>>>,
|
||||
packet: Packet<T>,
|
||||
}
|
||||
|
||||
unsafe impl<T: Send> Sync for JoinGuard<T> {}
|
||||
|
||||
impl<T: Send> JoinGuard<T> {
|
||||
/// Extract a handle to the thread this guard will join on.
|
||||
pub fn thread(&self) -> &Thread {
|
||||
|
@ -410,7 +417,7 @@ pub fn join(mut self) -> Result<T> {
|
|||
unsafe { imp::join(self.native) };
|
||||
self.joined = true;
|
||||
unsafe {
|
||||
(*self.packet.get()).take().unwrap()
|
||||
(*self.packet.0.get()).take().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -196,10 +196,10 @@ pub fn is_set(&'static self) -> bool {
|
|||
|
||||
#[cfg(not(any(windows, target_os = "android", target_os = "ios")))]
|
||||
mod imp {
|
||||
use std::comm::RacyCell;
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
#[doc(hidden)]
|
||||
pub struct KeyInner<T> { pub inner: RacyCell<*mut T> }
|
||||
pub struct KeyInner<T> { pub inner: UnsafeCell<*mut T> }
|
||||
|
||||
unsafe impl<T> ::kinds::Sync for KeyInner<T> { }
|
||||
|
||||
|
|
|
@ -9,29 +9,32 @@
|
|||
// except according to those terms.
|
||||
|
||||
use std::kinds::marker;
|
||||
use std::comm::RacyCell;
|
||||
use std::cell::UnsafeCell;
|
||||
|
||||
struct MyUnsafe<T> {
|
||||
value: RacyCell<T>
|
||||
value: UnsafeCell<T>
|
||||
}
|
||||
|
||||
impl<T> MyUnsafe<T> {
|
||||
fn forbidden(&self) {}
|
||||
}
|
||||
|
||||
impl<T: Send> Sync for MyUnsafe<T> {}
|
||||
|
||||
enum UnsafeEnum<T> {
|
||||
VariantSafe,
|
||||
VariantUnsafe(RacyCell<T>)
|
||||
VariantUnsafe(UnsafeCell<T>)
|
||||
}
|
||||
|
||||
impl<T: Send> Sync for UnsafeEnum<T> {}
|
||||
|
||||
static STATIC1: UnsafeEnum<int> = UnsafeEnum::VariantSafe;
|
||||
|
||||
static STATIC2: RacyCell<int> = RacyCell(UnsafeCell { value: 1 });
|
||||
const CONST: RacyCell<int> = RacyCell(UnsafeCell { value: 1 });
|
||||
static STATIC2: UnsafeCell<int> = UnsafeCell { value: 1 };
|
||||
const CONST: UnsafeCell<int> = UnsafeCell { value: 1 };
|
||||
static STATIC3: MyUnsafe<int> = MyUnsafe{value: CONST};
|
||||
|
||||
static STATIC4: &'static RacyCell<int> = &STATIC2;
|
||||
static STATIC4: &'static UnsafeCell<int> = &STATIC2;
|
||||
|
||||
struct Wrap<T> {
|
||||
value: T
|
||||
|
@ -39,13 +42,11 @@ struct Wrap<T> {
|
|||
|
||||
unsafe impl<T: Send> Sync for Wrap<T> {}
|
||||
|
||||
static UNSAFE: RacyCell<int> = RacyCell(UnsafeCell{value: 1});
|
||||
static WRAPPED_UNSAFE: Wrap<&'static RacyCell<int>> = Wrap { value: &UNSAFE };
|
||||
static UNSAFE: UnsafeCell<int> = UnsafeCell{value: 1};
|
||||
static WRAPPED_UNSAFE: Wrap<&'static UnsafeCell<int>> = Wrap { value: &UNSAFE };
|
||||
|
||||
fn main() {
|
||||
let a = &STATIC1;
|
||||
|
||||
STATIC3.forbidden()
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue