Skip to content

Commit

Permalink
Remove 'static bound from sync::mpsc, Mutex and RwLock.
Browse files Browse the repository at this point in the history
Adds some basic tests to check that the types still catch the most
glaring errors that could occur.

cc #22444.
  • Loading branch information
huonw committed Feb 21, 2015
1 parent 522d09d commit 380d23b
Show file tree
Hide file tree
Showing 12 changed files with 147 additions and 45 deletions.
30 changes: 15 additions & 15 deletions src/libstd/sync/mpsc/mod.rs
Expand Up @@ -345,7 +345,7 @@ pub struct Receiver<T> {

// The receiver port can be sent from place to place, so long as it
// is not used to receive non-sendable things.
unsafe impl<T: Send + 'static> Send for Receiver<T> { }
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
Expand All @@ -364,7 +364,7 @@ pub struct Sender<T> {

// The send port can be sent from place to place, so long as it
// is not used to send non-sendable things.
unsafe impl<T: Send + 'static> Send for Sender<T> { }
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.
Expand All @@ -373,7 +373,7 @@ pub struct SyncSender<T> {
inner: Arc<UnsafeCell<sync::Packet<T>>>,
}

unsafe impl<T: Send + 'static> Send for SyncSender<T> {}
unsafe impl<T: Send> Send for SyncSender<T> {}

impl<T> !Sync for SyncSender<T> {}

Expand Down Expand Up @@ -485,7 +485,7 @@ impl<T> UnsafeFlavor<T> for Receiver<T> {
/// println!("{:?}", rx.recv().unwrap());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) {
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)))
}
Expand Down Expand Up @@ -525,7 +525,7 @@ pub fn channel<T: Send + 'static>() -> (Sender<T>, Receiver<T>) {
/// assert_eq!(rx.recv().unwrap(), 2);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
pub fn sync_channel<T: Send + 'static>(bound: uint) -> (SyncSender<T>, Receiver<T>) {
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)))
}
Expand All @@ -534,7 +534,7 @@ pub fn sync_channel<T: Send + 'static>(bound: uint) -> (SyncSender<T>, Receiver<
// Sender
////////////////////////////////////////////////////////////////////////////////

impl<T: Send + 'static> Sender<T> {
impl<T: Send> Sender<T> {
fn new(inner: Flavor<T>) -> Sender<T> {
Sender {
inner: UnsafeCell::new(inner),
Expand Down Expand Up @@ -616,7 +616,7 @@ impl<T: Send + 'static> Sender<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + 'static> Clone for Sender<T> {
impl<T: Send> Clone for Sender<T> {
fn clone(&self) -> Sender<T> {
let (packet, sleeper, guard) = match *unsafe { self.inner() } {
Flavor::Oneshot(ref p) => {
Expand Down Expand Up @@ -662,7 +662,7 @@ impl<T: Send + 'static> Clone for Sender<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + 'static> Drop for Sender<T> {
impl<T: Send> Drop for Sender<T> {
fn drop(&mut self) {
match *unsafe { self.inner_mut() } {
Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_chan(); },
Expand All @@ -677,7 +677,7 @@ impl<T: Send + 'static> Drop for Sender<T> {
// SyncSender
////////////////////////////////////////////////////////////////////////////////

impl<T: Send + 'static> SyncSender<T> {
impl<T: Send> SyncSender<T> {
fn new(inner: Arc<UnsafeCell<sync::Packet<T>>>) -> SyncSender<T> {
SyncSender { inner: inner }
}
Expand Down Expand Up @@ -717,7 +717,7 @@ impl<T: Send + 'static> SyncSender<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + 'static> Clone for SyncSender<T> {
impl<T: Send> Clone for SyncSender<T> {
fn clone(&self) -> SyncSender<T> {
unsafe { (*self.inner.get()).clone_chan(); }
return SyncSender::new(self.inner.clone());
Expand All @@ -726,7 +726,7 @@ impl<T: Send + 'static> Clone for SyncSender<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + 'static> Drop for SyncSender<T> {
impl<T: Send> Drop for SyncSender<T> {
fn drop(&mut self) {
unsafe { (*self.inner.get()).drop_chan(); }
}
Expand All @@ -736,7 +736,7 @@ impl<T: Send + 'static> Drop for SyncSender<T> {
// Receiver
////////////////////////////////////////////////////////////////////////////////

impl<T: Send + 'static> Receiver<T> {
impl<T: Send> Receiver<T> {
fn new(inner: Flavor<T>) -> Receiver<T> {
Receiver { inner: UnsafeCell::new(inner) }
}
Expand Down Expand Up @@ -855,7 +855,7 @@ impl<T: Send + 'static> Receiver<T> {
}
}

impl<T: Send + 'static> select::Packet for Receiver<T> {
impl<T: Send> select::Packet for Receiver<T> {
fn can_recv(&self) -> bool {
loop {
let new_port = match *unsafe { self.inner() } {
Expand Down Expand Up @@ -942,15 +942,15 @@ impl<T: Send + 'static> select::Packet for Receiver<T> {
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<'a, T: Send + 'static> Iterator for Iter<'a, T> {
impl<'a, T: Send> Iterator for Iter<'a, T> {
type Item = T;

fn next(&mut self) -> Option<T> { self.rx.recv().ok() }
}

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + 'static> Drop for Receiver<T> {
impl<T: Send> Drop for Receiver<T> {
fn drop(&mut self) {
match *unsafe { self.inner_mut() } {
Flavor::Oneshot(ref mut p) => unsafe { (*p.get()).drop_port(); },
Expand Down
6 changes: 3 additions & 3 deletions src/libstd/sync/mpsc/mpsc_queue.rs
Expand Up @@ -78,7 +78,7 @@ pub struct Queue<T> {
}

unsafe impl<T:Send> Send for Queue<T> { }
unsafe impl<T: Send + 'static> Sync for Queue<T> { }
unsafe impl<T: Send> Sync for Queue<T> { }

impl<T> Node<T> {
unsafe fn new(v: Option<T>) -> *mut Node<T> {
Expand All @@ -89,7 +89,7 @@ impl<T> Node<T> {
}
}

impl<T: Send + 'static> Queue<T> {
impl<T: Send> Queue<T> {
/// Creates a new queue that is safe to share among multiple producers and
/// one consumer.
pub fn new() -> Queue<T> {
Expand Down Expand Up @@ -140,7 +140,7 @@ impl<T: Send + 'static> Queue<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + 'static> Drop for Queue<T> {
impl<T: Send> Drop for Queue<T> {
fn drop(&mut self) {
unsafe {
let mut cur = *self.tail.get();
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sync/mpsc/oneshot.rs
Expand Up @@ -88,7 +88,7 @@ enum MyUpgrade<T> {
GoUp(Receiver<T>),
}

impl<T: Send + 'static> Packet<T> {
impl<T: Send> Packet<T> {
pub fn new() -> Packet<T> {
Packet {
data: None,
Expand Down Expand Up @@ -368,7 +368,7 @@ impl<T: Send + 'static> Packet<T> {
}

#[unsafe_destructor]
impl<T: Send + 'static> Drop for Packet<T> {
impl<T: Send> Drop for Packet<T> {
fn drop(&mut self) {
assert_eq!(self.state.load(Ordering::SeqCst), DISCONNECTED);
}
Expand Down
6 changes: 3 additions & 3 deletions src/libstd/sync/mpsc/select.rs
Expand Up @@ -134,7 +134,7 @@ impl Select {
/// 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.
pub fn handle<'a, T: Send + 'static>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
pub fn handle<'a, T: Send>(&'a self, rx: &'a Receiver<T>) -> Handle<'a, T> {
let id = self.next_id.get();
self.next_id.set(id + 1);
Handle {
Expand Down Expand Up @@ -251,7 +251,7 @@ impl Select {
fn iter(&self) -> Packets { Packets { cur: self.head } }
}

impl<'rx, T: Send + 'static> Handle<'rx, T> {
impl<'rx, T: Send> Handle<'rx, T> {
/// Retrieve the id of this handle.
#[inline]
pub fn id(&self) -> uint { self.id }
Expand Down Expand Up @@ -322,7 +322,7 @@ impl Drop for Select {
}

#[unsafe_destructor]
impl<'rx, T: Send + 'static> Drop for Handle<'rx, T> {
impl<'rx, T: Send> Drop for Handle<'rx, T> {
fn drop(&mut self) {
unsafe { self.remove() }
}
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sync/mpsc/shared.rs
Expand Up @@ -64,7 +64,7 @@ pub enum Failure {
Disconnected,
}

impl<T: Send + 'static> Packet<T> {
impl<T: Send> Packet<T> {
// Creation of a packet *must* be followed by a call to postinit_lock
// and later by inherit_blocker
pub fn new() -> Packet<T> {
Expand Down Expand Up @@ -474,7 +474,7 @@ impl<T: Send + 'static> Packet<T> {
}

#[unsafe_destructor]
impl<T: Send + 'static> Drop for Packet<T> {
impl<T: Send> Drop for Packet<T> {
fn drop(&mut self) {
// Note that this load is not only an assert for correctness about
// disconnection, but also a proper fence before the read of
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/sync/mpsc/spsc_queue.rs
Expand Up @@ -74,11 +74,11 @@ pub struct Queue<T> {
cache_subtractions: AtomicUsize,
}

unsafe impl<T: Send + 'static> Send for Queue<T> { }
unsafe impl<T: Send> Send for Queue<T> { }

unsafe impl<T: Send + 'static> Sync for Queue<T> { }
unsafe impl<T: Send> Sync for Queue<T> { }

impl<T: Send + 'static> Node<T> {
impl<T: Send> Node<T> {
fn new() -> *mut Node<T> {
unsafe {
mem::transmute(box Node {
Expand All @@ -89,7 +89,7 @@ impl<T: Send + 'static> Node<T> {
}
}

impl<T: Send + 'static> Queue<T> {
impl<T: Send> Queue<T> {
/// Creates a new queue.
///
/// This is unsafe as the type system doesn't enforce a single
Expand Down Expand Up @@ -227,7 +227,7 @@ impl<T: Send + 'static> Queue<T> {
}

#[unsafe_destructor]
impl<T: Send + 'static> Drop for Queue<T> {
impl<T: Send> Drop for Queue<T> {
fn drop(&mut self) {
unsafe {
let mut cur = *self.first.get();
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sync/mpsc/stream.rs
Expand Up @@ -74,7 +74,7 @@ enum Message<T> {
GoUp(Receiver<T>),
}

impl<T: Send + 'static> Packet<T> {
impl<T: Send> Packet<T> {
pub fn new() -> Packet<T> {
Packet {
queue: unsafe { spsc::Queue::new(128) },
Expand Down Expand Up @@ -472,7 +472,7 @@ impl<T: Send + 'static> Packet<T> {
}

#[unsafe_destructor]
impl<T: Send + 'static> Drop for Packet<T> {
impl<T: Send> Drop for Packet<T> {
fn drop(&mut self) {
// Note that this load is not only an assert for correctness about
// disconnection, but also a proper fence before the read of
Expand Down
12 changes: 6 additions & 6 deletions src/libstd/sync/mpsc/sync.rs
Expand Up @@ -55,9 +55,9 @@ pub struct Packet<T> {
lock: Mutex<State<T>>,
}

unsafe impl<T: Send + 'static> Send for Packet<T> { }
unsafe impl<T: Send> Send for Packet<T> { }

unsafe impl<T: Send + 'static> Sync for Packet<T> { }
unsafe impl<T: Send> Sync for Packet<T> { }

struct State<T> {
disconnected: bool, // Is the channel disconnected yet?
Expand All @@ -75,7 +75,7 @@ struct State<T> {
canceled: Option<&'static mut bool>,
}

unsafe impl<T: Send + 'static> Send for State<T> {}
unsafe impl<T: Send> Send for State<T> {}

/// Possible flavors of threads who can be blocked on this channel.
enum Blocker {
Expand Down Expand Up @@ -113,7 +113,7 @@ pub enum Failure {

/// Atomically blocks the current thread, placing it into `slot`, unlocking `lock`
/// in the meantime. This re-locks the mutex upon returning.
fn wait<'a, 'b, T: Send + 'static>(lock: &'a Mutex<State<T>>,
fn wait<'a, 'b, T: Send>(lock: &'a Mutex<State<T>>,
mut guard: MutexGuard<'b, State<T>>,
f: fn(SignalToken) -> Blocker)
-> MutexGuard<'a, State<T>>
Expand All @@ -136,7 +136,7 @@ fn wakeup<T>(token: SignalToken, guard: MutexGuard<State<T>>) {
token.signal();
}

impl<T: Send + 'static> Packet<T> {
impl<T: Send> Packet<T> {
pub fn new(cap: uint) -> Packet<T> {
Packet {
channels: AtomicUsize::new(1),
Expand Down Expand Up @@ -412,7 +412,7 @@ impl<T: Send + 'static> Packet<T> {
}

#[unsafe_destructor]
impl<T: Send + 'static> Drop for Packet<T> {
impl<T: Send> Drop for Packet<T> {
fn drop(&mut self) {
assert_eq!(self.channels.load(Ordering::SeqCst), 0);
let mut guard = self.lock.lock().unwrap();
Expand Down
10 changes: 5 additions & 5 deletions src/libstd/sync/mutex.rs
Expand Up @@ -120,9 +120,9 @@ pub struct Mutex<T> {
data: UnsafeCell<T>,
}

unsafe impl<T: Send + 'static> Send for Mutex<T> { }
unsafe impl<T: Send> Send for Mutex<T> { }

unsafe impl<T: Send + 'static> Sync for Mutex<T> { }
unsafe impl<T: Send> Sync for Mutex<T> { }

/// The static mutex type is provided to allow for static allocation of mutexes.
///
Expand Down Expand Up @@ -180,7 +180,7 @@ pub const MUTEX_INIT: StaticMutex = StaticMutex {
poison: poison::FLAG_INIT,
};

impl<T: Send + 'static> Mutex<T> {
impl<T: Send> Mutex<T> {
/// Creates a new mutex in an unlocked state ready for use.
#[stable(feature = "rust1", since = "1.0.0")]
pub fn new(t: T) -> Mutex<T> {
Expand Down Expand Up @@ -243,7 +243,7 @@ impl<T: Send + 'static> Mutex<T> {

#[unsafe_destructor]
#[stable(feature = "rust1", since = "1.0.0")]
impl<T: Send + 'static> Drop for Mutex<T> {
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
// this mutex (it's up to the user to arrange for a mutex to get
Expand Down Expand Up @@ -354,7 +354,7 @@ mod test {

struct Packet<T>(Arc<(Mutex<T>, Condvar)>);

unsafe impl<T:'static+Send> Send for Packet<T> {}
unsafe impl<T: Send> Send for Packet<T> {}
unsafe impl<T> Sync for Packet<T> {}

#[test]
Expand Down
4 changes: 2 additions & 2 deletions src/libstd/sync/rwlock.rs
Expand Up @@ -64,8 +64,8 @@ pub struct RwLock<T> {
data: UnsafeCell<T>,
}

unsafe impl<T:'static+Send> Send for RwLock<T> {}
unsafe impl<T> Sync for RwLock<T> {}
unsafe impl<T: Send + Sync> Send for RwLock<T> {}
unsafe impl<T: Send + Sync> Sync for RwLock<T> {}

/// Structure representing a statically allocated RwLock.
///
Expand Down

0 comments on commit 380d23b

Please sign in to comment.