diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 03d9030b025..182344452a4 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -110,6 +110,7 @@ #![feature(slicing_syntax, unboxed_closures)] #![feature(box_syntax)] #![feature(old_impl_check)] +#![feature(optin_builtin_traits)] #![allow(unknown_features)] #![feature(int_uint)] // Don't link to std. We are std. diff --git a/src/libstd/sync/mpsc/blocking.rs b/src/libstd/sync/mpsc/blocking.rs index f174771a3e0..17e690e9540 100644 --- a/src/libstd/sync/mpsc/blocking.rs +++ b/src/libstd/sync/mpsc/blocking.rs @@ -14,6 +14,7 @@ use thread::Thread; use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering}; use sync::Arc; use marker::{Sync, Send}; +#[cfg(stage0)] // NOTE remove use after next snapshot use marker::{NoSend, NoSync}; use mem; use clone::Clone; @@ -31,12 +32,25 @@ pub struct SignalToken { inner: Arc, } +#[cfg(stage0)] // NOTE remove impl after next snapshot pub struct WaitToken { inner: Arc, no_send: NoSend, no_sync: NoSync, } +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +pub struct WaitToken { + inner: Arc, +} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl !Send for WaitToken {} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl !Sync for WaitToken {} + +#[cfg(stage0)] // NOTE remove impl after next snapshot pub fn tokens() -> (WaitToken, SignalToken) { let inner = Arc::new(Inner { thread: Thread::current(), @@ -53,6 +67,21 @@ pub fn tokens() -> (WaitToken, SignalToken) { (wait_token, signal_token) } +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +pub fn tokens() -> (WaitToken, SignalToken) { + let inner = Arc::new(Inner { + thread: Thread::current(), + woken: ATOMIC_BOOL_INIT, + }); + let wait_token = WaitToken { + inner: inner.clone(), + }; + let signal_token = SignalToken { + inner: inner + }; + (wait_token, signal_token) +} + impl SignalToken { pub fn signal(&self) -> bool { let wake = !self.inner.woken.compare_and_swap(false, true, Ordering::SeqCst); diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index eca7d3155b1..0ba19b70617 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -370,12 +370,24 @@ 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. #[stable] +#[cfg(stage0)] // NOTE remove impl after next snapshot pub struct SyncSender { inner: Arc>>, // can't share in an arc _marker: marker::NoSync, } +/// 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. +#[stable] +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +pub struct SyncSender { + inner: Arc>>, +} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl !marker::Sync for SyncSender {} + /// An error returned from the `send` function on channels. /// /// A `send` operation can only fail if the receiving end of a channel is @@ -677,10 +689,16 @@ impl Drop for Sender { //////////////////////////////////////////////////////////////////////////////// impl SyncSender { + #[cfg(stage0)] // NOTE remove impl after next snapshot fn new(inner: Arc>>) -> SyncSender { SyncSender { inner: inner, _marker: marker::NoSync } } + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + fn new(inner: Arc>>) -> SyncSender { + SyncSender { inner: inner } + } + /// Sends a value on this synchronous channel. /// /// This function will *block* until space in the internal buffer becomes diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index 0da458a51f1..62a7b823ec8 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -66,6 +66,7 @@ use sync::mpsc::blocking::{self, SignalToken}; /// The "receiver set" of the select interface. This structure is used to manage /// a set of receivers which are being selected over. +#[cfg(stage0)] // NOTE remove impl after next snapshot pub struct Select { head: *mut Handle<'static, ()>, tail: *mut Handle<'static, ()>, @@ -73,6 +74,18 @@ pub struct Select { marker1: marker::NoSend, } +/// The "receiver set" of the select interface. This structure is used to manage +/// a set of receivers which are being selected over. +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +pub struct Select { + head: *mut Handle<'static, ()>, + tail: *mut Handle<'static, ()>, + next_id: Cell, +} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl !marker::Send for Select {} + /// A handle to a receiver which is currently a member of a `Select` set of /// receivers. This handle is used to keep the receiver in the set as well as /// interact with the underlying receiver. @@ -113,6 +126,7 @@ impl Select { /// /// Usage of this struct directly can sometimes be burdensome, and usage is /// rather much easier through the `select!` macro. + #[cfg(stage0)] // NOTE remove impl after next snapshot pub fn new() -> Select { Select { marker1: marker::NoSend, @@ -122,6 +136,20 @@ impl Select { } } + /// Creates a new selection structure. This set is initially empty and + /// `wait` will panic!() if called. + /// + /// Usage of this struct directly can sometimes be burdensome, and usage is + /// rather much easier through the `select!` macro. + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + pub fn new() -> Select { + Select { + head: 0 as *mut Handle<'static, ()>, + tail: 0 as *mut Handle<'static, ()>, + next_id: Cell::new(1), + } + } + /// Creates a new handle into this receiver set for a new receiver. Note /// that this does *not* add the receiver to the receiver set, for that you /// must call the `add` method on the handle itself. diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index c1b55c6ff78..73d5332d16f 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -160,6 +160,7 @@ unsafe impl Sync for StaticMutex {} /// Deref and DerefMut implementations #[must_use] #[stable] +#[cfg(stage0)] // NOTE remove impl after next snapshot pub struct MutexGuard<'a, T: 'a> { // funny underscores due to how Deref/DerefMut currently work (they // disregard field privacy). @@ -169,6 +170,25 @@ pub struct MutexGuard<'a, T: 'a> { __marker: marker::NoSend, } +/// An RAII implementation of a "scoped lock" of a mutex. When this structure is +/// dropped (falls out of scope), the lock will be unlocked. +/// +/// The data protected by the mutex can be access through this guard via its +/// Deref and DerefMut implementations +#[must_use] +#[stable] +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +pub struct MutexGuard<'a, T: 'a> { + // funny underscores due to how Deref/DerefMut currently work (they + // disregard field privacy). + __lock: &'a StaticMutex, + __data: &'a UnsafeCell, + __poison: poison::Guard, +} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl<'a, T> !marker::Send for MutexGuard<'a, T> {} + /// Static initialization of a mutex. This constant can be used to initialize /// other mutex constants. #[unstable = "may be merged with Mutex in the future"] @@ -279,6 +299,7 @@ impl StaticMutex { } impl<'mutex, T> MutexGuard<'mutex, T> { + #[cfg(stage0)] // NOTE remove afte next snapshot fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell) -> LockResult> { poison::map_result(lock.poison.borrow(), |guard| { @@ -290,6 +311,18 @@ impl<'mutex, T> MutexGuard<'mutex, T> { } }) } + + #[cfg(not(stage0))] // NOTE remove cfg afte next snapshot + fn new(lock: &'mutex StaticMutex, data: &'mutex UnsafeCell) + -> LockResult> { + poison::map_result(lock.poison.borrow(), |guard| { + MutexGuard { + __lock: lock, + __data: data, + __poison: guard, + } + }) + } } #[stable] diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 7db2111cc46..237f6d08a95 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -110,23 +110,52 @@ pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock { /// dropped. #[must_use] #[stable] +#[cfg(stage0)] // NOTE remove impl after next snapshot pub struct RwLockReadGuard<'a, T: 'a> { __lock: &'a StaticRwLock, __data: &'a UnsafeCell, __marker: marker::NoSend, } +/// RAII structure used to release the shared read access of a lock when +/// dropped. +#[must_use] +#[stable] +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +pub struct RwLockReadGuard<'a, T: 'a> { + __lock: &'a StaticRwLock, + __data: &'a UnsafeCell, +} + +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl<'a, T> !marker::Send for RwLockReadGuard<'a, T> {} + +/// RAII structure used to release the exclusive write access of a lock when +/// dropped. +#[must_use] +#[stable] +#[cfg(stage0)] // NOTE remove impl after next snapshot +pub struct RwLockWriteGuard<'a, T: 'a> { + __lock: &'a StaticRwLock, + __data: &'a UnsafeCell, + __poison: poison::Guard, + __marker: marker::NoSend, +} + /// RAII structure used to release the exclusive write access of a lock when /// dropped. #[must_use] #[stable] +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot pub struct RwLockWriteGuard<'a, T: 'a> { __lock: &'a StaticRwLock, __data: &'a UnsafeCell, __poison: poison::Guard, - __marker: marker::NoSend, } +#[cfg(not(stage0))] // NOTE remove cfg after next snapshot +impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {} + impl RwLock { /// Creates a new instance of an RwLock which is unlocked and read to go. #[stable] @@ -303,6 +332,7 @@ impl StaticRwLock { } impl<'rwlock, T> RwLockReadGuard<'rwlock, T> { + #[cfg(stage0)] // NOTE remove impl after next snapshot fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell) -> LockResult> { poison::map_result(lock.poison.borrow(), |_| { @@ -313,8 +343,20 @@ impl<'rwlock, T> RwLockReadGuard<'rwlock, T> { } }) } + + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell) + -> LockResult> { + poison::map_result(lock.poison.borrow(), |_| { + RwLockReadGuard { + __lock: lock, + __data: data, + } + }) + } } impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> { + #[cfg(stage0)] // NOTE remove impl after next snapshot fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell) -> LockResult> { poison::map_result(lock.poison.borrow(), |guard| { @@ -326,6 +368,18 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> { } }) } + + #[cfg(not(stage0))] // NOTE remove cfg after next snapshot + fn new(lock: &'rwlock StaticRwLock, data: &'rwlock UnsafeCell) + -> LockResult> { + poison::map_result(lock.poison.borrow(), |guard| { + RwLockWriteGuard { + __lock: lock, + __data: data, + __poison: guard, + } + }) + } } #[stable]