From fb803a857000813e4d572900799f0498fb20050b Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sat, 6 Dec 2014 11:39:25 -0500 Subject: Require types to opt-in Sync --- src/libstd/c_str.rs | 6 +++-- src/libstd/collections/hash/table.rs | 20 ++++++++--------- src/libstd/comm/blocking.rs | 1 + src/libstd/comm/mod.rs | 40 +++++++++++++++++++--------------- src/libstd/comm/mpsc_queue.rs | 3 +++ src/libstd/comm/spsc_queue.rs | 4 ++++ src/libstd/comm/sync.rs | 7 ++++++ src/libstd/rt/exclusive.rs | 4 ++++ src/libstd/sync/mutex.rs | 15 ++++++++----- src/libstd/sync/once.rs | 1 + src/libstd/sys/common/helper_thread.rs | 4 ++++ src/libstd/sys/common/mutex.rs | 1 + src/libstd/sys/unix/c.rs | 6 +++++ src/libstd/sys/unix/mutex.rs | 7 +++--- src/libstd/sys/unix/pipe.rs | 2 ++ src/libstd/sys/unix/stack_overflow.rs | 2 +- src/libstd/sys/unix/tcp.rs | 2 ++ src/libstd/thread.rs | 11 +++++----- src/libstd/thread_local/mod.rs | 4 ++++ src/libstd/thread_local/scoped.rs | 6 ++++- 20 files changed, 101 insertions(+), 45 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index fb44961017f..27b63be6cd0 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -72,13 +72,12 @@ use libc; use fmt; use hash; -use kinds::marker; use mem; use ptr; use slice::{mod, ImmutableIntSlice}; use str; use string::String; - +use core::kinds::marker; /// The representation of a C String. /// @@ -90,6 +89,9 @@ pub struct CString { owns_buffer_: bool, } +impl Send for CString { } +impl Sync for CString { } + impl Clone for CString { /// Clone this CString into a new, uniquely owned CString. For safety /// reasons, this is always a deep clone with the memory allocated diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 8f2152c5a9d..ee37eb27795 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -23,7 +23,7 @@ use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{Some, None}; -use ptr::{RawPtr, copy_nonoverlapping_memory, zero_memory}; +use ptr::{OwnedPtr, RawPtr, copy_nonoverlapping_memory, zero_memory}; use ptr; use rt::heap::{allocate, deallocate}; @@ -69,7 +69,7 @@ const EMPTY_BUCKET: u64 = 0u64; pub struct RawTable { capacity: uint, size: uint, - hashes: *mut u64, + hashes: OwnedPtr, // Because K/V do not appear directly in any of the types in the struct, // inform rustc that in fact instances of K and V are reachable from here. marker: marker::CovariantType<(K,V)>, @@ -563,7 +563,7 @@ impl RawTable { return RawTable { size: 0, capacity: 0, - hashes: 0 as *mut u64, + hashes: OwnedPtr::null(), marker: marker::CovariantType, }; } @@ -602,7 +602,7 @@ impl RawTable { RawTable { capacity: capacity, size: 0, - hashes: hashes, + hashes: OwnedPtr(hashes), marker: marker::CovariantType, } } @@ -611,14 +611,14 @@ impl RawTable { let hashes_size = self.capacity * size_of::(); let keys_size = self.capacity * size_of::(); - let buffer = self.hashes as *mut u8; + let buffer = self.hashes.0 as *mut u8; let (keys_offset, vals_offset) = calculate_offsets(hashes_size, keys_size, min_align_of::(), min_align_of::()); unsafe { RawBucket { - hash: self.hashes, + hash: self.hashes.0, key: buffer.offset(keys_offset as int) as *mut K, val: buffer.offset(vals_offset as int) as *mut V } @@ -631,7 +631,7 @@ impl RawTable { pub fn new(capacity: uint) -> RawTable { unsafe { let ret = RawTable::new_uninitialized(capacity); - zero_memory(ret.hashes, capacity); + zero_memory(ret.hashes.0, capacity); ret } } @@ -651,7 +651,7 @@ impl RawTable { RawBuckets { raw: self.first_bucket_raw(), hashes_end: unsafe { - self.hashes.offset(self.capacity as int) + self.hashes.0.offset(self.capacity as int) }, marker: marker::ContravariantLifetime, } @@ -916,7 +916,7 @@ impl Clone for RawTable { #[unsafe_destructor] impl Drop for RawTable { fn drop(&mut self) { - if self.hashes.is_null() { + if self.hashes.0.is_null() { return; } // This is done in reverse because we've likely partially taken @@ -936,7 +936,7 @@ impl Drop for RawTable { vals_size, min_align_of::()); unsafe { - deallocate(self.hashes as *mut u8, size, align); + deallocate(self.hashes.0 as *mut u8, size, align); // Remember how everything was allocated out of one buffer // during initialization? We only need one call to free here. } diff --git a/src/libstd/comm/blocking.rs b/src/libstd/comm/blocking.rs index c477acd70aa..a154224824c 100644 --- a/src/libstd/comm/blocking.rs +++ b/src/libstd/comm/blocking.rs @@ -17,6 +17,7 @@ use kinds::marker::{NoSend, NoSync}; use mem; use clone::Clone; +#[deriving(Send, Sync)] struct Inner { thread: Thread, woken: AtomicBool, diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 7352cdfbfe7..18b50c621e9 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -321,7 +321,7 @@ use self::Flavor::*; use alloc::arc::Arc; use core::kinds::marker; use core::mem; -use core::cell::UnsafeCell; +use core::cell::{UnsafeCell, RacyCell}; pub use self::select::{Select, Handle}; use self::select::StartResult; @@ -359,10 +359,12 @@ mod spsc_queue; #[unstable] pub struct Receiver { inner: UnsafeCell>, - // can't share in an arc - _marker: marker::NoSync, } +// The receiver port can be sent from place to place, so long as it +// is not used to receive non-sendable things. +impl Send for Receiver { } + /// An iterator over messages on a receiver, this iterator will block /// whenever `next` is called, waiting for a new message, and `None` will be /// returned when the corresponding channel has hung up. @@ -376,15 +378,17 @@ pub struct Messages<'a, T:'a> { #[unstable] pub struct Sender { inner: UnsafeCell>, - // can't share in an arc - _marker: marker::NoSync, } +// The send port can be sent from place to place, so long as it +// is not used to send non-sendable things. +impl Send for Sender { } + /// The sending-half of Rust's synchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. #[unstable = "this type may be renamed, but it will always exist"] pub struct SyncSender { - inner: Arc>>, + inner: Arc>>, // can't share in an arc _marker: marker::NoSync, } @@ -420,10 +424,10 @@ pub enum TrySendError { } enum Flavor { - Oneshot(Arc>>), - Stream(Arc>>), - Shared(Arc>>), - Sync(Arc>>), + Oneshot(Arc>>), + Stream(Arc>>), + Shared(Arc>>), + Sync(Arc>>), } #[doc(hidden)] @@ -474,7 +478,7 @@ impl UnsafeFlavor for Receiver { /// ``` #[unstable] pub fn channel() -> (Sender, Receiver) { - let a = Arc::new(UnsafeCell::new(oneshot::Packet::new())); + let a = Arc::new(RacyCell::new(oneshot::Packet::new())); (Sender::new(Oneshot(a.clone())), Receiver::new(Oneshot(a))) } @@ -514,7 +518,7 @@ pub fn channel() -> (Sender, Receiver) { #[unstable = "this function may be renamed to more accurately reflect the type \ of channel that is is creating"] pub fn sync_channel(bound: uint) -> (SyncSender, Receiver) { - let a = Arc::new(UnsafeCell::new(sync::Packet::new(bound))); + let a = Arc::new(RacyCell::new(sync::Packet::new(bound))); (SyncSender::new(a.clone()), Receiver::new(Sync(a))) } @@ -526,7 +530,6 @@ impl Sender { fn new(inner: Flavor) -> Sender { Sender { inner: UnsafeCell::new(inner), - _marker: marker::NoSync, } } @@ -596,7 +599,8 @@ impl Sender { if !(*p).sent() { return (*p).send(t); } else { - let a = Arc::new(UnsafeCell::new(stream::Packet::new())); + let a = + Arc::new(RacyCell::new(stream::Packet::new())); match (*p).upgrade(Receiver::new(Stream(a.clone()))) { oneshot::UpSuccess => { let ret = (*a.get()).send(t); @@ -633,7 +637,7 @@ impl Clone for Sender { fn clone(&self) -> Sender { let (packet, sleeper, guard) = match *unsafe { self.inner() } { Oneshot(ref p) => { - let a = Arc::new(UnsafeCell::new(shared::Packet::new())); + let a = Arc::new(RacyCell::new(shared::Packet::new())); unsafe { let guard = (*a.get()).postinit_lock(); match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) { @@ -644,7 +648,7 @@ impl Clone for Sender { } } Stream(ref p) => { - let a = Arc::new(UnsafeCell::new(shared::Packet::new())); + let a = Arc::new(RacyCell::new(shared::Packet::new())); unsafe { let guard = (*a.get()).postinit_lock(); match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) { @@ -688,7 +692,7 @@ impl Drop for Sender { //////////////////////////////////////////////////////////////////////////////// impl SyncSender { - fn new(inner: Arc>>) -> SyncSender { + fn new(inner: Arc>>) -> SyncSender { SyncSender { inner: inner, _marker: marker::NoSync } } @@ -777,7 +781,7 @@ impl Drop for SyncSender { impl Receiver { fn new(inner: Flavor) -> Receiver { - Receiver { inner: UnsafeCell::new(inner), _marker: marker::NoSync } + Receiver { inner: UnsafeCell::new(inner) } } /// Blocks waiting for a value on this receiver diff --git a/src/libstd/comm/mpsc_queue.rs b/src/libstd/comm/mpsc_queue.rs index db4e3eac449..6298896a18b 100644 --- a/src/libstd/comm/mpsc_queue.rs +++ b/src/libstd/comm/mpsc_queue.rs @@ -76,6 +76,9 @@ pub struct Queue { tail: UnsafeCell<*mut Node>, } +impl Send for Queue { } +impl Sync for Queue { } + impl Node { unsafe fn new(v: Option) -> *mut Node { mem::transmute(box Node { diff --git a/src/libstd/comm/spsc_queue.rs b/src/libstd/comm/spsc_queue.rs index db8fff772a4..dbf1f255997 100644 --- a/src/libstd/comm/spsc_queue.rs +++ b/src/libstd/comm/spsc_queue.rs @@ -73,6 +73,10 @@ pub struct Queue { cache_subtractions: AtomicUint, } +impl Send for Queue { } + +impl Sync for Queue { } + impl Node { fn new() -> *mut Node { unsafe { diff --git a/src/libstd/comm/sync.rs b/src/libstd/comm/sync.rs index f75186e70e3..f4f4c7472e2 100644 --- a/src/libstd/comm/sync.rs +++ b/src/libstd/comm/sync.rs @@ -53,6 +53,11 @@ pub struct Packet { lock: Mutex>, } +impl Send for Packet { } + +impl Sync for Packet { } + +#[deriving(Send)] struct State { disconnected: bool, // Is the channel disconnected yet? queue: Queue, // queue of senders waiting to send data @@ -88,6 +93,8 @@ struct Node { next: *mut Node, } +impl Send for Node {} + /// A simple ring-buffer struct Buffer { buf: Vec>, diff --git a/src/libstd/rt/exclusive.rs b/src/libstd/rt/exclusive.rs index 1d3082d1b4c..a878066ad16 100644 --- a/src/libstd/rt/exclusive.rs +++ b/src/libstd/rt/exclusive.rs @@ -26,6 +26,10 @@ pub struct Exclusive { data: UnsafeCell, } +impl Send for Exclusive { } + +impl Sync for Exclusive { } + /// An RAII guard returned via `lock` pub struct ExclusiveGuard<'a, T:'a> { // FIXME #12808: strange name to try to avoid interfering with diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 4829be569cc..2849813c510 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -10,7 +10,7 @@ use prelude::*; -use cell::UnsafeCell; +use cell::{UnsafeCell, RacyCell}; use kinds::marker; use sync::{poison, AsMutexGuard}; use sys_common::mutex as sys; @@ -70,9 +70,13 @@ pub struct Mutex { // time, so to ensure that the native mutex is used correctly we box the // inner lock to give it a constant address. inner: Box, - data: UnsafeCell, + data: RacyCell, } +impl Send for Mutex { } + +impl Sync for Mutex { } + /// The static mutex type is provided to allow for static allocation of mutexes. /// /// Note that this is a separate type because using a Mutex correctly means that @@ -94,9 +98,10 @@ pub struct Mutex { /// } /// // lock is unlocked here. /// ``` +#[deriving(Sync)] pub struct StaticMutex { lock: sys::Mutex, - poison: UnsafeCell, + poison: RacyCell, } /// An RAII implementation of a "scoped lock" of a mutex. When this structure is @@ -125,7 +130,7 @@ pub struct StaticMutexGuard { /// other mutex constants. pub const MUTEX_INIT: StaticMutex = StaticMutex { lock: sys::MUTEX_INIT, - poison: UnsafeCell { value: poison::Flag { failed: false } }, + poison: RacyCell(UnsafeCell { value: poison::Flag { failed: false } }), }; impl Mutex { @@ -133,7 +138,7 @@ impl Mutex { pub fn new(t: T) -> Mutex { Mutex { inner: box MUTEX_INIT, - data: UnsafeCell::new(t), + data: RacyCell::new(t), } } diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index a43f822e351..4b940b0420a 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -35,6 +35,7 @@ use sync::{StaticMutex, MUTEX_INIT}; /// // run initialization here /// }); /// ``` +#[deriving(Sync)] pub struct Once { mutex: StaticMutex, cnt: atomic::AtomicInt, diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 421778e2012..9df69d8e0d6 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -59,6 +59,10 @@ pub struct Helper { pub shutdown: UnsafeCell, } +impl Send for Helper { } + +impl Sync for Helper { } + impl Helper { /// Lazily boots a helper thread, becoming a no-op if the helper has already /// been spawned. diff --git a/src/libstd/sys/common/mutex.rs b/src/libstd/sys/common/mutex.rs index 1a8a92a105a..5869c280517 100644 --- a/src/libstd/sys/common/mutex.rs +++ b/src/libstd/sys/common/mutex.rs @@ -15,6 +15,7 @@ use sys::mutex as imp; /// This is the thinnest cross-platform wrapper around OS mutexes. All usage of /// this mutex is unsafe and it is recommended to instead use the safe wrapper /// at the top level of the crate instead of this type. +#[deriving(Sync)] pub struct Mutex(imp::Mutex); /// Constant initializer for statically allocated mutexes. diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs index e76f2a2b872..a5796f8dd01 100644 --- a/src/libstd/sys/unix/c.rs +++ b/src/libstd/sys/unix/c.rs @@ -162,6 +162,9 @@ mod signal { sa_restorer: *mut libc::c_void, } + impl ::kinds::Send for sigaction { } + impl ::kinds::Sync for sigaction { } + #[repr(C)] #[cfg(target_word_size = "32")] pub struct sigset_t { @@ -211,6 +214,9 @@ mod signal { sa_resv: [libc::c_int, ..1], } + impl ::kinds::Send for sigaction { } + impl ::kinds::Sync for sigaction { } + #[repr(C)] pub struct sigset_t { __val: [libc::c_ulong, ..32], diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index 2f01c53cb2c..52ed0649694 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -8,11 +8,12 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use cell::UnsafeCell; +use cell::{UnsafeCell, RacyCell}; use sys::sync as ffi; use sys_common::mutex; -pub struct Mutex { inner: UnsafeCell } +#[deriving(Sync)] +pub struct Mutex { inner: RacyCell } #[inline] pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t { @@ -20,7 +21,7 @@ pub unsafe fn raw(m: &Mutex) -> *mut ffi::pthread_mutex_t { } pub const MUTEX_INIT: Mutex = Mutex { - inner: UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER }, + inner: RacyCell(UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER }), }; impl Mutex { diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 348b7cfad33..8d1010937bc 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -210,6 +210,7 @@ impl Clone for UnixStream { // Unix Listener //////////////////////////////////////////////////////////////////////////////// +#[deriving(Sync)] pub struct UnixListener { inner: Inner, path: CString, @@ -252,6 +253,7 @@ pub struct UnixAcceptor { deadline: u64, } +#[deriving(Sync)] struct AcceptorInner { listener: UnixListener, reader: FileDesc, diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs index 340f9514241..bcbbb8766b7 100644 --- a/src/libstd/sys/unix/stack_overflow.rs +++ b/src/libstd/sys/unix/stack_overflow.rs @@ -160,7 +160,7 @@ mod imp { pub static SIGSTKSZ: libc::size_t = 8192; - pub static SIG_DFL: sighandler_t = 0i as sighandler_t; + pub const SIG_DFL: sighandler_t = 0i as sighandler_t; // This definition is not as accurate as it could be, {si_addr} is // actually a giant union. Currently we're only interested in that field, diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index 5c99ad1e0ce..60ca76171b1 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -29,6 +29,7 @@ pub use sys_common::net::TcpStream; // TCP listeners //////////////////////////////////////////////////////////////////////////////// +#[deriving(Sync)] pub struct TcpListener { pub inner: FileDesc, } @@ -89,6 +90,7 @@ pub struct TcpAcceptor { deadline: u64, } +#[deriving(Sync)] struct AcceptorInner { listener: TcpListener, reader: FileDesc, diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 89773207347..e3b97afb31d 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -127,9 +127,9 @@ use any::Any; use borrow::IntoCow; use boxed::Box; -use cell::UnsafeCell; +use cell::RacyCell; use clone::Clone; -use kinds::Send; +use kinds::{Send, Sync}; use ops::{Drop, FnOnce}; use option::Option::{mod, Some, None}; use result::Result::{Err, Ok}; @@ -211,7 +211,7 @@ impl Builder { } fn spawn_inner(self, f: Thunk<(), T>) -> JoinGuard { - let my_packet = Arc::new(UnsafeCell::new(None)); + let my_packet = Arc::new(RacyCell::new(None)); let their_packet = my_packet.clone(); let Builder { name, stack_size, stdout, stderr } = self; @@ -283,13 +283,14 @@ impl Builder { } } +#[deriving(Sync)] struct Inner { name: Option, lock: Mutex, // true when there is a buffered unpark cvar: Condvar, } -#[deriving(Clone)] +#[deriving(Clone, Sync)] /// A handle to a thread. pub struct Thread { inner: Arc, @@ -387,7 +388,7 @@ pub struct JoinGuard { native: imp::rust_thread, thread: Thread, joined: bool, - packet: Arc>>>, + packet: Arc>>>, } impl JoinGuard { diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index 04718dcc6ae..55fb3151133 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -280,6 +280,8 @@ mod imp { pub dtor_running: UnsafeCell, // should be Cell } + impl ::kinds::Sync for Key { } + #[doc(hidden)] impl Key { pub unsafe fn get(&'static self) -> Option<&'static T> { @@ -410,6 +412,8 @@ mod imp { pub os: OsStaticKey, } + impl ::kinds::Sync for Key { } + struct Value { key: &'static Key, value: T, diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs index 643a0f55e74..83e61373dd1 100644 --- a/src/libstd/thread_local/scoped.rs +++ b/src/libstd/thread_local/scoped.rs @@ -198,10 +198,12 @@ impl Key { mod imp { use std::cell::UnsafeCell; - // FIXME: Should be a `Cell`, but that's not `Sync` + // SNAP c9f6d69 switch to `Cell` #[doc(hidden)] pub struct KeyInner { pub inner: UnsafeCell<*mut T> } + #[cfg(not(stage0))] impl ::kinds::Sync for KeyInner { } + #[doc(hidden)] impl KeyInner { #[doc(hidden)] @@ -222,6 +224,8 @@ mod imp { pub marker: marker::InvariantType, } + #[cfg(not(stage0))] impl ::kinds::Sync for KeyInner { } + #[doc(hidden)] impl KeyInner { #[doc(hidden)] -- cgit 1.4.1-3-g733a5 From 686ce664da31f87b8d1c7377313f160d8fdcebe9 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 22 Dec 2014 00:01:20 +0100 Subject: Rename `OwnedPtr` to `UniquePtr` --- src/liballoc/boxed.rs | 4 ++-- src/libcollections/vec.rs | 20 +++++++++--------- src/libcore/ptr.rs | 24 +++++++++++----------- src/libflate/lib.rs | 6 +++--- src/librustc/middle/mem_categorization.rs | 14 ++++++------- src/librustc_borrowck/borrowck/check_loans.rs | 12 +++++------ src/librustc_borrowck/borrowck/fragments.rs | 4 ++-- .../borrowck/gather_loans/gather_moves.rs | 2 +- .../borrowck/gather_loans/lifetime.rs | 4 ++-- .../borrowck/gather_loans/restrictions.rs | 2 +- src/librustc_typeck/check/regionck.rs | 6 +++--- src/libstd/collections/hash/table.rs | 8 ++++---- 12 files changed, 53 insertions(+), 53 deletions(-) (limited to 'src/libstd') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 0f81d43356d..6825a42ef08 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -19,7 +19,7 @@ use core::hash::{mod, Hash}; use core::kinds::Sized; use core::mem; use core::option::Option; -use core::ptr::OwnedPtr; +use core::ptr::UniquePtr; use core::raw::TraitObject; use core::result::Result; use core::result::Result::{Ok, Err}; @@ -45,7 +45,7 @@ pub static HEAP: () = (); /// A type that represents a uniquely-owned value. #[lang = "owned_box"] #[unstable = "custom allocators will add an additional type parameter (with default)"] -pub struct Box(OwnedPtr); +pub struct Box(UniquePtr); #[stable] impl Default for Box { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index 9b668b25df3..e4522597b9d 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -58,7 +58,7 @@ use core::kinds::marker::{ContravariantLifetime, InvariantType}; use core::mem; use core::num::{Int, UnsignedInt}; use core::ops; -use core::ptr::{mod, OwnedPtr}; +use core::ptr::{mod, UniquePtr}; use core::raw::Slice as RawSlice; use core::uint; @@ -133,7 +133,7 @@ use slice::CloneSliceExt; #[unsafe_no_drop_flag] #[stable] pub struct Vec { - ptr: OwnedPtr, + ptr: UniquePtr, len: uint, cap: uint, } @@ -176,7 +176,7 @@ impl Vec { // non-null value which is fine since we never call deallocate on the ptr // if cap is 0. The reason for this is because the pointer of a slice // being NULL would break the null pointer optimization for enums. - Vec { ptr: OwnedPtr(EMPTY as *mut T), len: 0, cap: 0 } + Vec { ptr: UniquePtr(EMPTY as *mut T), len: 0, cap: 0 } } /// Constructs a new, empty `Vec` with the specified capacity. @@ -209,7 +209,7 @@ impl Vec { #[stable] pub fn with_capacity(capacity: uint) -> Vec { if mem::size_of::() == 0 { - Vec { ptr: OwnedPtr(EMPTY as *mut T), len: 0, cap: uint::MAX } + Vec { ptr: UniquePtr(EMPTY as *mut T), len: 0, cap: uint::MAX } } else if capacity == 0 { Vec::new() } else { @@ -217,7 +217,7 @@ impl Vec { .expect("capacity overflow"); let ptr = unsafe { allocate(size, mem::min_align_of::()) }; if ptr.is_null() { ::alloc::oom() } - Vec { ptr: OwnedPtr(ptr as *mut T), len: 0, cap: capacity } + Vec { ptr: UniquePtr(ptr as *mut T), len: 0, cap: capacity } } } @@ -284,7 +284,7 @@ impl Vec { #[unstable = "needs finalization"] pub unsafe fn from_raw_parts(ptr: *mut T, length: uint, capacity: uint) -> Vec { - Vec { ptr: OwnedPtr(ptr), len: length, cap: capacity } + Vec { ptr: UniquePtr(ptr), len: length, cap: capacity } } /// Creates a vector by copying the elements from a raw pointer. @@ -803,7 +803,7 @@ impl Vec { unsafe { // Overflow check is unnecessary as the vector is already at // least this large. - self.ptr = OwnedPtr(reallocate(self.ptr.0 as *mut u8, + self.ptr = UniquePtr(reallocate(self.ptr.0 as *mut u8, self.cap * mem::size_of::(), self.len * mem::size_of::(), mem::min_align_of::()) as *mut T); @@ -1110,7 +1110,7 @@ impl Vec { let size = max(old_size, 2 * mem::size_of::()) * 2; if old_size > size { panic!("capacity overflow") } unsafe { - self.ptr = OwnedPtr(alloc_or_realloc(self.ptr.0, old_size, size)); + self.ptr = UniquePtr(alloc_or_realloc(self.ptr.0, old_size, size)); if self.ptr.0.is_null() { ::alloc::oom() } } self.cap = max(self.cap, 2) * 2; @@ -1231,7 +1231,7 @@ impl Vec { let size = capacity.checked_mul(mem::size_of::()) .expect("capacity overflow"); unsafe { - self.ptr = OwnedPtr(alloc_or_realloc(self.ptr.0, + self.ptr = UniquePtr(alloc_or_realloc(self.ptr.0, self.cap * mem::size_of::(), size)); if self.ptr.0.is_null() { ::alloc::oom() } @@ -1420,7 +1420,7 @@ impl IntoIter { for _x in self { } let IntoIter { allocation, cap, ptr: _ptr, end: _end } = self; mem::forget(self); - Vec { ptr: OwnedPtr(allocation), cap: cap, len: 0 } + Vec { ptr: UniquePtr(allocation), cap: cap, len: 0 } } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 9b8a3f97f39..6bde1015d29 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -505,28 +505,28 @@ impl PartialOrd for *mut T { /// A wrapper around a raw `*mut T` that indicates that the possessor /// of this wrapper owns the referent. This in turn implies that the -/// `OwnedPtr` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a +/// `UniquePtr` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a /// raw `*mut T` (which conveys no particular ownership semantics). /// Useful for building abstractions like `Vec` or `Box`, which /// internally use raw pointers to manage the memory that they own. -pub struct OwnedPtr(pub *mut T); +pub struct UniquePtr(pub *mut T); -/// `OwnedPtr` pointers are `Send` if `T` is `Send` because the data they +/// `UniquePtr` pointers are `Send` if `T` is `Send` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the -/// `OwnedPtr` must enforce it. -impl Send for OwnedPtr { } +/// `UniquePtr` must enforce it. +impl Send for UniquePtr { } -/// `OwnedPtr` pointers are `Sync` if `T` is `Sync` because the data they +/// `UniquePtr` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the -/// `OwnedPtr` must enforce it. -impl Sync for OwnedPtr { } +/// `UniquePtr` must enforce it. +impl Sync for UniquePtr { } -impl OwnedPtr { - /// Returns a null OwnedPtr. - pub fn null() -> OwnedPtr { - OwnedPtr(RawPtr::null()) +impl UniquePtr { + /// Returns a null UniquePtr. + pub fn null() -> UniquePtr { + UniquePtr(RawPtr::null()) } /// Return an (unsafe) pointer into the memory owned by `self`. diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 1f14fde9ed4..3326960baa8 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -29,7 +29,7 @@ extern crate libc; use libc::{c_void, size_t, c_int}; use std::c_vec::CVec; -use std::ptr::OwnedPtr; +use std::ptr::UniquePtr; #[link(name = "miniz", kind = "static")] extern { @@ -60,7 +60,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { &mut outsz, flags); if !res.is_null() { - let res = OwnedPtr(res); + let res = UniquePtr(res); Some(CVec::new_with_dtor(res.0 as *mut u8, outsz as uint, move|:| libc::free(res.0))) } else { None @@ -86,7 +86,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { &mut outsz, flags); if !res.is_null() { - let res = OwnedPtr(res); + let res = UniquePtr(res); Some(CVec::new_with_dtor(res.0 as *mut u8, outsz as uint, move|:| libc::free(res.0))) } else { None diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 932a124ed33..ad74c8d8bda 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -113,7 +113,7 @@ pub struct Upvar { // different kinds of pointers: #[deriving(Clone, Copy, PartialEq, Eq, Hash, Show)] pub enum PointerKind { - OwnedPtr, + UniquePtr, BorrowedPtr(ty::BorrowKind, ty::Region), Implicit(ty::BorrowKind, ty::Region), // Implicit deref of a borrowed ptr. UnsafePtr(ast::Mutability) @@ -199,7 +199,7 @@ pub fn opt_deref_kind(t: Ty) -> Option { match t.sty { ty::ty_uniq(_) | ty::ty_closure(box ty::ClosureTy {store: ty::UniqTraitStore, ..}) => { - Some(deref_ptr(OwnedPtr)) + Some(deref_ptr(UniquePtr)) } ty::ty_rptr(r, mt) => { @@ -315,7 +315,7 @@ impl MutabilityCategory { pub fn from_pointer_kind(base_mutbl: MutabilityCategory, ptr: PointerKind) -> MutabilityCategory { match ptr { - OwnedPtr => { + UniquePtr => { base_mutbl.inherit() } BorrowedPtr(borrow_kind, _) | Implicit(borrow_kind, _) => { @@ -1351,7 +1351,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { Implicit(..) => { "dereference (dereference is implicit, due to indexing)".to_string() } - OwnedPtr => format!("dereference of `{}`", ptr_sigil(pk)), + UniquePtr => format!("dereference of `{}`", ptr_sigil(pk)), _ => format!("dereference of `{}`-pointer", ptr_sigil(pk)) } } @@ -1412,7 +1412,7 @@ impl<'tcx> cmt_<'tcx> { } cat_downcast(ref b, _) | cat_interior(ref b, _) | - cat_deref(ref b, _, OwnedPtr) => { + cat_deref(ref b, _, UniquePtr) => { b.guarantor() } } @@ -1431,7 +1431,7 @@ impl<'tcx> cmt_<'tcx> { cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) | cat_deref(ref b, _, Implicit(ty::UniqueImmBorrow, _)) | cat_downcast(ref b, _) | - cat_deref(ref b, _, OwnedPtr) | + cat_deref(ref b, _, UniquePtr) | cat_interior(ref b, _) => { // Aliasability depends on base cmt b.freely_aliasable(ctxt) @@ -1523,7 +1523,7 @@ impl<'tcx> Repr<'tcx> for categorization<'tcx> { pub fn ptr_sigil(ptr: PointerKind) -> &'static str { match ptr { - OwnedPtr => "Box", + UniquePtr => "Box", BorrowedPtr(ty::ImmBorrow, _) | Implicit(ty::ImmBorrow, _) => "&", BorrowedPtr(ty::MutBorrow, _) | diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 568bb023b68..4ae9e60299a 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -33,11 +33,11 @@ use std::rc::Rc; // FIXME (#16118): These functions are intended to allow the borrow checker to // be less precise in its handling of Box while still allowing moves out of a -// Box. They should be removed when OwnedPtr is removed from LoanPath. +// Box. They should be removed when UniquePtr is removed from LoanPath. fn owned_ptr_base_path<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> &'a LoanPath<'tcx> { - //! Returns the base of the leftmost dereference of an OwnedPtr in - //! `loan_path`. If there is no dereference of an OwnedPtr in `loan_path`, + //! Returns the base of the leftmost dereference of an UniquePtr in + //! `loan_path`. If there is no dereference of an UniquePtr in `loan_path`, //! then it just returns `loan_path` itself. return match helper(loan_path) { @@ -48,7 +48,7 @@ fn owned_ptr_base_path<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> &'a LoanPath< fn helper<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> Option<&'a LoanPath<'tcx>> { match loan_path.kind { LpVar(_) | LpUpvar(_) => None, - LpExtend(ref lp_base, _, LpDeref(mc::OwnedPtr)) => { + LpExtend(ref lp_base, _, LpDeref(mc::UniquePtr)) => { match helper(&**lp_base) { v @ Some(_) => v, None => Some(&**lp_base) @@ -72,7 +72,7 @@ fn owned_ptr_base_path_rc<'tcx>(loan_path: &Rc>) -> Rc(loan_path: &Rc>) -> Option>> { match loan_path.kind { LpVar(_) | LpUpvar(_) => None, - LpExtend(ref lp_base, _, LpDeref(mc::OwnedPtr)) => { + LpExtend(ref lp_base, _, LpDeref(mc::UniquePtr)) => { match helper(lp_base) { v @ Some(_) => v, None => Some(lp_base.clone()) @@ -880,7 +880,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { } } - mc::cat_deref(b, _, mc::OwnedPtr) => { + mc::cat_deref(b, _, mc::UniquePtr) => { assert_eq!(cmt.mutbl, mc::McInherited); cmt = b; } diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index dbbc52cf362..5530b8f39ec 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -291,9 +291,9 @@ fn add_fragment_siblings<'tcx>(this: &MoveData<'tcx>, add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id); } - // *LV for OwnedPtr consumes the contents of the box (at + // *LV for UniquePtr consumes the contents of the box (at // least when it is non-copy...), so propagate inward. - LpExtend(ref loan_parent, _, LpDeref(mc::OwnedPtr)) => { + LpExtend(ref loan_parent, _, LpDeref(mc::UniquePtr)) => { add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id); } diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 01cbab6dbf4..5eb16447057 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -190,7 +190,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, } } - mc::cat_deref(ref b, _, mc::OwnedPtr) => { + mc::cat_deref(ref b, _, mc::UniquePtr) => { check_and_get_illegal_move_origin(bccx, b) } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index d7c96346463..39670314cd1 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -84,7 +84,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } mc::cat_downcast(ref base, _) | - mc::cat_deref(ref base, _, mc::OwnedPtr) | // L-Deref-Send + mc::cat_deref(ref base, _, mc::UniquePtr) | // L-Deref-Send mc::cat_interior(ref base, _) => { // L-Field self.check(base, discr_scope) } @@ -129,7 +129,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { r } mc::cat_downcast(ref cmt, _) | - mc::cat_deref(ref cmt, _, mc::OwnedPtr) | + mc::cat_deref(ref cmt, _, mc::UniquePtr) | mc::cat_interior(ref cmt, _) => { self.scope(cmt) } diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index c783489dab7..d940b1079fc 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { mc::cat_deref(cmt_base, _, pk) => { match pk { - mc::OwnedPtr => { + mc::UniquePtr => { // R-Deref-Send-Pointer // // When we borrow the interior of an owned pointer, we diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 22502c0dd1a..dda6240ad82 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1460,7 +1460,7 @@ fn link_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, } mc::cat_downcast(cmt_base, _) | - mc::cat_deref(cmt_base, _, mc::OwnedPtr) | + mc::cat_deref(cmt_base, _, mc::UniquePtr) | mc::cat_interior(cmt_base, _) => { // Borrowing interior or owned data requires the base // to be valid and borrowable in the same fashion. @@ -1684,7 +1684,7 @@ fn adjust_upvar_borrow_kind_for_mut<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, cmt.repr(rcx.tcx())); match cmt.cat.clone() { - mc::cat_deref(base, _, mc::OwnedPtr) | + mc::cat_deref(base, _, mc::UniquePtr) | mc::cat_interior(base, _) | mc::cat_downcast(base, _) => { // Interior or owned data is mutable if base is @@ -1731,7 +1731,7 @@ fn adjust_upvar_borrow_kind_for_unique<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, cmt: mc::c cmt.repr(rcx.tcx())); match cmt.cat.clone() { - mc::cat_deref(base, _, mc::OwnedPtr) | + mc::cat_deref(base, _, mc::UniquePtr) | mc::cat_interior(base, _) | mc::cat_downcast(base, _) => { // Interior or owned data is unique if base is diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index ee37eb27795..643c2b7d074 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -23,7 +23,7 @@ use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{Some, None}; -use ptr::{OwnedPtr, RawPtr, copy_nonoverlapping_memory, zero_memory}; +use ptr::{UniquePtr, RawPtr, copy_nonoverlapping_memory, zero_memory}; use ptr; use rt::heap::{allocate, deallocate}; @@ -69,7 +69,7 @@ const EMPTY_BUCKET: u64 = 0u64; pub struct RawTable { capacity: uint, size: uint, - hashes: OwnedPtr, + hashes: UniquePtr, // Because K/V do not appear directly in any of the types in the struct, // inform rustc that in fact instances of K and V are reachable from here. marker: marker::CovariantType<(K,V)>, @@ -563,7 +563,7 @@ impl RawTable { return RawTable { size: 0, capacity: 0, - hashes: OwnedPtr::null(), + hashes: UniquePtr::null(), marker: marker::CovariantType, }; } @@ -602,7 +602,7 @@ impl RawTable { RawTable { capacity: capacity, size: 0, - hashes: OwnedPtr(hashes), + hashes: UniquePtr(hashes), marker: marker::CovariantType, } } -- cgit 1.4.1-3-g733a5 From f436f9ca2963e33cc41802370bb9c551c833970e Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 22 Dec 2014 00:49:42 +0100 Subject: Make Send and Sync traits unsafe --- src/liballoc/arc.rs | 4 ++-- src/libcore/cell.rs | 4 ++-- src/libcore/kinds.rs | 4 ++-- src/libcore/ptr.rs | 4 ++-- src/librustc_trans/back/write.rs | 2 +- src/librustc_trans/trans/mod.rs | 4 ++-- src/libstd/c_str.rs | 4 ++-- src/libstd/comm/blocking.rs | 5 ++++- src/libstd/comm/mod.rs | 4 ++-- src/libstd/comm/mpsc_queue.rs | 4 ++-- src/libstd/comm/spsc_queue.rs | 4 ++-- src/libstd/comm/sync.rs | 9 +++++---- src/libstd/rt/exclusive.rs | 4 ++-- src/libstd/sync/mutex.rs | 9 +++++---- src/libstd/sync/once.rs | 4 +++- src/libstd/sys/common/helper_thread.rs | 4 ++-- src/libstd/sys/common/mutex.rs | 4 +++- src/libstd/sys/unix/c.rs | 4 ++-- src/libstd/sys/unix/mutex.rs | 4 +++- src/libstd/sys/unix/pipe.rs | 6 ++++-- src/libstd/sys/unix/tcp.rs | 6 ++++-- src/libstd/thread.rs | 7 +++++-- src/libstd/thread_local/mod.rs | 4 ++-- src/libstd/thread_local/scoped.rs | 4 ++-- src/libtest/lib.rs | 2 +- src/test/run-pass/const-block.rs | 2 +- src/test/run-pass/const-cast-ptr-int.rs | 2 +- src/test/run-pass/const-cast.rs | 2 +- src/test/run-pass/issue-13837.rs | 2 +- src/test/run-pass/issue-17718-static-unsafe-interior.rs | 2 +- src/test/run-pass/issue-2718.rs | 2 +- src/test/run-pass/typeck_type_placeholder_1.rs | 2 +- 32 files changed, 73 insertions(+), 55 deletions(-) (limited to 'src/libstd') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index e060ecad974..4810e15d68b 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -129,9 +129,9 @@ pub struct Weak { _ptr: *mut ArcInner, } -impl Send for Arc { } +unsafe impl Send for Arc { } -impl Sync for Arc { } +unsafe impl Sync for Arc { } struct ArcInner { strong: atomic::AtomicUint, diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 89118a6a8e4..6fc6c2a569d 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -577,6 +577,6 @@ impl RacyCell { } } -impl Send for RacyCell { } +unsafe impl Send for RacyCell { } -impl Sync for RacyCell { } // Oh dear +unsafe impl Sync for RacyCell { } // Oh dear diff --git a/src/libcore/kinds.rs b/src/libcore/kinds.rs index b0f46e3d68c..fb030ea45f3 100644 --- a/src/libcore/kinds.rs +++ b/src/libcore/kinds.rs @@ -19,7 +19,7 @@ /// Types able to be transferred across task boundaries. #[lang="send"] -pub trait Send for Sized? : 'static { +pub unsafe trait Send for Sized? : 'static { // empty. } @@ -81,7 +81,7 @@ pub trait Copy for Sized? { /// reference; not doing this is undefined behaviour (for example, /// `transmute`-ing from `&T` to `&mut T` is illegal). #[lang="sync"] -pub trait Sync for Sized? { +pub unsafe trait Sync for Sized? { // Empty } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 6bde1015d29..402e85b4d8b 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -515,13 +515,13 @@ pub struct UniquePtr(pub *mut T); /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `UniquePtr` must enforce it. -impl Send for UniquePtr { } +unsafe impl Send for UniquePtr { } /// `UniquePtr` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `UniquePtr` must enforce it. -impl Sync for UniquePtr { } +unsafe impl Sync for UniquePtr { } impl UniquePtr { /// Returns a null UniquePtr. diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs index 6348ce89608..513b955da3f 100644 --- a/src/librustc_trans/back/write.rs +++ b/src/librustc_trans/back/write.rs @@ -281,7 +281,7 @@ struct ModuleConfig { time_passes: bool, } -impl Send for ModuleConfig { } +unsafe impl Send for ModuleConfig { } impl ModuleConfig { fn new(tm: TargetMachineRef, passes: Vec) -> ModuleConfig { diff --git a/src/librustc_trans/trans/mod.rs b/src/librustc_trans/trans/mod.rs index c8cfdd3e4e4..7e4517c209b 100644 --- a/src/librustc_trans/trans/mod.rs +++ b/src/librustc_trans/trans/mod.rs @@ -60,8 +60,8 @@ pub struct ModuleTranslation { pub llmod: ModuleRef, } -impl Send for ModuleTranslation { } -impl Sync for ModuleTranslation { } +unsafe impl Send for ModuleTranslation { } +unsafe impl Sync for ModuleTranslation { } pub struct CrateTranslation { pub modules: Vec, diff --git a/src/libstd/c_str.rs b/src/libstd/c_str.rs index 27b63be6cd0..846b542d81a 100644 --- a/src/libstd/c_str.rs +++ b/src/libstd/c_str.rs @@ -89,8 +89,8 @@ pub struct CString { owns_buffer_: bool, } -impl Send for CString { } -impl Sync for CString { } +unsafe impl Send for CString { } +unsafe impl Sync for CString { } impl Clone for CString { /// Clone this CString into a new, uniquely owned CString. For safety diff --git a/src/libstd/comm/blocking.rs b/src/libstd/comm/blocking.rs index a154224824c..412b7161305 100644 --- a/src/libstd/comm/blocking.rs +++ b/src/libstd/comm/blocking.rs @@ -13,16 +13,19 @@ use thread::Thread; use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Ordering}; use sync::Arc; +use kinds::{Sync, Send}; use kinds::marker::{NoSend, NoSync}; use mem; use clone::Clone; -#[deriving(Send, Sync)] struct Inner { thread: Thread, woken: AtomicBool, } +unsafe impl Send for Inner {} +unsafe impl Sync for Inner {} + #[deriving(Clone)] pub struct SignalToken { inner: Arc, diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 18b50c621e9..618a5eebf0f 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -363,7 +363,7 @@ pub struct Receiver { // The receiver port can be sent from place to place, so long as it // is not used to receive non-sendable things. -impl Send for Receiver { } +unsafe impl Send for Receiver { } /// An iterator over messages on a receiver, this iterator will block /// whenever `next` is called, waiting for a new message, and `None` will be @@ -382,7 +382,7 @@ pub struct Sender { // The send port can be sent from place to place, so long as it // is not used to send non-sendable things. -impl Send for Sender { } +unsafe impl Send for Sender { } /// The sending-half of Rust's synchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. diff --git a/src/libstd/comm/mpsc_queue.rs b/src/libstd/comm/mpsc_queue.rs index 6298896a18b..cddef236664 100644 --- a/src/libstd/comm/mpsc_queue.rs +++ b/src/libstd/comm/mpsc_queue.rs @@ -76,8 +76,8 @@ pub struct Queue { tail: UnsafeCell<*mut Node>, } -impl Send for Queue { } -impl Sync for Queue { } +unsafe impl Send for Queue { } +unsafe impl Sync for Queue { } impl Node { unsafe fn new(v: Option) -> *mut Node { diff --git a/src/libstd/comm/spsc_queue.rs b/src/libstd/comm/spsc_queue.rs index dbf1f255997..becb78063ae 100644 --- a/src/libstd/comm/spsc_queue.rs +++ b/src/libstd/comm/spsc_queue.rs @@ -73,9 +73,9 @@ pub struct Queue { cache_subtractions: AtomicUint, } -impl Send for Queue { } +unsafe impl Send for Queue { } -impl Sync for Queue { } +unsafe impl Sync for Queue { } impl Node { fn new() -> *mut Node { diff --git a/src/libstd/comm/sync.rs b/src/libstd/comm/sync.rs index f4f4c7472e2..88338849965 100644 --- a/src/libstd/comm/sync.rs +++ b/src/libstd/comm/sync.rs @@ -53,11 +53,10 @@ pub struct Packet { lock: Mutex>, } -impl Send for Packet { } +unsafe impl Send for Packet { } -impl Sync for Packet { } +unsafe impl Sync for Packet { } -#[deriving(Send)] struct State { disconnected: bool, // Is the channel disconnected yet? queue: Queue, // queue of senders waiting to send data @@ -74,6 +73,8 @@ struct State { canceled: Option<&'static mut bool>, } +unsafe impl Send for State {} + /// Possible flavors of threads who can be blocked on this channel. enum Blocker { BlockedSender(SignalToken), @@ -93,7 +94,7 @@ struct Node { next: *mut Node, } -impl Send for Node {} +unsafe impl Send for Node {} /// A simple ring-buffer struct Buffer { diff --git a/src/libstd/rt/exclusive.rs b/src/libstd/rt/exclusive.rs index a878066ad16..88bdb29caec 100644 --- a/src/libstd/rt/exclusive.rs +++ b/src/libstd/rt/exclusive.rs @@ -26,9 +26,9 @@ pub struct Exclusive { data: UnsafeCell, } -impl Send for Exclusive { } +unsafe impl Send for Exclusive { } -impl Sync for Exclusive { } +unsafe impl Sync for Exclusive { } /// An RAII guard returned via `lock` pub struct ExclusiveGuard<'a, T:'a> { diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 2849813c510..d2dafac281a 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -11,7 +11,7 @@ use prelude::*; use cell::{UnsafeCell, RacyCell}; -use kinds::marker; +use kinds::{marker, Sync}; use sync::{poison, AsMutexGuard}; use sys_common::mutex as sys; @@ -73,9 +73,9 @@ pub struct Mutex { data: RacyCell, } -impl Send for Mutex { } +unsafe impl Send for Mutex { } -impl Sync for Mutex { } +unsafe impl Sync for Mutex { } /// The static mutex type is provided to allow for static allocation of mutexes. /// @@ -98,12 +98,13 @@ impl Sync for Mutex { } /// } /// // lock is unlocked here. /// ``` -#[deriving(Sync)] pub struct StaticMutex { lock: sys::Mutex, poison: RacyCell, } +unsafe impl Sync for StaticMutex {} + /// An RAII implementation of a "scoped lock" of a mutex. When this structure is /// dropped (falls out of scope), the lock will be unlocked. /// diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 4b940b0420a..4d9fbb59908 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -14,6 +14,7 @@ //! example use case would be for initializing an FFI library. use int; +use kinds::Sync; use mem::drop; use ops::FnOnce; use sync::atomic; @@ -35,13 +36,14 @@ use sync::{StaticMutex, MUTEX_INIT}; /// // run initialization here /// }); /// ``` -#[deriving(Sync)] pub struct Once { mutex: StaticMutex, cnt: atomic::AtomicInt, lock_cnt: atomic::AtomicInt, } +unsafe impl Sync for Once {} + /// Initialization value for static `Once` values. pub const ONCE_INIT: Once = Once { mutex: MUTEX_INIT, diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index 9df69d8e0d6..b0137bdad06 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -59,9 +59,9 @@ pub struct Helper { pub shutdown: UnsafeCell, } -impl Send for Helper { } +unsafe impl Send for Helper { } -impl Sync for Helper { } +unsafe impl Sync for Helper { } impl Helper { /// Lazily boots a helper thread, becoming a no-op if the helper has already diff --git a/src/libstd/sys/common/mutex.rs b/src/libstd/sys/common/mutex.rs index 5869c280517..567c26956ef 100644 --- a/src/libstd/sys/common/mutex.rs +++ b/src/libstd/sys/common/mutex.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use kinds::Sync; use sys::mutex as imp; /// An OS-based mutual exclusion lock. @@ -15,9 +16,10 @@ use sys::mutex as imp; /// This is the thinnest cross-platform wrapper around OS mutexes. All usage of /// this mutex is unsafe and it is recommended to instead use the safe wrapper /// at the top level of the crate instead of this type. -#[deriving(Sync)] pub struct Mutex(imp::Mutex); +unsafe impl Sync for Mutex {} + /// Constant initializer for statically allocated mutexes. pub const MUTEX_INIT: Mutex = Mutex(imp::MUTEX_INIT); diff --git a/src/libstd/sys/unix/c.rs b/src/libstd/sys/unix/c.rs index a5796f8dd01..a4ebcbd25d0 100644 --- a/src/libstd/sys/unix/c.rs +++ b/src/libstd/sys/unix/c.rs @@ -162,8 +162,8 @@ mod signal { sa_restorer: *mut libc::c_void, } - impl ::kinds::Send for sigaction { } - impl ::kinds::Sync for sigaction { } + unsafe impl ::kinds::Send for sigaction { } + unsafe impl ::kinds::Sync for sigaction { } #[repr(C)] #[cfg(target_word_size = "32")] diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index 52ed0649694..986f50bc8de 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -8,11 +8,11 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use kinds::Sync; use cell::{UnsafeCell, RacyCell}; use sys::sync as ffi; use sys_common::mutex; -#[deriving(Sync)] pub struct Mutex { inner: RacyCell } #[inline] @@ -24,6 +24,8 @@ pub const MUTEX_INIT: Mutex = Mutex { inner: RacyCell(UnsafeCell { value: ffi::PTHREAD_MUTEX_INITIALIZER }), }; +unsafe impl Sync for Mutex {} + impl Mutex { #[inline] pub unsafe fn new() -> Mutex { diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index 8d1010937bc..c4aec82894f 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -210,12 +210,13 @@ impl Clone for UnixStream { // Unix Listener //////////////////////////////////////////////////////////////////////////////// -#[deriving(Sync)] pub struct UnixListener { inner: Inner, path: CString, } +unsafe impl Sync for UnixListener {} + impl UnixListener { pub fn bind(addr: &CString) -> IoResult { bind(addr, libc::SOCK_STREAM).map(|fd| { @@ -253,7 +254,6 @@ pub struct UnixAcceptor { deadline: u64, } -#[deriving(Sync)] struct AcceptorInner { listener: UnixListener, reader: FileDesc, @@ -261,6 +261,8 @@ struct AcceptorInner { closed: atomic::AtomicBool, } +unsafe impl Sync for AcceptorInner {} + impl UnixAcceptor { pub fn fd(&self) -> fd_t { self.inner.listener.fd() } diff --git a/src/libstd/sys/unix/tcp.rs b/src/libstd/sys/unix/tcp.rs index 60ca76171b1..e2a78947e16 100644 --- a/src/libstd/sys/unix/tcp.rs +++ b/src/libstd/sys/unix/tcp.rs @@ -29,11 +29,12 @@ pub use sys_common::net::TcpStream; // TCP listeners //////////////////////////////////////////////////////////////////////////////// -#[deriving(Sync)] pub struct TcpListener { pub inner: FileDesc, } +unsafe impl Sync for TcpListener {} + impl TcpListener { pub fn bind(addr: ip::SocketAddr) -> IoResult { let fd = try!(net::socket(addr, libc::SOCK_STREAM)); @@ -90,7 +91,6 @@ pub struct TcpAcceptor { deadline: u64, } -#[deriving(Sync)] struct AcceptorInner { listener: TcpListener, reader: FileDesc, @@ -98,6 +98,8 @@ struct AcceptorInner { closed: atomic::AtomicBool, } +unsafe impl Sync for AcceptorInner {} + impl TcpAcceptor { pub fn fd(&self) -> sock_t { self.inner.listener.fd() } diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index e3b97afb31d..92aa5201ec3 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -283,19 +283,22 @@ impl Builder { } } -#[deriving(Sync)] struct Inner { name: Option, lock: Mutex, // true when there is a buffered unpark cvar: Condvar, } -#[deriving(Clone, Sync)] +unsafe impl Sync for Inner {} + +#[deriving(Clone)] /// A handle to a thread. pub struct Thread { inner: Arc, } +unsafe impl Sync for Thread {} + impl Thread { // Used only internally to construct a thread object without spawning fn new(name: Option) -> Thread { diff --git a/src/libstd/thread_local/mod.rs b/src/libstd/thread_local/mod.rs index 55fb3151133..242dceb4256 100644 --- a/src/libstd/thread_local/mod.rs +++ b/src/libstd/thread_local/mod.rs @@ -280,7 +280,7 @@ mod imp { pub dtor_running: UnsafeCell, // should be Cell } - impl ::kinds::Sync for Key { } + unsafe impl ::kinds::Sync for Key { } #[doc(hidden)] impl Key { @@ -412,7 +412,7 @@ mod imp { pub os: OsStaticKey, } - impl ::kinds::Sync for Key { } + unsafe impl ::kinds::Sync for Key { } struct Value { key: &'static Key, diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs index 83e61373dd1..d7ea163cc80 100644 --- a/src/libstd/thread_local/scoped.rs +++ b/src/libstd/thread_local/scoped.rs @@ -202,7 +202,7 @@ mod imp { #[doc(hidden)] pub struct KeyInner { pub inner: UnsafeCell<*mut T> } - #[cfg(not(stage0))] impl ::kinds::Sync for KeyInner { } + unsafe impl ::kinds::Sync for KeyInner { } #[doc(hidden)] impl KeyInner { @@ -224,7 +224,7 @@ mod imp { pub marker: marker::InvariantType, } - #[cfg(not(stage0))] impl ::kinds::Sync for KeyInner { } + unsafe impl ::kinds::Sync for KeyInner { } #[doc(hidden)] impl KeyInner { diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs index dc30f973ff7..88dd6fce88f 100644 --- a/src/libtest/lib.rs +++ b/src/libtest/lib.rs @@ -976,7 +976,7 @@ enum TestEvent { pub type MonitorMsg = (TestDesc, TestResult, Vec ); -impl Send for MonitorMsg {} +unsafe impl Send for MonitorMsg {} fn run_tests(opts: &TestOpts, tests: Vec , diff --git a/src/test/run-pass/const-block.rs b/src/test/run-pass/const-block.rs index 81943b9f13a..35783ea5899 100644 --- a/src/test/run-pass/const-block.rs +++ b/src/test/run-pass/const-block.rs @@ -18,7 +18,7 @@ struct Foo { b: *const () } -impl Sync for Foo {} +unsafe impl Sync for Foo {} fn foo(a: T) -> T { a diff --git a/src/test/run-pass/const-cast-ptr-int.rs b/src/test/run-pass/const-cast-ptr-int.rs index e581a3a65d1..50e460bd179 100644 --- a/src/test/run-pass/const-cast-ptr-int.rs +++ b/src/test/run-pass/const-cast-ptr-int.rs @@ -14,7 +14,7 @@ struct TestStruct { x: *const u8 } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} static a: TestStruct = TestStruct{x: 0 as *const u8}; diff --git a/src/test/run-pass/const-cast.rs b/src/test/run-pass/const-cast.rs index 29c119f742f..b7e9c0338dd 100644 --- a/src/test/run-pass/const-cast.rs +++ b/src/test/run-pass/const-cast.rs @@ -14,7 +14,7 @@ struct TestStruct { x: *const libc::c_void } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} extern fn foo() {} const x: extern "C" fn() = foo; diff --git a/src/test/run-pass/issue-13837.rs b/src/test/run-pass/issue-13837.rs index 3a3d236b69d..c6847ce55de 100644 --- a/src/test/run-pass/issue-13837.rs +++ b/src/test/run-pass/issue-13837.rs @@ -12,7 +12,7 @@ struct TestStruct { x: *const [int; 2] } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} static TEST_VALUE : TestStruct = TestStruct{x: 0x1234 as *const [int; 2]}; diff --git a/src/test/run-pass/issue-17718-static-unsafe-interior.rs b/src/test/run-pass/issue-17718-static-unsafe-interior.rs index 9ca1245f067..17dd6d69fd4 100644 --- a/src/test/run-pass/issue-17718-static-unsafe-interior.rs +++ b/src/test/run-pass/issue-17718-static-unsafe-interior.rs @@ -36,7 +36,7 @@ struct Wrap { value: T } -impl Sync for Wrap {} +unsafe impl Sync for Wrap {} static UNSAFE: RacyCell = RacyCell(UnsafeCell{value: 1}); static WRAPPED_UNSAFE: Wrap<&'static RacyCell> = Wrap { value: &UNSAFE }; diff --git a/src/test/run-pass/issue-2718.rs b/src/test/run-pass/issue-2718.rs index 73cda4ba8fb..d949cab97c2 100644 --- a/src/test/run-pass/issue-2718.rs +++ b/src/test/run-pass/issue-2718.rs @@ -46,7 +46,7 @@ pub mod pipes { payload: Option } - impl Send for packet {} + unsafe impl Send for packet {} pub fn packet() -> *const packet { unsafe { diff --git a/src/test/run-pass/typeck_type_placeholder_1.rs b/src/test/run-pass/typeck_type_placeholder_1.rs index 5e9d778e5ba..a8ae3f40f0e 100644 --- a/src/test/run-pass/typeck_type_placeholder_1.rs +++ b/src/test/run-pass/typeck_type_placeholder_1.rs @@ -15,7 +15,7 @@ struct TestStruct { x: *const int } -impl Sync for TestStruct {} +unsafe impl Sync for TestStruct {} static CONSTEXPR: TestStruct = TestStruct{x: &413 as *const _}; -- cgit 1.4.1-3-g733a5 From e2116c8fba6e73bc2bbf7cb6bb41911d4daed043 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 22 Dec 2014 12:29:46 +0100 Subject: 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. --- src/libcore/atomic.rs | 34 ++++++++++++++-------- src/libcore/cell.rs | 27 +---------------- src/libstd/comm/mod.rs | 29 +++++++++++++++++- src/libstd/sync/mutex.rs | 5 ++-- src/libstd/sys/unix/mutex.rs | 3 +- src/libstd/thread.rs | 2 +- src/libstd/thread_local/scoped.rs | 5 ++-- .../run-pass/issue-17718-static-unsafe-interior.rs | 3 +- 8 files changed, 61 insertions(+), 47 deletions(-) (limited to 'src/libstd') diff --git a/src/libcore/atomic.rs b/src/libcore/atomic.rs index a34f13d127c..9452d0a64bf 100644 --- a/src/libcore/atomic.rs +++ b/src/libcore/atomic.rs @@ -14,33 +14,43 @@ pub use self::Ordering::*; +use kinds::Sync; + use intrinsics; -use cell::{UnsafeCell, RacyCell}; +use cell::UnsafeCell; /// A boolean type which can be safely shared between threads. #[stable] pub struct AtomicBool { - v: RacyCell, + v: UnsafeCell, } +unsafe impl Sync for AtomicBool {} + /// A signed integer type which can be safely shared between threads. #[stable] pub struct AtomicInt { - v: RacyCell, + v: UnsafeCell, } +unsafe impl Sync for AtomicInt {} + /// An unsigned integer type which can be safely shared between threads. #[stable] pub struct AtomicUint { - v: RacyCell, + v: UnsafeCell, } +unsafe impl Sync for AtomicUint {} + /// A raw pointer type which can be safely shared between threads. #[stable] pub struct AtomicPtr { - p: RacyCell, + p: UnsafeCell, } +unsafe impl Sync for AtomicPtr {} + /// Atomic memory orderings /// /// 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`. #[unstable = "may be renamed, pending conventions for static initalizers"] pub const INIT_ATOMIC_BOOL: AtomicBool = - AtomicBool { v: RacyCell(UnsafeCell { value: 0 }) }; + AtomicBool { v: UnsafeCell { value: 0 } }; /// An `AtomicInt` initialized to `0`. #[unstable = "may be renamed, pending conventions for static initalizers"] pub const INIT_ATOMIC_INT: AtomicInt = - AtomicInt { v: RacyCell(UnsafeCell { value: 0 }) }; + AtomicInt { v: UnsafeCell { value: 0 } }; /// An `AtomicUint` initialized to `0`. #[unstable = "may be renamed, pending conventions for static initalizers"] 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 const UINT_TRUE: uint = -1; @@ -108,7 +118,7 @@ impl AtomicBool { #[stable] pub fn new(v: bool) -> AtomicBool { let val = if v { UINT_TRUE } else { 0 }; - AtomicBool { v: RacyCell::new(val) } + AtomicBool { v: UnsafeCell::new(val) } } /// Loads a value from the bool. @@ -348,7 +358,7 @@ impl AtomicInt { #[inline] #[stable] pub fn new(v: int) -> AtomicInt { - AtomicInt {v: RacyCell::new(v)} + AtomicInt {v: UnsafeCell::new(v)} } /// Loads a value from the int. @@ -534,7 +544,7 @@ impl AtomicUint { #[inline] #[stable] pub fn new(v: uint) -> AtomicUint { - AtomicUint { v: RacyCell::new(v) } + AtomicUint { v: UnsafeCell::new(v) } } /// Loads a value from the uint. @@ -721,7 +731,7 @@ impl AtomicPtr { #[inline] #[stable] pub fn new(p: *mut T) -> AtomicPtr { - AtomicPtr { p: RacyCell::new(p as uint) } + AtomicPtr { p: UnsafeCell::new(p as uint) } } /// Loads a value from the pointer. diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 6fc6c2a569d..b45424a5eed 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -158,7 +158,7 @@ use clone::Clone; use cmp::PartialEq; use default::Default; -use kinds::{marker, Copy, Send, Sync}; +use kinds::{marker, Copy}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{None, Some}; @@ -555,28 +555,3 @@ impl UnsafeCell { #[deprecated = "renamed to 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(pub UnsafeCell); - -impl RacyCell { - /// DOX - pub fn new(value: T) -> RacyCell { - 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 Send for RacyCell { } - -unsafe impl Sync for RacyCell { } // Oh dear diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index 618a5eebf0f..c317be85ebc 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -319,9 +319,10 @@ pub use self::TrySendError::*; use self::Flavor::*; use alloc::arc::Arc; +use core::kinds; use core::kinds::marker; use core::mem; -use core::cell::{UnsafeCell, RacyCell}; +use core::cell::UnsafeCell; pub use self::select::{Select, Handle}; use self::select::StartResult; @@ -1024,6 +1025,32 @@ impl Drop for Receiver { } } +/// A version of `UnsafeCell` intended for use in concurrent data +/// structures (for example, you might put it in an `Arc`). +pub struct RacyCell(pub UnsafeCell); + +impl RacyCell { + /// DOX + pub fn new(value: T) -> RacyCell { + 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 Send for RacyCell { } + +unsafe impl kinds::Sync for RacyCell { } // Oh dear + + #[cfg(test)] mod test { use prelude::*; diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index d2dafac281a..77c358c6259 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -10,8 +10,9 @@ use prelude::*; -use cell::{UnsafeCell, RacyCell}; -use kinds::{marker, Sync}; +use comm::RacyCell; +use cell::UnsafeCell; +use kinds::marker; use sync::{poison, AsMutexGuard}; use sys_common::mutex as sys; diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index 986f50bc8de..3b0114b3e90 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -8,8 +8,9 @@ // 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 cell::{UnsafeCell, RacyCell}; use sys::sync as ffi; use sys_common::mutex; diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 92aa5201ec3..45d5c5e0aab 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -127,7 +127,7 @@ use any::Any; use borrow::IntoCow; use boxed::Box; -use cell::RacyCell; +use comm::RacyCell; use clone::Clone; use kinds::{Send, Sync}; use ops::{Drop, FnOnce}; diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs index d7ea163cc80..3ea051b16f2 100644 --- a/src/libstd/thread_local/scoped.rs +++ b/src/libstd/thread_local/scoped.rs @@ -196,11 +196,10 @@ impl Key { #[cfg(not(any(windows, target_os = "android", target_os = "ios")))] mod imp { - use std::cell::UnsafeCell; + use std::comm::RacyCell; - // SNAP c9f6d69 switch to `Cell` #[doc(hidden)] - pub struct KeyInner { pub inner: UnsafeCell<*mut T> } + pub struct KeyInner { pub inner: RacyCell<*mut T> } unsafe impl ::kinds::Sync for KeyInner { } diff --git a/src/test/run-pass/issue-17718-static-unsafe-interior.rs b/src/test/run-pass/issue-17718-static-unsafe-interior.rs index 17dd6d69fd4..82bfdb0612a 100644 --- a/src/test/run-pass/issue-17718-static-unsafe-interior.rs +++ b/src/test/run-pass/issue-17718-static-unsafe-interior.rs @@ -9,7 +9,8 @@ // except according to those terms. use std::kinds::marker; -use std::cell::{UnsafeCell, RacyCell}; +use std::comm::RacyCell; +use std::cell::UnsafeCell; struct MyUnsafe { value: RacyCell -- cgit 1.4.1-3-g733a5 From 51d2fefd91bbbfa8572d30f9bd4374fe53514cd9 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 22 Dec 2014 14:13:24 +0100 Subject: Implement `Sync` for some windows sys types --- src/libstd/sys/windows/mutex.rs | 2 ++ src/libstd/sys/windows/pipe.rs | 6 ++++++ 2 files changed, 8 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sys/windows/mutex.rs b/src/libstd/sys/windows/mutex.rs index ddd89070ed5..3ac7c09154e 100644 --- a/src/libstd/sys/windows/mutex.rs +++ b/src/libstd/sys/windows/mutex.rs @@ -22,6 +22,8 @@ pub struct Mutex { inner: atomic::AtomicUint } pub const MUTEX_INIT: Mutex = Mutex { inner: atomic::INIT_ATOMIC_UINT }; +unsafe impl Sync for Mutex {} + #[inline] pub unsafe fn raw(m: &Mutex) -> ffi::LPCRITICAL_SECTION { m.get() diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index bf658d0efd0..11226f53e17 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -559,6 +559,8 @@ pub struct UnixListener { name: CString, } +unsafe impl Sync for UnixListener {} + impl UnixListener { pub fn bind(addr: &CString) -> IoResult { // Although we technically don't need the pipe until much later, we @@ -603,11 +605,15 @@ pub struct UnixAcceptor { deadline: u64, } +unsafe impl Sync for UnixAcceptor {} + struct AcceptorState { abort: Event, closed: atomic::AtomicBool, } +unsafe impl Sync for AcceptorState {} + impl UnixAcceptor { pub fn accept(&mut self) -> IoResult { // This function has some funky implementation details when working with -- cgit 1.4.1-3-g733a5 From 7df17a2868004597bff61348060f423ad2384e04 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 22 Dec 2014 14:25:58 +0100 Subject: Rename `UniquePtr` to `Unique` Mostly following the convention in RFC 356 --- src/liballoc/boxed.rs | 4 ++-- src/libcollections/vec.rs | 20 +++++++++--------- src/libcore/ptr.rs | 24 +++++++++++----------- src/libflate/lib.rs | 6 +++--- src/librustc/middle/mem_categorization.rs | 14 ++++++------- src/librustc_borrowck/borrowck/check_loans.rs | 12 +++++------ src/librustc_borrowck/borrowck/fragments.rs | 4 ++-- .../borrowck/gather_loans/gather_moves.rs | 2 +- .../borrowck/gather_loans/lifetime.rs | 4 ++-- .../borrowck/gather_loans/restrictions.rs | 2 +- src/librustc_typeck/check/regionck.rs | 6 +++--- src/libstd/collections/hash/table.rs | 8 ++++---- 12 files changed, 53 insertions(+), 53 deletions(-) (limited to 'src/libstd') diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs index 6825a42ef08..3c6b2d2cbc0 100644 --- a/src/liballoc/boxed.rs +++ b/src/liballoc/boxed.rs @@ -19,7 +19,7 @@ use core::hash::{mod, Hash}; use core::kinds::Sized; use core::mem; use core::option::Option; -use core::ptr::UniquePtr; +use core::ptr::Unique; use core::raw::TraitObject; use core::result::Result; use core::result::Result::{Ok, Err}; @@ -45,7 +45,7 @@ pub static HEAP: () = (); /// A type that represents a uniquely-owned value. #[lang = "owned_box"] #[unstable = "custom allocators will add an additional type parameter (with default)"] -pub struct Box(UniquePtr); +pub struct Box(Unique); #[stable] impl Default for Box { diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index e4522597b9d..d700b187e8a 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -58,7 +58,7 @@ use core::kinds::marker::{ContravariantLifetime, InvariantType}; use core::mem; use core::num::{Int, UnsignedInt}; use core::ops; -use core::ptr::{mod, UniquePtr}; +use core::ptr::{mod, Unique}; use core::raw::Slice as RawSlice; use core::uint; @@ -133,7 +133,7 @@ use slice::CloneSliceExt; #[unsafe_no_drop_flag] #[stable] pub struct Vec { - ptr: UniquePtr, + ptr: Unique, len: uint, cap: uint, } @@ -176,7 +176,7 @@ impl Vec { // non-null value which is fine since we never call deallocate on the ptr // if cap is 0. The reason for this is because the pointer of a slice // being NULL would break the null pointer optimization for enums. - Vec { ptr: UniquePtr(EMPTY as *mut T), len: 0, cap: 0 } + Vec { ptr: Unique(EMPTY as *mut T), len: 0, cap: 0 } } /// Constructs a new, empty `Vec` with the specified capacity. @@ -209,7 +209,7 @@ impl Vec { #[stable] pub fn with_capacity(capacity: uint) -> Vec { if mem::size_of::() == 0 { - Vec { ptr: UniquePtr(EMPTY as *mut T), len: 0, cap: uint::MAX } + Vec { ptr: Unique(EMPTY as *mut T), len: 0, cap: uint::MAX } } else if capacity == 0 { Vec::new() } else { @@ -217,7 +217,7 @@ impl Vec { .expect("capacity overflow"); let ptr = unsafe { allocate(size, mem::min_align_of::()) }; if ptr.is_null() { ::alloc::oom() } - Vec { ptr: UniquePtr(ptr as *mut T), len: 0, cap: capacity } + Vec { ptr: Unique(ptr as *mut T), len: 0, cap: capacity } } } @@ -284,7 +284,7 @@ impl Vec { #[unstable = "needs finalization"] pub unsafe fn from_raw_parts(ptr: *mut T, length: uint, capacity: uint) -> Vec { - Vec { ptr: UniquePtr(ptr), len: length, cap: capacity } + Vec { ptr: Unique(ptr), len: length, cap: capacity } } /// Creates a vector by copying the elements from a raw pointer. @@ -803,7 +803,7 @@ impl Vec { unsafe { // Overflow check is unnecessary as the vector is already at // least this large. - self.ptr = UniquePtr(reallocate(self.ptr.0 as *mut u8, + self.ptr = Unique(reallocate(self.ptr.0 as *mut u8, self.cap * mem::size_of::(), self.len * mem::size_of::(), mem::min_align_of::()) as *mut T); @@ -1110,7 +1110,7 @@ impl Vec { let size = max(old_size, 2 * mem::size_of::()) * 2; if old_size > size { panic!("capacity overflow") } unsafe { - self.ptr = UniquePtr(alloc_or_realloc(self.ptr.0, old_size, size)); + self.ptr = Unique(alloc_or_realloc(self.ptr.0, old_size, size)); if self.ptr.0.is_null() { ::alloc::oom() } } self.cap = max(self.cap, 2) * 2; @@ -1231,7 +1231,7 @@ impl Vec { let size = capacity.checked_mul(mem::size_of::()) .expect("capacity overflow"); unsafe { - self.ptr = UniquePtr(alloc_or_realloc(self.ptr.0, + self.ptr = Unique(alloc_or_realloc(self.ptr.0, self.cap * mem::size_of::(), size)); if self.ptr.0.is_null() { ::alloc::oom() } @@ -1420,7 +1420,7 @@ impl IntoIter { for _x in self { } let IntoIter { allocation, cap, ptr: _ptr, end: _end } = self; mem::forget(self); - Vec { ptr: UniquePtr(allocation), cap: cap, len: 0 } + Vec { ptr: Unique(allocation), cap: cap, len: 0 } } } diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 402e85b4d8b..8c9d77a0e9c 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -505,28 +505,28 @@ impl PartialOrd for *mut T { /// A wrapper around a raw `*mut T` that indicates that the possessor /// of this wrapper owns the referent. This in turn implies that the -/// `UniquePtr` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a +/// `Unique` is `Send`/`Sync` if `T` is `Send`/`Sync`, unlike a /// raw `*mut T` (which conveys no particular ownership semantics). /// Useful for building abstractions like `Vec` or `Box`, which /// internally use raw pointers to manage the memory that they own. -pub struct UniquePtr(pub *mut T); +pub struct Unique(pub *mut T); -/// `UniquePtr` pointers are `Send` if `T` is `Send` because the data they +/// `Unique` pointers are `Send` if `T` is `Send` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the -/// `UniquePtr` must enforce it. -unsafe impl Send for UniquePtr { } +/// `Unique` must enforce it. +unsafe impl Send for Unique { } -/// `UniquePtr` pointers are `Sync` if `T` is `Sync` because the data they +/// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the -/// `UniquePtr` must enforce it. -unsafe impl Sync for UniquePtr { } +/// `Unique` must enforce it. +unsafe impl Sync for Unique { } -impl UniquePtr { - /// Returns a null UniquePtr. - pub fn null() -> UniquePtr { - UniquePtr(RawPtr::null()) +impl Unique { + /// Returns a null Unique. + pub fn null() -> Unique { + Unique(RawPtr::null()) } /// Return an (unsafe) pointer into the memory owned by `self`. diff --git a/src/libflate/lib.rs b/src/libflate/lib.rs index 3326960baa8..8c4f74027a5 100644 --- a/src/libflate/lib.rs +++ b/src/libflate/lib.rs @@ -29,7 +29,7 @@ extern crate libc; use libc::{c_void, size_t, c_int}; use std::c_vec::CVec; -use std::ptr::UniquePtr; +use std::ptr::Unique; #[link(name = "miniz", kind = "static")] extern { @@ -60,7 +60,7 @@ fn deflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { &mut outsz, flags); if !res.is_null() { - let res = UniquePtr(res); + let res = Unique(res); Some(CVec::new_with_dtor(res.0 as *mut u8, outsz as uint, move|:| libc::free(res.0))) } else { None @@ -86,7 +86,7 @@ fn inflate_bytes_internal(bytes: &[u8], flags: c_int) -> Option> { &mut outsz, flags); if !res.is_null() { - let res = UniquePtr(res); + let res = Unique(res); Some(CVec::new_with_dtor(res.0 as *mut u8, outsz as uint, move|:| libc::free(res.0))) } else { None diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index ad74c8d8bda..d81894a3daf 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -113,7 +113,7 @@ pub struct Upvar { // different kinds of pointers: #[deriving(Clone, Copy, PartialEq, Eq, Hash, Show)] pub enum PointerKind { - UniquePtr, + Unique, BorrowedPtr(ty::BorrowKind, ty::Region), Implicit(ty::BorrowKind, ty::Region), // Implicit deref of a borrowed ptr. UnsafePtr(ast::Mutability) @@ -199,7 +199,7 @@ pub fn opt_deref_kind(t: Ty) -> Option { match t.sty { ty::ty_uniq(_) | ty::ty_closure(box ty::ClosureTy {store: ty::UniqTraitStore, ..}) => { - Some(deref_ptr(UniquePtr)) + Some(deref_ptr(Unique)) } ty::ty_rptr(r, mt) => { @@ -315,7 +315,7 @@ impl MutabilityCategory { pub fn from_pointer_kind(base_mutbl: MutabilityCategory, ptr: PointerKind) -> MutabilityCategory { match ptr { - UniquePtr => { + Unique => { base_mutbl.inherit() } BorrowedPtr(borrow_kind, _) | Implicit(borrow_kind, _) => { @@ -1351,7 +1351,7 @@ impl<'t,'tcx,TYPER:Typer<'tcx>> MemCategorizationContext<'t,TYPER> { Implicit(..) => { "dereference (dereference is implicit, due to indexing)".to_string() } - UniquePtr => format!("dereference of `{}`", ptr_sigil(pk)), + Unique => format!("dereference of `{}`", ptr_sigil(pk)), _ => format!("dereference of `{}`-pointer", ptr_sigil(pk)) } } @@ -1412,7 +1412,7 @@ impl<'tcx> cmt_<'tcx> { } cat_downcast(ref b, _) | cat_interior(ref b, _) | - cat_deref(ref b, _, UniquePtr) => { + cat_deref(ref b, _, Unique) => { b.guarantor() } } @@ -1431,7 +1431,7 @@ impl<'tcx> cmt_<'tcx> { cat_deref(ref b, _, BorrowedPtr(ty::UniqueImmBorrow, _)) | cat_deref(ref b, _, Implicit(ty::UniqueImmBorrow, _)) | cat_downcast(ref b, _) | - cat_deref(ref b, _, UniquePtr) | + cat_deref(ref b, _, Unique) | cat_interior(ref b, _) => { // Aliasability depends on base cmt b.freely_aliasable(ctxt) @@ -1523,7 +1523,7 @@ impl<'tcx> Repr<'tcx> for categorization<'tcx> { pub fn ptr_sigil(ptr: PointerKind) -> &'static str { match ptr { - UniquePtr => "Box", + Unique => "Box", BorrowedPtr(ty::ImmBorrow, _) | Implicit(ty::ImmBorrow, _) => "&", BorrowedPtr(ty::MutBorrow, _) | diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs index 4ae9e60299a..4ad060202ee 100644 --- a/src/librustc_borrowck/borrowck/check_loans.rs +++ b/src/librustc_borrowck/borrowck/check_loans.rs @@ -33,11 +33,11 @@ use std::rc::Rc; // FIXME (#16118): These functions are intended to allow the borrow checker to // be less precise in its handling of Box while still allowing moves out of a -// Box. They should be removed when UniquePtr is removed from LoanPath. +// Box. They should be removed when Unique is removed from LoanPath. fn owned_ptr_base_path<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> &'a LoanPath<'tcx> { - //! Returns the base of the leftmost dereference of an UniquePtr in - //! `loan_path`. If there is no dereference of an UniquePtr in `loan_path`, + //! Returns the base of the leftmost dereference of an Unique in + //! `loan_path`. If there is no dereference of an Unique in `loan_path`, //! then it just returns `loan_path` itself. return match helper(loan_path) { @@ -48,7 +48,7 @@ fn owned_ptr_base_path<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> &'a LoanPath< fn helper<'a, 'tcx>(loan_path: &'a LoanPath<'tcx>) -> Option<&'a LoanPath<'tcx>> { match loan_path.kind { LpVar(_) | LpUpvar(_) => None, - LpExtend(ref lp_base, _, LpDeref(mc::UniquePtr)) => { + LpExtend(ref lp_base, _, LpDeref(mc::Unique)) => { match helper(&**lp_base) { v @ Some(_) => v, None => Some(&**lp_base) @@ -72,7 +72,7 @@ fn owned_ptr_base_path_rc<'tcx>(loan_path: &Rc>) -> Rc(loan_path: &Rc>) -> Option>> { match loan_path.kind { LpVar(_) | LpUpvar(_) => None, - LpExtend(ref lp_base, _, LpDeref(mc::UniquePtr)) => { + LpExtend(ref lp_base, _, LpDeref(mc::Unique)) => { match helper(lp_base) { v @ Some(_) => v, None => Some(lp_base.clone()) @@ -880,7 +880,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> { } } - mc::cat_deref(b, _, mc::UniquePtr) => { + mc::cat_deref(b, _, mc::Unique) => { assert_eq!(cmt.mutbl, mc::McInherited); cmt = b; } diff --git a/src/librustc_borrowck/borrowck/fragments.rs b/src/librustc_borrowck/borrowck/fragments.rs index 5530b8f39ec..ef9130bb607 100644 --- a/src/librustc_borrowck/borrowck/fragments.rs +++ b/src/librustc_borrowck/borrowck/fragments.rs @@ -291,9 +291,9 @@ fn add_fragment_siblings<'tcx>(this: &MoveData<'tcx>, add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id); } - // *LV for UniquePtr consumes the contents of the box (at + // *LV for Unique consumes the contents of the box (at // least when it is non-copy...), so propagate inward. - LpExtend(ref loan_parent, _, LpDeref(mc::UniquePtr)) => { + LpExtend(ref loan_parent, _, LpDeref(mc::Unique)) => { add_fragment_siblings(this, tcx, gathered_fragments, loan_parent.clone(), origin_id); } diff --git a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs index 5eb16447057..ed5abda6f7c 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/gather_moves.rs @@ -190,7 +190,7 @@ fn check_and_get_illegal_move_origin<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, } } - mc::cat_deref(ref b, _, mc::UniquePtr) => { + mc::cat_deref(ref b, _, mc::Unique) => { check_and_get_illegal_move_origin(bccx, b) } } diff --git a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs index 39670314cd1..1c57097ae26 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/lifetime.rs @@ -84,7 +84,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { } mc::cat_downcast(ref base, _) | - mc::cat_deref(ref base, _, mc::UniquePtr) | // L-Deref-Send + mc::cat_deref(ref base, _, mc::Unique) | // L-Deref-Send mc::cat_interior(ref base, _) => { // L-Field self.check(base, discr_scope) } @@ -129,7 +129,7 @@ impl<'a, 'tcx> GuaranteeLifetimeContext<'a, 'tcx> { r } mc::cat_downcast(ref cmt, _) | - mc::cat_deref(ref cmt, _, mc::UniquePtr) | + mc::cat_deref(ref cmt, _, mc::Unique) | mc::cat_interior(ref cmt, _) => { self.scope(cmt) } diff --git a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs index d940b1079fc..1773e8cb233 100644 --- a/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs +++ b/src/librustc_borrowck/borrowck/gather_loans/restrictions.rs @@ -107,7 +107,7 @@ impl<'a, 'tcx> RestrictionsContext<'a, 'tcx> { mc::cat_deref(cmt_base, _, pk) => { match pk { - mc::UniquePtr => { + mc::Unique => { // R-Deref-Send-Pointer // // When we borrow the interior of an owned pointer, we diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index dda6240ad82..87fa8261575 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -1460,7 +1460,7 @@ fn link_region<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, } mc::cat_downcast(cmt_base, _) | - mc::cat_deref(cmt_base, _, mc::UniquePtr) | + mc::cat_deref(cmt_base, _, mc::Unique) | mc::cat_interior(cmt_base, _) => { // Borrowing interior or owned data requires the base // to be valid and borrowable in the same fashion. @@ -1684,7 +1684,7 @@ fn adjust_upvar_borrow_kind_for_mut<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, cmt.repr(rcx.tcx())); match cmt.cat.clone() { - mc::cat_deref(base, _, mc::UniquePtr) | + mc::cat_deref(base, _, mc::Unique) | mc::cat_interior(base, _) | mc::cat_downcast(base, _) => { // Interior or owned data is mutable if base is @@ -1731,7 +1731,7 @@ fn adjust_upvar_borrow_kind_for_unique<'a, 'tcx>(rcx: &Rcx<'a, 'tcx>, cmt: mc::c cmt.repr(rcx.tcx())); match cmt.cat.clone() { - mc::cat_deref(base, _, mc::UniquePtr) | + mc::cat_deref(base, _, mc::Unique) | mc::cat_interior(base, _) | mc::cat_downcast(base, _) => { // Interior or owned data is unique if base is diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs index 643c2b7d074..3ae3a8ffbad 100644 --- a/src/libstd/collections/hash/table.rs +++ b/src/libstd/collections/hash/table.rs @@ -23,7 +23,7 @@ use num::{Int, UnsignedInt}; use ops::{Deref, DerefMut, Drop}; use option::Option; use option::Option::{Some, None}; -use ptr::{UniquePtr, RawPtr, copy_nonoverlapping_memory, zero_memory}; +use ptr::{Unique, RawPtr, copy_nonoverlapping_memory, zero_memory}; use ptr; use rt::heap::{allocate, deallocate}; @@ -69,7 +69,7 @@ const EMPTY_BUCKET: u64 = 0u64; pub struct RawTable { capacity: uint, size: uint, - hashes: UniquePtr, + hashes: Unique, // Because K/V do not appear directly in any of the types in the struct, // inform rustc that in fact instances of K and V are reachable from here. marker: marker::CovariantType<(K,V)>, @@ -563,7 +563,7 @@ impl RawTable { return RawTable { size: 0, capacity: 0, - hashes: UniquePtr::null(), + hashes: Unique::null(), marker: marker::CovariantType, }; } @@ -602,7 +602,7 @@ impl RawTable { RawTable { capacity: capacity, size: 0, - hashes: UniquePtr(hashes), + hashes: Unique(hashes), marker: marker::CovariantType, } } -- cgit 1.4.1-3-g733a5 From 88186934960dae4f616df815eb25205c2713f503 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Mon, 22 Dec 2014 17:15:51 +0100 Subject: 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. --- src/liballoc/arc.rs | 2 +- src/libstd/comm/mod.rs | 13 ++++--------- src/libstd/sync/mutex.rs | 9 ++++----- src/libstd/sys/unix/mutex.rs | 5 ++--- src/libstd/thread.rs | 19 +++++++++++++------ src/libstd/thread_local/scoped.rs | 4 ++-- .../run-pass/issue-17718-static-unsafe-interior.rs | 21 +++++++++++---------- 7 files changed, 37 insertions(+), 36 deletions(-) (limited to 'src/libstd') diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs index 4810e15d68b..3d10628b1cb 100644 --- a/src/liballoc/arc.rs +++ b/src/liballoc/arc.rs @@ -139,7 +139,7 @@ struct ArcInner { data: T, } -impl Arc { +impl Arc { /// Constructs a new `Arc`. /// /// # Examples diff --git a/src/libstd/comm/mod.rs b/src/libstd/comm/mod.rs index c317be85ebc..269d988d1ee 100644 --- a/src/libstd/comm/mod.rs +++ b/src/libstd/comm/mod.rs @@ -1027,23 +1027,18 @@ impl Drop for Receiver { /// A version of `UnsafeCell` intended for use in concurrent data /// structures (for example, you might put it in an `Arc`). -pub struct RacyCell(pub UnsafeCell); +struct RacyCell(pub UnsafeCell); impl RacyCell { - /// DOX - pub fn new(value: T) -> RacyCell { + + fn new(value: T) -> RacyCell { 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 Send for RacyCell { } diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 77c358c6259..fbbbb3e77a4 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -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 { // time, so to ensure that the native mutex is used correctly we box the // inner lock to give it a constant address. inner: Box, - data: RacyCell, + data: UnsafeCell, } unsafe impl Send for Mutex { } @@ -101,7 +100,7 @@ unsafe impl Sync for Mutex { } /// ``` pub struct StaticMutex { lock: sys::Mutex, - poison: RacyCell, + poison: UnsafeCell, } 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 Mutex { @@ -140,7 +139,7 @@ impl Mutex { pub fn new(t: T) -> Mutex { Mutex { inner: box MUTEX_INIT, - data: RacyCell::new(t), + data: UnsafeCell::new(t), } } diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs index 3b0114b3e90..81f8659d6ae 100644 --- a/src/libstd/sys/unix/mutex.rs +++ b/src/libstd/sys/unix/mutex.rs @@ -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 } +pub struct Mutex { inner: UnsafeCell } #[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 {} diff --git a/src/libstd/thread.rs b/src/libstd/thread.rs index 45d5c5e0aab..56731bd7ec3 100644 --- a/src/libstd/thread.rs +++ b/src/libstd/thread.rs @@ -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 @@ impl Builder { } fn spawn_inner(self, f: Thunk<(), T>) -> JoinGuard { - 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 @@ impl Builder { } }; 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 @@ impl thread_info::NewThread for Thread { /// A thread that completes without panicking is considered to exit successfully. pub type Result = ::result::Result>; +struct Packet(Arc>>>); + +unsafe impl Send for Packet {} +unsafe impl Sync for Packet {} + #[must_use] /// An RAII-style guard that will block until thread termination when dropped. /// @@ -391,9 +396,11 @@ pub struct JoinGuard { native: imp::rust_thread, thread: Thread, joined: bool, - packet: Arc>>>, + packet: Packet, } +unsafe impl Sync for JoinGuard {} + impl JoinGuard { /// Extract a handle to the thread this guard will join on. pub fn thread(&self) -> &Thread { @@ -410,7 +417,7 @@ impl JoinGuard { unsafe { imp::join(self.native) }; self.joined = true; unsafe { - (*self.packet.get()).take().unwrap() + (*self.packet.0.get()).take().unwrap() } } diff --git a/src/libstd/thread_local/scoped.rs b/src/libstd/thread_local/scoped.rs index 3ea051b16f2..756c86c2115 100644 --- a/src/libstd/thread_local/scoped.rs +++ b/src/libstd/thread_local/scoped.rs @@ -196,10 +196,10 @@ impl Key { #[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 { pub inner: RacyCell<*mut T> } + pub struct KeyInner { pub inner: UnsafeCell<*mut T> } unsafe impl ::kinds::Sync for KeyInner { } diff --git a/src/test/run-pass/issue-17718-static-unsafe-interior.rs b/src/test/run-pass/issue-17718-static-unsafe-interior.rs index 82bfdb0612a..a25632b3376 100644 --- a/src/test/run-pass/issue-17718-static-unsafe-interior.rs +++ b/src/test/run-pass/issue-17718-static-unsafe-interior.rs @@ -9,29 +9,32 @@ // except according to those terms. use std::kinds::marker; -use std::comm::RacyCell; use std::cell::UnsafeCell; struct MyUnsafe { - value: RacyCell + value: UnsafeCell } impl MyUnsafe { fn forbidden(&self) {} } +impl Sync for MyUnsafe {} + enum UnsafeEnum { VariantSafe, - VariantUnsafe(RacyCell) + VariantUnsafe(UnsafeCell) } +impl Sync for UnsafeEnum {} + static STATIC1: UnsafeEnum = UnsafeEnum::VariantSafe; -static STATIC2: RacyCell = RacyCell(UnsafeCell { value: 1 }); -const CONST: RacyCell = RacyCell(UnsafeCell { value: 1 }); +static STATIC2: UnsafeCell = UnsafeCell { value: 1 }; +const CONST: UnsafeCell = UnsafeCell { value: 1 }; static STATIC3: MyUnsafe = MyUnsafe{value: CONST}; -static STATIC4: &'static RacyCell = &STATIC2; +static STATIC4: &'static UnsafeCell = &STATIC2; struct Wrap { value: T @@ -39,13 +42,11 @@ struct Wrap { unsafe impl Sync for Wrap {} -static UNSAFE: RacyCell = RacyCell(UnsafeCell{value: 1}); -static WRAPPED_UNSAFE: Wrap<&'static RacyCell> = Wrap { value: &UNSAFE }; +static UNSAFE: UnsafeCell = UnsafeCell{value: 1}; +static WRAPPED_UNSAFE: Wrap<&'static UnsafeCell> = Wrap { value: &UNSAFE }; fn main() { let a = &STATIC1; STATIC3.forbidden() } - - -- cgit 1.4.1-3-g733a5 From d35ebcb483722303d21882b369c315449457147f Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Tue, 23 Dec 2014 20:21:14 +0100 Subject: Make Barrier and Condvar Sync/Send --- src/libstd/c_vec.rs | 8 ++++---- src/libstd/sync/barrier.rs | 7 +++++++ src/libstd/sync/condvar.rs | 6 ++++++ src/libstd/sync/mutex.rs | 21 +++++++++++++-------- src/libstd/sync/rwlock.rs | 6 ++++++ 5 files changed, 36 insertions(+), 12 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs index 44e7291150e..f4338815f75 100644 --- a/src/libstd/c_vec.rs +++ b/src/libstd/c_vec.rs @@ -180,12 +180,12 @@ mod tests { fn malloc(n: uint) -> CVec { unsafe { - let mem = libc::malloc(n as libc::size_t); - if mem.is_null() { ::alloc::oom() } + let mem = ptr::Unique(libc::malloc(n as libc::size_t)); + if mem.0.is_null() { ::alloc::oom() } - CVec::new_with_dtor(mem as *mut u8, + CVec::new_with_dtor(mem.0 as *mut u8, n, - move|| { libc::free(mem as *mut libc::c_void); }) + move|| { libc::free(mem.0 as *mut libc::c_void); }) } } diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs index 6573d9273ce..6cdb199819a 100644 --- a/src/libstd/sync/barrier.rs +++ b/src/libstd/sync/barrier.rs @@ -8,6 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +use kinds::{Send, Sync}; use sync::{Mutex, Condvar}; /// A barrier enables multiple tasks to synchronize the beginning @@ -35,12 +36,18 @@ pub struct Barrier { num_threads: uint, } +unsafe impl Send for Barrier {} +unsafe impl Sync for Barrier {} + // The inner state of a double barrier struct BarrierState { count: uint, generation_id: uint, } +unsafe impl Send for BarrierState {} +unsafe impl Sync for BarrierState {} + impl Barrier { /// Create a new barrier that can block a given number of threads. /// diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index be27c06b83c..f1940bfd829 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -58,6 +58,9 @@ use time::Duration; /// ``` pub struct Condvar { inner: Box } +unsafe impl Send for Condvar {} +unsafe impl Sync for Condvar {} + /// Statically allocated condition variables. /// /// This structure is identical to `Condvar` except that it is suitable for use @@ -75,6 +78,9 @@ pub struct StaticCondvar { mutex: AtomicUint, } +unsafe impl Send for StaticCondvar {} +unsafe impl Sync for StaticCondvar {} + /// Constant initializer for a statically allocated condition variable. pub const CONDVAR_INIT: StaticCondvar = StaticCondvar { inner: sys::CONDVAR_INIT, diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index fbbbb3e77a4..4d2fbfc4055 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -284,6 +284,11 @@ mod test { use thread::Thread; use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar}; + struct Packet(Arc<(Mutex, Condvar)>); + + unsafe impl Send for Packet {} + unsafe impl Sync for Packet {} + #[test] fn smoke() { let m = Mutex::new(()); @@ -343,19 +348,19 @@ mod test { #[test] fn test_mutex_arc_condvar() { - let arc = Arc::new((Mutex::new(false), Condvar::new())); - let arc2 = arc.clone(); + let packet = Packet(Arc::new((Mutex::new(false), Condvar::new()))); + let packet2 = Packet(packet.0.clone()); let (tx, rx) = channel(); spawn(move|| { // wait until parent gets in rx.recv(); - let &(ref lock, ref cvar) = &*arc2; + let &(ref lock, ref cvar) = &*packet2.0; let mut lock = lock.lock(); *lock = true; cvar.notify_one(); }); - let &(ref lock, ref cvar) = &*arc; + let &(ref lock, ref cvar) = &*packet.0; let lock = lock.lock(); tx.send(()); assert!(!*lock); @@ -367,20 +372,20 @@ mod test { #[test] #[should_fail] fn test_arc_condvar_poison() { - let arc = Arc::new((Mutex::new(1i), Condvar::new())); - let arc2 = arc.clone(); + let packet = Packet(Arc::new((Mutex::new(1i), Condvar::new()))); + let packet2 = Packet(packet.0.clone()); let (tx, rx) = channel(); spawn(move|| { rx.recv(); - let &(ref lock, ref cvar) = &*arc2; + let &(ref lock, ref cvar) = &*packet2.0; let _g = lock.lock(); cvar.notify_one(); // Parent should fail when it wakes up. panic!(); }); - let &(ref lock, ref cvar) = &*arc; + let &(ref lock, ref cvar) = &*packet.0; let lock = lock.lock(); tx.send(()); while *lock == 1 { diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 3f177a42f44..76d05d9bfd4 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -60,6 +60,9 @@ pub struct RWLock { data: UnsafeCell, } +unsafe impl Send for RWLock {} +unsafe impl Sync for RWLock {} + /// Structure representing a statically allocated RWLock. /// /// This structure is intended to be used inside of a `static` and will provide @@ -88,6 +91,9 @@ pub struct StaticRWLock { poison: UnsafeCell, } +unsafe impl Send for StaticRWLock {} +unsafe impl Sync for StaticRWLock {} + /// Constant initialization for a statically-initialized rwlock. pub const RWLOCK_INIT: StaticRWLock = StaticRWLock { inner: sys::RWLOCK_INIT, -- cgit 1.4.1-3-g733a5 From bb315f25f84c93b69d99d41b2c68185639c30e83 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Wed, 24 Dec 2014 17:40:40 +0100 Subject: Implement RaceBox for StdinReader --- src/libstd/io/buffered.rs | 6 +++++ src/libstd/io/stdio.rs | 41 +++++++++++++++++++++------------- src/libstd/sys/common/helper_thread.rs | 9 +++++++- src/libstd/sys/windows/timer.rs | 3 +++ 4 files changed, 43 insertions(+), 16 deletions(-) (limited to 'src/libstd') diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs index 9d9e8827571..c26450310a9 100644 --- a/src/libstd/io/buffered.rs +++ b/src/libstd/io/buffered.rs @@ -22,6 +22,7 @@ use result::Result::{Ok, Err}; use slice::{SliceExt}; use slice; use vec::Vec; +use kinds::{Send,Sync}; /// Wraps a Reader and buffers input from it /// @@ -51,6 +52,11 @@ pub struct BufferedReader { cap: uint, } + +unsafe impl Send for BufferedReader {} +unsafe impl Sync for BufferedReader {} + + impl BufferedReader { /// Creates a new `BufferedReader` with the specified buffer capacity pub fn with_capacity(cap: uint, inner: R) -> BufferedReader { diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs index 1c5ceaf2450..b7da57fed27 100644 --- a/src/libstd/io/stdio.rs +++ b/src/libstd/io/stdio.rs @@ -34,7 +34,7 @@ use failure::LOCAL_STDERR; use fmt; use io::{Reader, Writer, IoResult, IoError, OtherIoError, Buffer, standard_error, EndOfFile, LineBufferedWriter, BufferedReader}; -use kinds::Send; +use kinds::{Sync, Send}; use libc; use mem; use option::Option; @@ -98,26 +98,34 @@ thread_local! { } } +struct RaceBox(BufferedReader); + +unsafe impl Send for RaceBox {} +unsafe impl Sync for RaceBox {} + /// A synchronized wrapper around a buffered reader from stdin #[deriving(Clone)] pub struct StdinReader { - inner: Arc>>, + inner: Arc>, } +unsafe impl Send for StdinReader {} +unsafe impl Sync for StdinReader {} + /// A guard for exclusive access to `StdinReader`'s internal `BufferedReader`. pub struct StdinReaderGuard<'a> { - inner: MutexGuard<'a, BufferedReader>, + inner: MutexGuard<'a, RaceBox>, } impl<'a> Deref> for StdinReaderGuard<'a> { fn deref(&self) -> &BufferedReader { - &*self.inner + &self.inner.0 } } impl<'a> DerefMut> for StdinReaderGuard<'a> { fn deref_mut(&mut self) -> &mut BufferedReader { - &mut *self.inner + &mut self.inner.0 } } @@ -147,7 +155,7 @@ impl StdinReader { /// The read is performed atomically - concurrent read calls in other /// threads will not interleave with this one. pub fn read_line(&mut self) -> IoResult { - self.inner.lock().read_line() + self.inner.lock().0.read_line() } /// Like `Buffer::read_until`. @@ -155,7 +163,7 @@ impl StdinReader { /// The read is performed atomically - concurrent read calls in other /// threads will not interleave with this one. pub fn read_until(&mut self, byte: u8) -> IoResult> { - self.inner.lock().read_until(byte) + self.inner.lock().0.read_until(byte) } /// Like `Buffer::read_char`. @@ -163,13 +171,13 @@ impl StdinReader { /// The read is performed atomically - concurrent read calls in other /// threads will not interleave with this one. pub fn read_char(&mut self) -> IoResult { - self.inner.lock().read_char() + self.inner.lock().0.read_char() } } impl Reader for StdinReader { fn read(&mut self, buf: &mut [u8]) -> IoResult { - self.inner.lock().read(buf) + self.inner.lock().0.read(buf) } // We have to manually delegate all of these because the default impls call @@ -177,23 +185,23 @@ impl Reader for StdinReader { // incur the costs of repeated locking). fn read_at_least(&mut self, min: uint, buf: &mut [u8]) -> IoResult { - self.inner.lock().read_at_least(min, buf) + self.inner.lock().0.read_at_least(min, buf) } fn push_at_least(&mut self, min: uint, len: uint, buf: &mut Vec) -> IoResult { - self.inner.lock().push_at_least(min, len, buf) + self.inner.lock().0.push_at_least(min, len, buf) } fn read_to_end(&mut self) -> IoResult> { - self.inner.lock().read_to_end() + self.inner.lock().0.read_to_end() } fn read_le_uint_n(&mut self, nbytes: uint) -> IoResult { - self.inner.lock().read_le_uint_n(nbytes) + self.inner.lock().0.read_le_uint_n(nbytes) } fn read_be_uint_n(&mut self, nbytes: uint) -> IoResult { - self.inner.lock().read_be_uint_n(nbytes) + self.inner.lock().0.read_be_uint_n(nbytes) } } @@ -221,7 +229,7 @@ pub fn stdin() -> StdinReader { BufferedReader::new(stdin_raw()) }; let stdin = StdinReader { - inner: Arc::new(Mutex::new(stdin)) + inner: Arc::new(Mutex::new(RaceBox(stdin))) }; STDIN = mem::transmute(box stdin); @@ -426,6 +434,9 @@ pub struct StdWriter { inner: StdSource } +unsafe impl Send for StdWriter {} +unsafe impl Sync for StdWriter {} + impl StdWriter { /// Gets the size of this output window, if possible. This is typically used /// when the writer is attached to something like a terminal, this is used diff --git a/src/libstd/sys/common/helper_thread.rs b/src/libstd/sys/common/helper_thread.rs index b0137bdad06..a629f035b07 100644 --- a/src/libstd/sys/common/helper_thread.rs +++ b/src/libstd/sys/common/helper_thread.rs @@ -63,6 +63,11 @@ unsafe impl Send for Helper { } unsafe impl Sync for Helper { } +struct RaceBox(helper_signal::signal); + +unsafe impl Send for RaceBox {} +unsafe impl Sync for RaceBox {} + impl Helper { /// Lazily boots a helper thread, becoming a no-op if the helper has already /// been spawned. @@ -85,9 +90,11 @@ impl Helper { let (receive, send) = helper_signal::new(); *self.signal.get() = send as uint; + let receive = RaceBox(receive); + let t = f(); Thread::spawn(move |:| { - helper(receive, rx, t); + helper(receive.0, rx, t); let _g = self.lock.lock(); *self.shutdown.get() = true; self.cond.notify_one() diff --git a/src/libstd/sys/windows/timer.rs b/src/libstd/sys/windows/timer.rs index 7e4dd768aa9..874838950cd 100644 --- a/src/libstd/sys/windows/timer.rs +++ b/src/libstd/sys/windows/timer.rs @@ -48,6 +48,9 @@ pub enum Req { RemoveTimer(libc::HANDLE, Sender<()>), } +unsafe impl Send for Req {} + + fn helper(input: libc::HANDLE, messages: Receiver, _: ()) { let mut objs = vec![input]; let mut chans = vec![]; -- cgit 1.4.1-3-g733a5 From f5d619caf9f32458680fae55526b99582ca682dd Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Fri, 26 Dec 2014 23:01:47 +0100 Subject: Implement Sync/Send for windows TCP types --- src/libstd/sys/windows/tcp.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sys/windows/tcp.rs b/src/libstd/sys/windows/tcp.rs index 505e6137bf9..513c1d38e36 100644 --- a/src/libstd/sys/windows/tcp.rs +++ b/src/libstd/sys/windows/tcp.rs @@ -24,6 +24,9 @@ pub use sys_common::net::TcpStream; pub struct Event(c::WSAEVENT); +unsafe impl Send for Event {} +unsafe impl Sync for Event {} + impl Event { pub fn new() -> IoResult { let event = unsafe { c::WSACreateEvent() }; @@ -49,6 +52,9 @@ impl Drop for Event { pub struct TcpListener { sock: sock_t } +unsafe impl Send for TcpListener {} +unsafe impl Sync for TcpListener {} + impl TcpListener { pub fn bind(addr: ip::SocketAddr) -> IoResult { sys::init_net(); @@ -109,6 +115,9 @@ pub struct TcpAcceptor { deadline: u64, } +unsafe impl Send for TcpAcceptor {} +unsafe impl Sync for TcpAcceptor {} + struct AcceptorInner { listener: TcpListener, abort: Event, @@ -116,6 +125,9 @@ struct AcceptorInner { closed: atomic::AtomicBool, } +unsafe impl Send for AcceptorInner {} +unsafe impl Sync for AcceptorInner {} + impl TcpAcceptor { pub fn socket(&self) -> sock_t { self.inner.listener.socket() } -- cgit 1.4.1-3-g733a5 From 11f71ec7016952744f999dd6e668825490b1855f Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sat, 27 Dec 2014 11:02:47 +0100 Subject: Implement Sync/Send for windows' UnixStream --- src/libstd/sys/windows/pipe.rs | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 11226f53e17..fc3640f2604 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -214,6 +214,9 @@ pub struct UnixStream { write_deadline: u64, } +unsafe impl Send for UnixStream {} +unsafe impl Sync for UnixStream {} + impl UnixStream { fn try_connect(p: *const u16) -> Option { // Note that most of this is lifted from the libuv implementation. @@ -559,6 +562,7 @@ pub struct UnixListener { name: CString, } +unsafe impl Send for UnixListener {} unsafe impl Sync for UnixListener {} impl UnixListener { @@ -605,6 +609,7 @@ pub struct UnixAcceptor { deadline: u64, } +unsafe impl Send for UnixAcceptor {} unsafe impl Sync for UnixAcceptor {} struct AcceptorState { @@ -612,6 +617,7 @@ struct AcceptorState { closed: atomic::AtomicBool, } +unsafe impl Send for AcceptorState {} unsafe impl Sync for AcceptorState {} impl UnixAcceptor { -- cgit 1.4.1-3-g733a5 From 1a73ccc8db0a10e82632808e058645f2d6fa0095 Mon Sep 17 00:00:00 2001 From: Flavio Percoco Date: Sat, 27 Dec 2014 13:00:20 +0100 Subject: Make trait's impls consistent for unix/windows --- src/libstd/sys/unix/pipe.rs | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src/libstd') diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs index c4aec82894f..f1b078b4e80 100644 --- a/src/libstd/sys/unix/pipe.rs +++ b/src/libstd/sys/unix/pipe.rs @@ -117,6 +117,9 @@ pub struct UnixStream { write_deadline: u64, } +unsafe impl Send for UnixStream {} +unsafe impl Sync for UnixStream {} + impl UnixStream { pub fn connect(addr: &CString, timeout: Option) -> IoResult { @@ -215,6 +218,7 @@ pub struct UnixListener { path: CString, } +unsafe impl Send for UnixListener {} unsafe impl Sync for UnixListener {} impl UnixListener { @@ -261,6 +265,7 @@ struct AcceptorInner { closed: atomic::AtomicBool, } +unsafe impl Send for AcceptorInner {} unsafe impl Sync for AcceptorInner {} impl UnixAcceptor { -- cgit 1.4.1-3-g733a5