Skip to content

Commit d35ebcb

Browse files
committed
Make Barrier and Condvar Sync/Send
1 parent 607f607 commit d35ebcb

File tree

5 files changed

+36
-12
lines changed

5 files changed

+36
-12
lines changed

src/libstd/c_vec.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,12 @@ mod tests {
180180

181181
fn malloc(n: uint) -> CVec<u8> {
182182
unsafe {
183-
let mem = libc::malloc(n as libc::size_t);
184-
if mem.is_null() { ::alloc::oom() }
183+
let mem = ptr::Unique(libc::malloc(n as libc::size_t));
184+
if mem.0.is_null() { ::alloc::oom() }
185185

186-
CVec::new_with_dtor(mem as *mut u8,
186+
CVec::new_with_dtor(mem.0 as *mut u8,
187187
n,
188-
move|| { libc::free(mem as *mut libc::c_void); })
188+
move|| { libc::free(mem.0 as *mut libc::c_void); })
189189
}
190190
}
191191

src/libstd/sync/barrier.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11+
use kinds::{Send, Sync};
1112
use sync::{Mutex, Condvar};
1213

1314
/// A barrier enables multiple tasks to synchronize the beginning
@@ -35,12 +36,18 @@ pub struct Barrier {
3536
num_threads: uint,
3637
}
3738

39+
unsafe impl Send for Barrier {}
40+
unsafe impl Sync for Barrier {}
41+
3842
// The inner state of a double barrier
3943
struct BarrierState {
4044
count: uint,
4145
generation_id: uint,
4246
}
4347

48+
unsafe impl Send for BarrierState {}
49+
unsafe impl Sync for BarrierState {}
50+
4451
impl Barrier {
4552
/// Create a new barrier that can block a given number of threads.
4653
///

src/libstd/sync/condvar.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,9 @@ use time::Duration;
5858
/// ```
5959
pub struct Condvar { inner: Box<StaticCondvar> }
6060

61+
unsafe impl Send for Condvar {}
62+
unsafe impl Sync for Condvar {}
63+
6164
/// Statically allocated condition variables.
6265
///
6366
/// This structure is identical to `Condvar` except that it is suitable for use
@@ -75,6 +78,9 @@ pub struct StaticCondvar {
7578
mutex: AtomicUint,
7679
}
7780

81+
unsafe impl Send for StaticCondvar {}
82+
unsafe impl Sync for StaticCondvar {}
83+
7884
/// Constant initializer for a statically allocated condition variable.
7985
pub const CONDVAR_INIT: StaticCondvar = StaticCondvar {
8086
inner: sys::CONDVAR_INIT,

src/libstd/sync/mutex.rs

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -284,6 +284,11 @@ mod test {
284284
use thread::Thread;
285285
use sync::{Arc, Mutex, StaticMutex, MUTEX_INIT, Condvar};
286286

287+
struct Packet<T>(Arc<(Mutex<T>, Condvar)>);
288+
289+
unsafe impl<T:'static+Send> Send for Packet<T> {}
290+
unsafe impl<T> Sync for Packet<T> {}
291+
287292
#[test]
288293
fn smoke() {
289294
let m = Mutex::new(());
@@ -343,19 +348,19 @@ mod test {
343348

344349
#[test]
345350
fn test_mutex_arc_condvar() {
346-
let arc = Arc::new((Mutex::new(false), Condvar::new()));
347-
let arc2 = arc.clone();
351+
let packet = Packet(Arc::new((Mutex::new(false), Condvar::new())));
352+
let packet2 = Packet(packet.0.clone());
348353
let (tx, rx) = channel();
349354
spawn(move|| {
350355
// wait until parent gets in
351356
rx.recv();
352-
let &(ref lock, ref cvar) = &*arc2;
357+
let &(ref lock, ref cvar) = &*packet2.0;
353358
let mut lock = lock.lock();
354359
*lock = true;
355360
cvar.notify_one();
356361
});
357362

358-
let &(ref lock, ref cvar) = &*arc;
363+
let &(ref lock, ref cvar) = &*packet.0;
359364
let lock = lock.lock();
360365
tx.send(());
361366
assert!(!*lock);
@@ -367,20 +372,20 @@ mod test {
367372
#[test]
368373
#[should_fail]
369374
fn test_arc_condvar_poison() {
370-
let arc = Arc::new((Mutex::new(1i), Condvar::new()));
371-
let arc2 = arc.clone();
375+
let packet = Packet(Arc::new((Mutex::new(1i), Condvar::new())));
376+
let packet2 = Packet(packet.0.clone());
372377
let (tx, rx) = channel();
373378

374379
spawn(move|| {
375380
rx.recv();
376-
let &(ref lock, ref cvar) = &*arc2;
381+
let &(ref lock, ref cvar) = &*packet2.0;
377382
let _g = lock.lock();
378383
cvar.notify_one();
379384
// Parent should fail when it wakes up.
380385
panic!();
381386
});
382387

383-
let &(ref lock, ref cvar) = &*arc;
388+
let &(ref lock, ref cvar) = &*packet.0;
384389
let lock = lock.lock();
385390
tx.send(());
386391
while *lock == 1 {

src/libstd/sync/rwlock.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,9 @@ pub struct RWLock<T> {
6060
data: UnsafeCell<T>,
6161
}
6262

63+
unsafe impl<T:'static+Send> Send for RWLock<T> {}
64+
unsafe impl<T> Sync for RWLock<T> {}
65+
6366
/// Structure representing a statically allocated RWLock.
6467
///
6568
/// This structure is intended to be used inside of a `static` and will provide
@@ -88,6 +91,9 @@ pub struct StaticRWLock {
8891
poison: UnsafeCell<poison::Flag>,
8992
}
9093

94+
unsafe impl Send for StaticRWLock {}
95+
unsafe impl Sync for StaticRWLock {}
96+
9197
/// Constant initialization for a statically-initialized rwlock.
9298
pub const RWLOCK_INIT: StaticRWLock = StaticRWLock {
9399
inner: sys::RWLOCK_INIT,

0 commit comments

Comments
 (0)