about summary refs log tree commit diff
path: root/src/libstd/sync
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2015-01-16 13:10:59 +0000
committerbors <bors@rust-lang.org>2015-01-16 13:10:59 +0000
commitee2bfae011e368e224d6d4f4c9fad13606ee99da (patch)
tree189eebe03c5b7fba71d429db8e0561a45d1317cb /src/libstd/sync
parentf3d71be65cccfddd232e733c11129ed53961f980 (diff)
parentcb852239033baf4f44ab448f27127d6ab906c7c0 (diff)
downloadrust-ee2bfae011e368e224d6d4f4c9fad13606ee99da.tar.gz
rust-ee2bfae011e368e224d6d4f4c9fad13606ee99da.zip
auto merge of #20972 : FlaPer87/rust/oibit-send-and-friends, r=nikomatsakis
This PR adds rules for negative implementations. It follows pretty much what the [RFC](https://github.com/rust-lang/rfcs/blob/master/text/0019-opt-in-builtin-traits.md) says with 1 main difference:

Instead of positive implementations override negative implementations, this have been implemented in a way that a negative implementation of `Trait` for `T` will overlap with a positive implementation, causing a coherence error.

@nikomatsakis r?

cc #13231

[breaking-change]
Diffstat (limited to 'src/libstd/sync')
-rw-r--r--src/libstd/sync/mpsc/blocking.rs29
-rw-r--r--src/libstd/sync/mpsc/mod.rs18
-rw-r--r--src/libstd/sync/mpsc/select.rs28
-rw-r--r--src/libstd/sync/mutex.rs33
-rw-r--r--src/libstd/sync/rwlock.rs54
5 files changed, 162 insertions, 0 deletions
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<Inner>,
 }
 
+#[cfg(stage0)] // NOTE remove impl after next snapshot
 pub struct WaitToken {
     inner: Arc<Inner>,
     no_send: NoSend,
     no_sync: NoSync,
 }
 
+#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
+pub struct WaitToken {
+    inner: Arc<Inner>,
+}
+
+#[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<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]
+#[cfg(stage0)] // NOTE remove impl after next snapshot
 pub struct SyncSender<T> {
     inner: Arc<RacyCell<sync::Packet<T>>>,
     // 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<T> {
+    inner: Arc<RacyCell<sync::Packet<T>>>,
+}
+
+#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
+impl<T> !marker::Sync for SyncSender<T> {}
+
 /// 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<T: Send> Drop for Sender<T> {
 ////////////////////////////////////////////////////////////////////////////////
 
 impl<T: Send> SyncSender<T> {
+    #[cfg(stage0)] // NOTE remove impl after next snapshot
     fn new(inner: Arc<RacyCell<sync::Packet<T>>>) -> SyncSender<T> {
         SyncSender { inner: inner, _marker: marker::NoSync }
     }
 
+    #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
+    fn new(inner: Arc<RacyCell<sync::Packet<T>>>) -> SyncSender<T> {
+        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<uint>,
+}
+
+#[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<T>,
+    __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<T>)
            -> LockResult<MutexGuard<'mutex, T>> {
         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<T>)
+           -> LockResult<MutexGuard<'mutex, T>> {
+        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,16 +110,31 @@ 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<T>,
     __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<T>,
+}
+
+#[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<T>,
@@ -127,6 +142,20 @@ pub struct RwLockWriteGuard<'a, T: 'a> {
     __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<T>,
+    __poison: poison::Guard,
+}
+
+#[cfg(not(stage0))] // NOTE remove cfg after next snapshot
+impl<'a, T> !marker::Send for RwLockWriteGuard<'a, T> {}
+
 impl<T: Send + Sync> RwLock<T> {
     /// 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<T>)
            -> LockResult<RwLockReadGuard<'rwlock, T>> {
         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<T>)
+           -> LockResult<RwLockReadGuard<'rwlock, T>> {
+        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<T>)
            -> LockResult<RwLockWriteGuard<'rwlock, T>> {
         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<T>)
+           -> LockResult<RwLockWriteGuard<'rwlock, T>> {
+        poison::map_result(lock.poison.borrow(), |guard| {
+            RwLockWriteGuard {
+                __lock: lock,
+                __data: data,
+                __poison: guard,
+            }
+        })
+    }
 }
 
 #[stable]