diff options
| author | bors <bors@rust-lang.org> | 2015-01-28 03:59:14 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2015-01-28 03:59:14 +0000 |
| commit | a530cc9706324ad44dba464d541a807eb5afdb08 (patch) | |
| tree | a8f9e5444cf2378b9c3d5a193484a3f6c9873a06 /src/libstd/sync | |
| parent | 92ff8ea52816982ad4cbfac8168e216d32d74c77 (diff) | |
| parent | 71223050538939ed758fcd3b9114f71abff20bb2 (diff) | |
| download | rust-a530cc9706324ad44dba464d541a807eb5afdb08.tar.gz rust-a530cc9706324ad44dba464d541a807eb5afdb08.zip | |
Auto merge of #21248 - brson:feature-staging, r=alexcrichton
This implements the remaining bits of 'feature staging', as described in [RFC 507](https://github.com/rust-lang/rfcs/blob/master/text/0507-release-channels.md).
This is not quite done, but the substance of the work is complete so submitting for early review.
Key changes:
* `unstable`, `stable` and `deprecated` attributes all require 'feature' and 'since', and support an optional 'reason'.
* The `unstable` lint is removed.
* A new 'stability checking' pass warns when a used unstable library feature has not been activated with the `feature` attribute. At 1.0 beta this will become an error.
* A new 'unused feature checking' pass emits a lint ('unused_feature', renamed from 'unknown_feature') for any features that were activated but not used.
* A new tidy script `featureck.py` performs some global sanity checking, particularly that 'since' numbers agree, and also prints out a summary of features.
Differences from RFC:
* As implemented `unstable` requires a `since` attribute. I do not know if this is useful. I included it in the original sed script and just left it.
* RFC didn't specify the name of the optional 'reason' attribute.
* This continues to use 'unstable', 'stable' and 'deprecated' names (the 'nice' names) instead of 'staged_unstable', but only activates them with the crate-level 'staged_api' attribute.
I intend to update the RFC based on the outcome of this PR.
Issues:
* The unused feature check doesn't account for language features - i.e. you can activate a language feature, not use it, and not get the error.
Open questions:
* All unstable and deprecated features are named 'unnamed_feature', which i picked just because it is uniquely greppable. This is the 'catch-all' feature. What should it be?
* All stable features are named 'grandfathered'. What should this be?
TODO:
* Add check that all `deprecated` attributes are paired with a `stable` attribute in order to preserve the knowledge about when a feature became stable.
* Update rustdoc in various ways.
* Remove obsolete stability discussion from reference.
* Add features for 'path', 'io', 'os', 'hash' and 'rand'.
cc #20445 @alexcrichton @aturon
Diffstat (limited to 'src/libstd/sync')
| -rw-r--r-- | src/libstd/sync/barrier.rs | 8 | ||||
| -rw-r--r-- | src/libstd/sync/condvar.rs | 40 | ||||
| -rw-r--r-- | src/libstd/sync/future.rs | 7 | ||||
| -rw-r--r-- | src/libstd/sync/mod.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sync/mpsc/mod.rs | 66 | ||||
| -rw-r--r-- | src/libstd/sync/mpsc/mpsc_queue.rs | 4 | ||||
| -rw-r--r-- | src/libstd/sync/mpsc/select.rs | 13 | ||||
| -rw-r--r-- | src/libstd/sync/mpsc/spsc_queue.rs | 2 | ||||
| -rw-r--r-- | src/libstd/sync/mutex.rs | 33 | ||||
| -rw-r--r-- | src/libstd/sync/once.rs | 6 | ||||
| -rw-r--r-- | src/libstd/sync/poison.rs | 29 | ||||
| -rw-r--r-- | src/libstd/sync/rwlock.rs | 49 | ||||
| -rw-r--r-- | src/libstd/sync/semaphore.rs | 7 | ||||
| -rw-r--r-- | src/libstd/sync/task_pool.rs | 9 |
14 files changed, 150 insertions, 125 deletions
diff --git a/src/libstd/sync/barrier.rs b/src/libstd/sync/barrier.rs index 70939879400..40710d627c0 100644 --- a/src/libstd/sync/barrier.rs +++ b/src/libstd/sync/barrier.rs @@ -29,7 +29,7 @@ use sync::{Mutex, Condvar}; /// }); /// } /// ``` -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Barrier { lock: Mutex<BarrierState>, cvar: Condvar, @@ -54,7 +54,7 @@ impl Barrier { /// /// A barrier will block `n`-1 threads which call `wait` and then wake up /// all threads at once when the `n`th thread calls `wait`. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(n: uint) -> Barrier { Barrier { lock: Mutex::new(BarrierState { @@ -75,7 +75,7 @@ impl Barrier { /// returns `true` from `is_leader` when returning from this function, and /// all other threads will receive a result that will return `false` from /// `is_leader` - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn wait(&self) -> BarrierWaitResult { let mut lock = self.lock.lock().unwrap(); let local_gen = lock.generation_id; @@ -102,7 +102,7 @@ impl BarrierWaitResult { /// /// Only one thread will have `true` returned from their result, all other /// threads will have `false` returned. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn is_leader(&self) -> bool { self.0 } } diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index d2d5335078e..a7a5b084582 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -58,7 +58,7 @@ use sync::{mutex, MutexGuard}; /// started = cvar.wait(started).unwrap(); /// } /// ``` -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Condvar { inner: Box<StaticCondvar> } unsafe impl Send for Condvar {} @@ -76,7 +76,8 @@ unsafe impl Sync for Condvar {} /// /// static CVAR: StaticCondvar = CONDVAR_INIT; /// ``` -#[unstable = "may be merged with Condvar in the future"] +#[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub struct StaticCondvar { inner: sys::Condvar, mutex: AtomicUsize, @@ -86,7 +87,8 @@ unsafe impl Send for StaticCondvar {} unsafe impl Sync for StaticCondvar {} /// Constant initializer for a statically allocated condition variable. -#[unstable = "may be merged with Condvar in the future"] +#[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub const CONDVAR_INIT: StaticCondvar = StaticCondvar { inner: sys::CONDVAR_INIT, mutex: ATOMIC_USIZE_INIT, @@ -95,7 +97,7 @@ pub const CONDVAR_INIT: StaticCondvar = StaticCondvar { impl Condvar { /// Creates a new condition variable which is ready to be waited on and /// notified. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new() -> Condvar { Condvar { inner: box StaticCondvar { @@ -131,7 +133,7 @@ impl Condvar { /// over time. Each condition variable is dynamically bound to exactly one /// mutex to ensure defined behavior across platforms. If this functionality /// is not desired, then unsafe primitives in `sys` are provided. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> { unsafe { @@ -154,7 +156,7 @@ impl Condvar { /// /// Like `wait`, the lock specified will be re-acquired when this function /// returns, regardless of whether the timeout elapsed or not. - #[unstable] + #[unstable(feature = "std_misc")] pub fn wait_timeout<'a, T>(&self, guard: MutexGuard<'a, T>, dur: Duration) -> LockResult<(MutexGuard<'a, T>, bool)> { unsafe { @@ -169,7 +171,7 @@ impl Condvar { /// The semantics of this function are equivalent to `wait_timeout` except /// that the implementation will repeatedly wait while the duration has not /// passed and the provided function returns `false`. - #[unstable] + #[unstable(feature = "std_misc")] pub fn wait_timeout_with<'a, T, F>(&self, guard: MutexGuard<'a, T>, dur: Duration, @@ -189,7 +191,7 @@ impl Condvar { /// `notify_one` are not buffered in any way. /// /// To wake up all threads, see `notify_all()`. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn notify_one(&self) { unsafe { self.inner.inner.notify_one() } } /// Wake up all blocked threads on this condvar. @@ -199,11 +201,11 @@ impl Condvar { /// way. /// /// To wake up only one thread, see `notify_one()`. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn notify_all(&self) { unsafe { self.inner.inner.notify_all() } } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl Drop for Condvar { fn drop(&mut self) { unsafe { self.inner.inner.destroy() } @@ -215,7 +217,8 @@ impl StaticCondvar { /// notification. /// /// See `Condvar::wait`. - #[unstable = "may be merged with Condvar in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub fn wait<'a, T>(&'static self, guard: MutexGuard<'a, T>) -> LockResult<MutexGuard<'a, T>> { let poisoned = unsafe { @@ -235,7 +238,8 @@ impl StaticCondvar { /// specified duration. /// /// See `Condvar::wait_timeout`. - #[unstable = "may be merged with Condvar in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub fn wait_timeout<'a, T>(&'static self, guard: MutexGuard<'a, T>, dur: Duration) -> LockResult<(MutexGuard<'a, T>, bool)> { let (poisoned, success) = unsafe { @@ -258,7 +262,8 @@ impl StaticCondvar { /// passed and the function returns `false`. /// /// See `Condvar::wait_timeout_with`. - #[unstable = "may be merged with Condvar in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub fn wait_timeout_with<'a, T, F>(&'static self, guard: MutexGuard<'a, T>, dur: Duration, @@ -298,13 +303,15 @@ impl StaticCondvar { /// Wake up one blocked thread on this condvar. /// /// See `Condvar::notify_one`. - #[unstable = "may be merged with Condvar in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub fn notify_one(&'static self) { unsafe { self.inner.notify_one() } } /// Wake up all blocked threads on this condvar. /// /// See `Condvar::notify_all`. - #[unstable = "may be merged with Condvar in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub fn notify_all(&'static self) { unsafe { self.inner.notify_all() } } /// Deallocate all resources associated with this static condvar. @@ -313,7 +320,8 @@ impl StaticCondvar { /// active users of the condvar, and this also doesn't prevent any future /// users of the condvar. This method is required to be called to not leak /// memory on all platforms. - #[unstable = "may be merged with Condvar in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Condvar in the future")] pub unsafe fn destroy(&'static self) { self.inner.destroy() } diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs index 36bbc5ff5b4..a79fb684f47 100644 --- a/src/libstd/sync/future.rs +++ b/src/libstd/sync/future.rs @@ -27,9 +27,10 @@ //! ``` #![allow(missing_docs)] -#![unstable = "futures as-is have yet to be deeply reevaluated with recent \ - core changes to Rust's synchronization story, and will likely \ - become stable in the future but are unstable until that time"] +#![unstable(feature = "std_misc", + reason = "futures as-is have yet to be deeply reevaluated with recent \ + core changes to Rust's synchronization story, and will likely \ + become stable in the future but are unstable until that time")] use core::prelude::*; use core::mem::replace; diff --git a/src/libstd/sync/mod.rs b/src/libstd/sync/mod.rs index 6fff6765bd3..f3b721438d8 100644 --- a/src/libstd/sync/mod.rs +++ b/src/libstd/sync/mod.rs @@ -15,7 +15,7 @@ //! and/or blocking at all, but rather provide the necessary tools to build //! other types of concurrent primitives. -#![stable] +#![stable(feature = "rust1", since = "1.0.0")] pub use alloc::arc::{Arc, Weak}; pub use core::atomic; diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs index 6140e3fd36c..322c6137984 100644 --- a/src/libstd/sync/mpsc/mod.rs +++ b/src/libstd/sync/mpsc/mod.rs @@ -163,7 +163,7 @@ //! } //! ``` -#![stable] +#![stable(feature = "rust1", since = "1.0.0")] // A description of how Rust's channel implementation works // @@ -338,7 +338,7 @@ mod spsc_queue; /// The receiving-half of Rust's channel type. This half can only be owned by /// one task -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Receiver<T> { inner: UnsafeCell<Flavor<T>>, } @@ -350,14 +350,14 @@ unsafe impl<T:Send> Send for Receiver<T> { } /// 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. -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Iter<'a, T:'a> { rx: &'a Receiver<T> } /// The sending-half of Rust's asynchronous channel type. This half can only be /// owned by one task, but it can be cloned to send to other tasks. -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Sender<T> { inner: UnsafeCell<Flavor<T>>, } @@ -368,7 +368,7 @@ unsafe impl<T:Send> Send for Sender<T> { } /// 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] +#[stable(feature = "rust1", since = "1.0.0")] pub struct SyncSender<T> { inner: Arc<UnsafeCell<sync::Packet<T>>>, } @@ -383,7 +383,7 @@ impl<T> !Sync for SyncSender<T> {} /// disconnected, implying that the data could never be received. The error /// contains the data being sent as a payload so it can be recovered. #[derive(PartialEq, Eq)] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct SendError<T>(pub T); /// An error returned from the `recv` function on a `Receiver`. @@ -391,29 +391,29 @@ pub struct SendError<T>(pub T); /// The `recv` operation can only fail if the sending half of a channel is /// disconnected, implying that no further messages will ever be received. #[derive(PartialEq, Eq, Clone, Copy, Show)] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct RecvError; /// This enumeration is the list of the possible reasons that try_recv could not /// return data when called. #[derive(PartialEq, Clone, Copy, Show)] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub enum TryRecvError { /// This channel is currently empty, but the sender(s) have not yet /// disconnected, so data may yet become available. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] Empty, /// This channel's sending half has become disconnected, and there will /// never be any more data received on this channel - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] Disconnected, } /// This enumeration is the list of the possible error outcomes for the /// `SyncSender::try_send` method. #[derive(PartialEq, Clone)] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub enum TrySendError<T> { /// The data could not be sent on the channel because it would require that /// the callee block to send the data. @@ -421,12 +421,12 @@ pub enum TrySendError<T> { /// If this is a buffered channel, then the buffer is full at this time. If /// this is not a buffered channel, then there is no receiver available to /// acquire the data. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] Full(T), /// This channel's receiving half has disconnected, so the data could not be /// sent. The data is returned back to the callee in this case. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] Disconnected(T), } @@ -484,7 +484,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> { /// // Let's see what that answer was /// println!("{:?}", rx.recv().unwrap()); /// ``` -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) { let a = Arc::new(UnsafeCell::new(oneshot::Packet::new())); (Sender::new(Flavor::Oneshot(a.clone())), Receiver::new(Flavor::Oneshot(a))) @@ -524,7 +524,7 @@ pub fn channel<T: Send>() -> (Sender<T>, Receiver<T>) { /// assert_eq!(rx.recv().unwrap(), 1i); /// assert_eq!(rx.recv().unwrap(), 2i); /// ``` -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub fn sync_channel<T: Send>(bound: uint) -> (SyncSender<T>, Receiver<T>) { let a = Arc::new(UnsafeCell::new(sync::Packet::new(bound))); (SyncSender::new(a.clone()), Receiver::new(Flavor::Sync(a))) @@ -568,7 +568,7 @@ impl<T: Send> Sender<T> { /// drop(rx); /// assert_eq!(tx.send(1i).err().unwrap().0, 1); /// ``` - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn send(&self, t: T) -> Result<(), SendError<T>> { let (new_inner, ret) = match *unsafe { self.inner() } { Flavor::Oneshot(ref p) => { @@ -615,7 +615,7 @@ impl<T: Send> Sender<T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> Clone for Sender<T> { fn clone(&self) -> Sender<T> { let (packet, sleeper, guard) = match *unsafe { self.inner() } { @@ -661,7 +661,7 @@ impl<T: Send> Clone for Sender<T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> Drop for Sender<T> { fn drop(&mut self) { match *unsafe { self.inner_mut() } { @@ -696,7 +696,7 @@ impl<T: Send> SyncSender<T> { /// This function will never panic, but it may return `Err` if the /// `Receiver` has disconnected and is no longer able to receive /// information. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn send(&self, t: T) -> Result<(), SendError<T>> { unsafe { (*self.inner.get()).send(t).map_err(SendError) } } @@ -710,13 +710,13 @@ impl<T: Send> SyncSender<T> { /// /// See `SyncSender::send` for notes about guarantees of whether the /// receiver has received the data or not if this function is successful. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn try_send(&self, t: T) -> Result<(), TrySendError<T>> { unsafe { (*self.inner.get()).try_send(t) } } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> Clone for SyncSender<T> { fn clone(&self) -> SyncSender<T> { unsafe { (*self.inner.get()).clone_chan(); } @@ -725,7 +725,7 @@ impl<T: Send> Clone for SyncSender<T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> Drop for SyncSender<T> { fn drop(&mut self) { unsafe { (*self.inner.get()).drop_chan(); } @@ -749,7 +749,7 @@ impl<T: Send> Receiver<T> { /// /// This is useful for a flavor of "optimistic check" before deciding to /// block on a receiver. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn try_recv(&self) -> Result<T, TryRecvError> { loop { let new_port = match *unsafe { self.inner() } { @@ -810,7 +810,7 @@ impl<T: Send> Receiver<T> { /// If the corresponding `Sender` has disconnected, or it disconnects while /// this call is blocking, this call will wake up and return `Err` to /// indicate that no more messages can ever be received on this channel. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn recv(&self) -> Result<T, RecvError> { loop { let new_port = match *unsafe { self.inner() } { @@ -849,7 +849,7 @@ impl<T: Send> Receiver<T> { /// Returns an iterator that will block waiting for messages, but never /// `panic!`. It will return `None` when the channel has hung up. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn iter(&self) -> Iter<T> { Iter { rx: self } } @@ -941,7 +941,7 @@ impl<T: Send> select::Packet for Receiver<T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T: Send> Iterator for Iter<'a, T> { type Item = T; @@ -949,7 +949,7 @@ impl<'a, T: Send> Iterator for Iter<'a, T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> Drop for Receiver<T> { fn drop(&mut self) { match *unsafe { self.inner_mut() } { @@ -961,21 +961,21 @@ impl<T: Send> Drop for Receiver<T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Debug for SendError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "SendError(..)".fmt(f) } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Display for SendError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "sending on a closed channel".fmt(f) } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Debug for TrySendError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -985,7 +985,7 @@ impl<T> fmt::Debug for TrySendError<T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Display for TrySendError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -999,14 +999,14 @@ impl<T> fmt::Display for TrySendError<T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for RecvError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "receiving on a closed channel".fmt(f) } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl fmt::Display for TryRecvError { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs index ea81ed30a9c..c222c313ba6 100644 --- a/src/libstd/sync/mpsc/mpsc_queue.rs +++ b/src/libstd/sync/mpsc/mpsc_queue.rs @@ -35,7 +35,7 @@ //! method, and see the method for more information about it. Due to this //! caveat, this queue may not be appropriate for all use-cases. -#![unstable] +#![unstable(feature = "std_misc")] // http://www.1024cores.net/home/lock-free-algorithms // /queues/non-intrusive-mpsc-node-based-queue @@ -139,7 +139,7 @@ impl<T: Send> Queue<T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> Drop for Queue<T> { fn drop(&mut self) { unsafe { diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs index f5bacbb8ce2..e97c82a5b1b 100644 --- a/src/libstd/sync/mpsc/select.rs +++ b/src/libstd/sync/mpsc/select.rs @@ -46,12 +46,13 @@ //! ``` #![allow(dead_code)] -#![unstable = "This implementation, while likely sufficient, is unsafe and \ - likely to be error prone. At some point in the future this \ - module will likely be replaced, and it is currently \ - unknown how much API breakage that will cause. The ability \ - to select over a number of channels will remain forever, \ - but no guarantees beyond this are being made"] +#![unstable(feature = "std_misc", + reason = "This implementation, while likely sufficient, is unsafe and \ + likely to be error prone. At some point in the future this \ + module will likely be replaced, and it is currently \ + unknown how much API breakage that will cause. The ability \ + to select over a number of channels will remain forever, \ + but no guarantees beyond this are being made")] use core::prelude::*; diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs index 8cd88cedf6b..c1983fcab19 100644 --- a/src/libstd/sync/mpsc/spsc_queue.rs +++ b/src/libstd/sync/mpsc/spsc_queue.rs @@ -33,7 +33,7 @@ //! concurrently between two tasks. This data structure is safe to use and //! enforces the semantics that there is one pusher and one popper. -#![unstable] +#![unstable(feature = "std_misc")] use core::prelude::*; diff --git a/src/libstd/sync/mutex.rs b/src/libstd/sync/mutex.rs index 6ddfe3e075b..f7fdd60eb8c 100644 --- a/src/libstd/sync/mutex.rs +++ b/src/libstd/sync/mutex.rs @@ -109,7 +109,7 @@ use sys_common::mutex as sys; /// /// *guard += 1; /// ``` -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Mutex<T> { // Note that this static mutex is in a *box*, not inlined into the struct // itself. Once a native mutex has been used once, its address can never @@ -145,7 +145,8 @@ unsafe impl<T:Send> Sync for Mutex<T> { } /// } /// // lock is unlocked here. /// ``` -#[unstable = "may be merged with Mutex in the future"] +#[unstable(feature = "std_misc", + reason = "may be merged with Mutex in the future")] pub struct StaticMutex { lock: sys::Mutex, poison: poison::Flag, @@ -159,7 +160,7 @@ unsafe impl Sync for StaticMutex {} /// The data protected by the mutex can be access through this guard via its /// Deref and DerefMut implementations #[must_use] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct MutexGuard<'a, T: 'a> { // funny underscores due to how Deref/DerefMut currently work (they // disregard field privacy). @@ -172,7 +173,8 @@ 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"] +#[unstable(feature = "std_misc", + reason = "may be merged with Mutex in the future")] pub const MUTEX_INIT: StaticMutex = StaticMutex { lock: sys::MUTEX_INIT, poison: poison::FLAG_INIT, @@ -180,7 +182,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex { impl<T: Send> Mutex<T> { /// Creates a new mutex in an unlocked state ready for use. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(t: T) -> Mutex<T> { Mutex { inner: box MUTEX_INIT, @@ -199,7 +201,7 @@ impl<T: Send> Mutex<T> { /// /// If another user of this mutex panicked while holding the mutex, then /// this call will return an error once the mutex is acquired. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn lock(&self) -> LockResult<MutexGuard<T>> { unsafe { self.inner.lock.lock() } MutexGuard::new(&*self.inner, &self.data) @@ -218,7 +220,7 @@ impl<T: Send> Mutex<T> { /// If another user of this mutex panicked while holding the mutex, then /// this call will return failure if the mutex would otherwise be /// acquired. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn try_lock(&self) -> TryLockResult<MutexGuard<T>> { if unsafe { self.inner.lock.try_lock() } { Ok(try!(MutexGuard::new(&*self.inner, &self.data))) @@ -229,7 +231,7 @@ impl<T: Send> Mutex<T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T: Send> Drop for Mutex<T> { fn drop(&mut self) { // This is actually safe b/c we know that there is no further usage of @@ -246,7 +248,8 @@ static DUMMY: Dummy = Dummy(UnsafeCell { value: () }); impl StaticMutex { /// Acquires this lock, see `Mutex::lock` #[inline] - #[unstable = "may be merged with Mutex in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Mutex in the future")] pub fn lock(&'static self) -> LockResult<MutexGuard<()>> { unsafe { self.lock.lock() } MutexGuard::new(self, &DUMMY.0) @@ -254,7 +257,8 @@ impl StaticMutex { /// Attempts to grab this lock, see `Mutex::try_lock` #[inline] - #[unstable = "may be merged with Mutex in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Mutex in the future")] pub fn try_lock(&'static self) -> TryLockResult<MutexGuard<()>> { if unsafe { self.lock.try_lock() } { Ok(try!(MutexGuard::new(self, &DUMMY.0))) @@ -273,7 +277,8 @@ impl StaticMutex { /// *all* platforms. It may be the case that some platforms do not leak /// memory if this method is not called, but this is not guaranteed to be /// true on all platforms. - #[unstable = "may be merged with Mutex in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with Mutex in the future")] pub unsafe fn destroy(&'static self) { self.lock.destroy() } @@ -293,7 +298,7 @@ impl<'mutex, T> MutexGuard<'mutex, T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'mutex, T> Deref for MutexGuard<'mutex, T> { type Target = T; @@ -301,7 +306,7 @@ impl<'mutex, T> Deref for MutexGuard<'mutex, T> { unsafe { &*self.__data.get() } } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> { fn deref_mut<'a>(&'a mut self) -> &'a mut T { unsafe { &mut *self.__data.get() } @@ -309,7 +314,7 @@ impl<'mutex, T> DerefMut for MutexGuard<'mutex, T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Drop for MutexGuard<'a, T> { #[inline] fn drop(&mut self) { diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 6231a91833d..1c489540581 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -36,7 +36,7 @@ use sync::{StaticMutex, MUTEX_INIT}; /// // run initialization here /// }); /// ``` -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct Once { mutex: StaticMutex, cnt: AtomicIsize, @@ -46,7 +46,7 @@ pub struct Once { unsafe impl Sync for Once {} /// Initialization value for static `Once` values. -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub const ONCE_INIT: Once = Once { mutex: MUTEX_INIT, cnt: ATOMIC_ISIZE_INIT, @@ -63,7 +63,7 @@ impl Once { /// /// When this function returns, it is guaranteed that some initialization /// has run and completed (it may not be the closure specified). - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn call_once<F>(&'static self, f: F) where F: FnOnce() { // Optimize common path: load is much cheaper than fetch_add. if self.cnt.load(Ordering::SeqCst) < 0 { diff --git a/src/libstd/sync/poison.rs b/src/libstd/sync/poison.rs index d7fcee3ae2e..18680b96592 100644 --- a/src/libstd/sync/poison.rs +++ b/src/libstd/sync/poison.rs @@ -53,22 +53,22 @@ pub struct Guard { /// is held. The precise semantics for when a lock is poisoned is documented on /// each lock, but once a lock is poisoned then all future acquisitions will /// return this error. -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct PoisonError<T> { guard: T, } /// An enumeration of possible errors which can occur while calling the /// `try_lock` method. -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub enum TryLockError<T> { /// The lock could not be acquired because another task failed while holding /// the lock. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] Poisoned(PoisonError<T>), /// The lock could not be acquired at this time because the operation would /// otherwise block. - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] WouldBlock, } @@ -79,7 +79,7 @@ pub enum TryLockError<T> { /// that the primitive was poisoned. Note that the `Err` variant *also* carries /// the associated guard, and it can be acquired through the `into_inner` /// method. -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>; /// A type alias for the result of a nonblocking locking method. @@ -87,17 +87,17 @@ pub type LockResult<Guard> = Result<Guard, PoisonError<Guard>>; /// For more information, see `LockResult`. A `TryLockResult` doesn't /// necessarily hold the associated guard in the `Err` type as the lock may not /// have been acquired for other reasons. -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub type TryLockResult<Guard> = Result<Guard, TryLockError<Guard>>; -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Debug for PoisonError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { "PoisonError { inner: .. }".fmt(f) } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Display for PoisonError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.description().fmt(f) @@ -113,22 +113,23 @@ impl<T> Error for PoisonError<T> { impl<T> PoisonError<T> { /// Consumes this error indicating that a lock is poisoned, returning the /// underlying guard to allow access regardless. - #[deprecated="renamed to into_inner"] + #[unstable(feature = "std_misc")] + #[deprecated(since = "1.0.0", reason = "renamed to into_inner")] pub fn into_guard(self) -> T { self.guard } /// Consumes this error indicating that a lock is poisoned, returning the /// underlying guard to allow access regardless. - #[unstable] + #[unstable(feature = "std_misc")] pub fn into_inner(self) -> T { self.guard } /// Reaches into this error indicating that a lock is poisoned, returning a /// reference to the underlying guard to allow access regardless. - #[unstable] + #[unstable(feature = "std_misc")] pub fn get_ref(&self) -> &T { &self.guard } /// Reaches into this error indicating that a lock is poisoned, returning a /// mutable reference to the underlying guard to allow access regardless. - #[unstable] + #[unstable(feature = "std_misc")] pub fn get_mut(&mut self) -> &mut T { &mut self.guard } } @@ -138,7 +139,7 @@ impl<T> FromError<PoisonError<T>> for TryLockError<T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Debug for TryLockError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { @@ -148,7 +149,7 @@ impl<T> fmt::Debug for TryLockError<T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> fmt::Display for TryLockError<T> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { self.description().fmt(f) diff --git a/src/libstd/sync/rwlock.rs b/src/libstd/sync/rwlock.rs index 8cc2cac33ec..12befbf72e3 100644 --- a/src/libstd/sync/rwlock.rs +++ b/src/libstd/sync/rwlock.rs @@ -58,7 +58,7 @@ use sys_common::rwlock as sys; /// assert_eq!(*w, 6); /// } // write lock is dropped here /// ``` -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct RwLock<T> { inner: Box<StaticRwLock>, data: UnsafeCell<T>, @@ -90,7 +90,8 @@ unsafe impl<T> Sync for RwLock<T> {} /// } /// unsafe { LOCK.destroy() } // free all resources /// ``` -#[unstable = "may be merged with RwLock in the future"] +#[unstable(feature = "std_misc", + reason = "may be merged with RwLock in the future")] pub struct StaticRwLock { lock: sys::RWLock, poison: poison::Flag, @@ -100,7 +101,8 @@ unsafe impl Send for StaticRwLock {} unsafe impl Sync for StaticRwLock {} /// Constant initialization for a statically-initialized rwlock. -#[unstable = "may be merged with RwLock in the future"] +#[unstable(feature = "std_misc", + reason = "may be merged with RwLock in the future")] pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock { lock: sys::RWLOCK_INIT, poison: poison::FLAG_INIT, @@ -109,7 +111,7 @@ pub const RW_LOCK_INIT: StaticRwLock = StaticRwLock { /// RAII structure used to release the shared read access of a lock when /// dropped. #[must_use] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] pub struct RwLockReadGuard<'a, T: 'a> { __lock: &'a StaticRwLock, __data: &'a UnsafeCell<T>, @@ -120,7 +122,7 @@ 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] +#[stable(feature = "rust1", since = "1.0.0")] pub struct RwLockWriteGuard<'a, T: 'a> { __lock: &'a StaticRwLock, __data: &'a UnsafeCell<T>, @@ -139,7 +141,7 @@ impl<T: Send + Sync> RwLock<T> { /// /// let lock = RwLock::new(5); /// ``` - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn new(t: T) -> RwLock<T> { RwLock { inner: box RW_LOCK_INIT, data: UnsafeCell::new(t) } } @@ -162,7 +164,7 @@ impl<T: Send + Sync> RwLock<T> { /// is poisoned whenever a writer panics while holding an exclusive lock. /// The failure will occur immediately after the lock has been acquired. #[inline] - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn read(&self) -> LockResult<RwLockReadGuard<T>> { unsafe { self.inner.lock.read() } RwLockReadGuard::new(&*self.inner, &self.data) @@ -184,7 +186,7 @@ impl<T: Send + Sync> RwLock<T> { /// error will only be returned if the lock would have otherwise been /// acquired. #[inline] - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<T>> { if unsafe { self.inner.lock.try_read() } { Ok(try!(RwLockReadGuard::new(&*self.inner, &self.data))) @@ -208,7 +210,7 @@ impl<T: Send + Sync> RwLock<T> { /// is poisoned whenever a writer panics while holding an exclusive lock. /// An error will be returned when the lock is acquired. #[inline] - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn write(&self) -> LockResult<RwLockWriteGuard<T>> { unsafe { self.inner.lock.write() } RwLockWriteGuard::new(&*self.inner, &self.data) @@ -227,7 +229,7 @@ impl<T: Send + Sync> RwLock<T> { /// error will only be returned if the lock would have otherwise been /// acquired. #[inline] - #[stable] + #[stable(feature = "rust1", since = "1.0.0")] pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<T>> { if unsafe { self.inner.lock.try_read() } { Ok(try!(RwLockWriteGuard::new(&*self.inner, &self.data))) @@ -238,7 +240,7 @@ impl<T: Send + Sync> RwLock<T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<T> Drop for RwLock<T> { fn drop(&mut self) { unsafe { self.inner.lock.destroy() } @@ -255,7 +257,8 @@ impl StaticRwLock { /// /// See `RwLock::read`. #[inline] - #[unstable = "may be merged with RwLock in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with RwLock in the future")] pub fn read(&'static self) -> LockResult<RwLockReadGuard<'static, ()>> { unsafe { self.lock.read() } RwLockReadGuard::new(self, &DUMMY.0) @@ -265,7 +268,8 @@ impl StaticRwLock { /// /// See `RwLock::try_read`. #[inline] - #[unstable = "may be merged with RwLock in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with RwLock in the future")] pub fn try_read(&'static self) -> TryLockResult<RwLockReadGuard<'static, ()>> { if unsafe { self.lock.try_read() } { @@ -280,7 +284,8 @@ impl StaticRwLock { /// /// See `RwLock::write`. #[inline] - #[unstable = "may be merged with RwLock in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with RwLock in the future")] pub fn write(&'static self) -> LockResult<RwLockWriteGuard<'static, ()>> { unsafe { self.lock.write() } RwLockWriteGuard::new(self, &DUMMY.0) @@ -290,7 +295,8 @@ impl StaticRwLock { /// /// See `RwLock::try_write`. #[inline] - #[unstable = "may be merged with RwLock in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with RwLock in the future")] pub fn try_write(&'static self) -> TryLockResult<RwLockWriteGuard<'static, ()>> { if unsafe { self.lock.try_write() } { @@ -306,7 +312,8 @@ impl StaticRwLock { /// active users of the lock, and this also doesn't prevent any future users /// of this lock. This method is required to be called to not leak memory on /// all platforms. - #[unstable = "may be merged with RwLock in the future"] + #[unstable(feature = "std_misc", + reason = "may be merged with RwLock in the future")] pub unsafe fn destroy(&'static self) { self.lock.destroy() } @@ -338,19 +345,19 @@ impl<'rwlock, T> RwLockWriteGuard<'rwlock, T> { } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'rwlock, T> Deref for RwLockReadGuard<'rwlock, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.__data.get() } } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'rwlock, T> Deref for RwLockWriteGuard<'rwlock, T> { type Target = T; fn deref(&self) -> &T { unsafe { &*self.__data.get() } } } -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> { fn deref_mut(&mut self) -> &mut T { unsafe { &mut *self.__data.get() } @@ -358,7 +365,7 @@ impl<'rwlock, T> DerefMut for RwLockWriteGuard<'rwlock, T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Drop for RwLockReadGuard<'a, T> { fn drop(&mut self) { unsafe { self.__lock.lock.read_unlock(); } @@ -366,7 +373,7 @@ impl<'a, T> Drop for RwLockReadGuard<'a, T> { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'a, T> Drop for RwLockWriteGuard<'a, T> { fn drop(&mut self) { self.__lock.poison.done(&self.__poison); diff --git a/src/libstd/sync/semaphore.rs b/src/libstd/sync/semaphore.rs index 8d44084671a..0304b898884 100644 --- a/src/libstd/sync/semaphore.rs +++ b/src/libstd/sync/semaphore.rs @@ -8,8 +8,9 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -#![unstable = "the interaction between semaphores and the acquisition/release \ - of resources is currently unclear"] +#![unstable(feature = "std_misc", + reason = "the interaction between semaphores and the acquisition/release \ + of resources is currently unclear")] use ops::Drop; use sync::{Mutex, Condvar}; @@ -99,7 +100,7 @@ impl Semaphore { } #[unsafe_destructor] -#[stable] +#[stable(feature = "rust1", since = "1.0.0")] impl<'a> Drop for SemaphoreGuard<'a> { fn drop(&mut self) { self.sem.release(); diff --git a/src/libstd/sync/task_pool.rs b/src/libstd/sync/task_pool.rs index 278528bdb38..3fac998d3e7 100644 --- a/src/libstd/sync/task_pool.rs +++ b/src/libstd/sync/task_pool.rs @@ -10,10 +10,11 @@ //! Abstraction of a thread pool for basic parallelism. -#![unstable = "the semantics of a failing task and whether a thread is \ - re-attached to a thread pool are somewhat unclear, and the \ - utility of this type in `std::sync` is questionable with \ - respect to the jobs of other primitives"] +#![unstable(feature = "std_misc", + reason = "the semantics of a failing task and whether a thread is \ + re-attached to a thread pool are somewhat unclear, and the \ + utility of this type in `std::sync` is questionable with \ + respect to the jobs of other primitives")] use core::prelude::*; |
