Skip to content

Commit c3adbd3

Browse files
committed
Fall out of the std::sync rewrite
1 parent 71d4e77 commit c3adbd3

19 files changed

+99
-188
lines changed

src/etc/licenseck.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,8 @@
3838
"rt/isaac/randport.cpp", # public domain
3939
"rt/isaac/rand.h", # public domain
4040
"rt/isaac/standard.h", # public domain
41-
"libstd/sync/mpsc_queue.rs", # BSD
42-
"libstd/sync/spsc_queue.rs", # BSD
43-
"libstd/sync/mpmc_bounded_queue.rs", # BSD
41+
"libstd/comm/mpsc_queue.rs", # BSD
42+
"libstd/comm/spsc_queue.rs", # BSD
4443
"test/bench/shootout-binarytrees.rs", # BSD
4544
"test/bench/shootout-chameneos-redux.rs", # BSD
4645
"test/bench/shootout-fannkuch-redux.rs", # BSD

src/libstd/comm/mod.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,8 @@ mod select;
354354
mod shared;
355355
mod stream;
356356
mod sync;
357+
mod mpsc_queue;
358+
mod spsc_queue;
357359

358360
/// The receiving-half of Rust's channel type. This half can only be owned by
359361
/// one task
@@ -628,24 +630,26 @@ impl<T: Send> Sender<T> {
628630
#[unstable]
629631
impl<T: Send> Clone for Sender<T> {
630632
fn clone(&self) -> Sender<T> {
631-
let (packet, sleeper) = match *unsafe { self.inner() } {
633+
let (packet, sleeper, guard) = match *unsafe { self.inner() } {
632634
Oneshot(ref p) => {
633635
let a = Arc::new(UnsafeCell::new(shared::Packet::new()));
634636
unsafe {
635-
(*a.get()).postinit_lock();
637+
let guard = (*a.get()).postinit_lock();
636638
match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) {
637-
oneshot::UpSuccess | oneshot::UpDisconnected => (a, None),
638-
oneshot::UpWoke(task) => (a, Some(task))
639+
oneshot::UpSuccess |
640+
oneshot::UpDisconnected => (a, None, guard),
641+
oneshot::UpWoke(task) => (a, Some(task), guard)
639642
}
640643
}
641644
}
642645
Stream(ref p) => {
643646
let a = Arc::new(UnsafeCell::new(shared::Packet::new()));
644647
unsafe {
645-
(*a.get()).postinit_lock();
648+
let guard = (*a.get()).postinit_lock();
646649
match (*p.get()).upgrade(Receiver::new(Shared(a.clone()))) {
647-
stream::UpSuccess | stream::UpDisconnected => (a, None),
648-
stream::UpWoke(task) => (a, Some(task)),
650+
stream::UpSuccess |
651+
stream::UpDisconnected => (a, None, guard),
652+
stream::UpWoke(task) => (a, Some(task), guard),
649653
}
650654
}
651655
}
@@ -657,7 +661,7 @@ impl<T: Send> Clone for Sender<T> {
657661
};
658662

659663
unsafe {
660-
(*packet.get()).inherit_blocker(sleeper);
664+
(*packet.get()).inherit_blocker(sleeper, guard);
661665

662666
let tmp = Sender::new(Shared(packet.clone()));
663667
mem::swap(self.inner_mut(), tmp.inner_mut());

src/libstd/comm/shared.rs

+11-10
Original file line numberDiff line numberDiff line change
@@ -26,12 +26,11 @@ use alloc::boxed::Box;
2626
use core::cmp;
2727
use core::int;
2828
use rustrt::local::Local;
29-
use rustrt::mutex::NativeMutex;
3029
use rustrt::task::{Task, BlockedTask};
3130
use rustrt::thread::Thread;
3231

33-
use sync::atomic;
34-
use sync::mpsc_queue as mpsc;
32+
use sync::{atomic, Mutex, MutexGuard};
33+
use comm::mpsc_queue as mpsc;
3534

3635
const DISCONNECTED: int = int::MIN;
3736
const FUDGE: int = 1024;
@@ -56,7 +55,7 @@ pub struct Packet<T> {
5655

5756
// this lock protects various portions of this implementation during
5857
// select()
59-
select_lock: NativeMutex,
58+
select_lock: Mutex<()>,
6059
}
6160

6261
pub enum Failure {
@@ -76,7 +75,7 @@ impl<T: Send> Packet<T> {
7675
channels: atomic::AtomicInt::new(2),
7776
port_dropped: atomic::AtomicBool::new(false),
7877
sender_drain: atomic::AtomicInt::new(0),
79-
select_lock: unsafe { NativeMutex::new() },
78+
select_lock: Mutex::new(()),
8079
};
8180
return p;
8281
}
@@ -86,16 +85,18 @@ impl<T: Send> Packet<T> {
8685
// In other case mutex data will be duplicated while cloning
8786
// and that could cause problems on platforms where it is
8887
// represented by opaque data structure
89-
pub fn postinit_lock(&mut self) {
90-
unsafe { self.select_lock.lock_noguard() }
88+
pub fn postinit_lock(&self) -> MutexGuard<()> {
89+
self.select_lock.lock()
9190
}
9291

9392
// This function is used at the creation of a shared packet to inherit a
9493
// previously blocked task. This is done to prevent spurious wakeups of
9594
// tasks in select().
9695
//
9796
// This can only be called at channel-creation time
98-
pub fn inherit_blocker(&mut self, task: Option<BlockedTask>) {
97+
pub fn inherit_blocker(&mut self,
98+
task: Option<BlockedTask>,
99+
guard: MutexGuard<()>) {
99100
match task {
100101
Some(task) => {
101102
assert_eq!(self.cnt.load(atomic::SeqCst), 0);
@@ -135,7 +136,7 @@ impl<T: Send> Packet<T> {
135136
// interfere with this method. After we unlock this lock, we're
136137
// signifying that we're done modifying self.cnt and self.to_wake and
137138
// the port is ready for the world to continue using it.
138-
unsafe { self.select_lock.unlock_noguard() }
139+
drop(guard);
139140
}
140141

141142
pub fn send(&mut self, t: T) -> Result<(), T> {
@@ -441,7 +442,7 @@ impl<T: Send> Packet<T> {
441442
// done with. Without this bounce, we can race with inherit_blocker
442443
// about looking at and dealing with to_wake. Once we have acquired the
443444
// lock, we are guaranteed that inherit_blocker is done.
444-
unsafe {
445+
{
445446
let _guard = self.select_lock.lock();
446447
}
447448

src/libstd/comm/stream.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ use rustrt::task::{Task, BlockedTask};
3232
use rustrt::thread::Thread;
3333

3434
use sync::atomic;
35-
use sync::spsc_queue as spsc;
35+
use comm::spsc_queue as spsc;
3636
use comm::Receiver;
3737

3838
const DISCONNECTED: int = int::MIN;

src/libstd/dynamic_lib.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -225,8 +225,8 @@ pub mod dl {
225225
}
226226

227227
pub fn check_for_errors_in<T>(f: || -> T) -> Result<T, String> {
228-
use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
229-
static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
228+
use sync::{StaticMutex, MUTEX_INIT};
229+
static LOCK: StaticMutex = MUTEX_INIT;
230230
unsafe {
231231
// dlerror isn't thread safe, so we need to lock around this entire
232232
// sequence

src/libstd/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@
106106
#![allow(unknown_features)]
107107
#![feature(macro_rules, globs, linkage)]
108108
#![feature(default_type_params, phase, lang_items, unsafe_destructor)]
109-
#![feature(import_shadowing, slicing_syntax)]
109+
#![feature(import_shadowing, slicing_syntax, tuple_indexing)]
110110

111111
// Don't link to std. We are std.
112112
#![no_std]

src/libstd/os.rs

+4-6
Original file line numberDiff line numberDiff line change
@@ -209,14 +209,12 @@ Accessing environment variables is not generally threadsafe.
209209
Serialize access through a global lock.
210210
*/
211211
fn with_env_lock<T>(f: || -> T) -> T {
212-
use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
212+
use sync::{StaticMutex, MUTEX_INIT};
213213

214-
static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
214+
static LOCK: StaticMutex = MUTEX_INIT;
215215

216-
unsafe {
217-
let _guard = LOCK.lock();
218-
f()
219-
}
216+
let _guard = LOCK.lock();
217+
f()
220218
}
221219

222220
/// Returns a vector of (variable, value) pairs, for all the environment

src/libstd/rt/backtrace.rs

+8-8
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ mod imp {
238238
use mem;
239239
use option::{Some, None, Option};
240240
use result::{Ok, Err};
241-
use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
241+
use sync::{StaticMutex, MUTEX_INIT};
242242

243243
/// As always - iOS on arm uses SjLj exceptions and
244244
/// _Unwind_Backtrace is even not available there. Still,
@@ -264,8 +264,8 @@ mod imp {
264264
// while it doesn't requires lock for work as everything is
265265
// local, it still displays much nicer backtraces when a
266266
// couple of tasks panic simultaneously
267-
static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
268-
let _g = unsafe { LOCK.lock() };
267+
static LOCK: StaticMutex = MUTEX_INIT;
268+
let _g = LOCK.lock();
269269

270270
try!(writeln!(w, "stack backtrace:"));
271271
// 100 lines should be enough
@@ -297,8 +297,8 @@ mod imp {
297297
// is semi-reasonable in terms of printing anyway, and we know that all
298298
// I/O done here is blocking I/O, not green I/O, so we don't have to
299299
// worry about this being a native vs green mutex.
300-
static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
301-
let _g = unsafe { LOCK.lock() };
300+
static LOCK: StaticMutex = MUTEX_INIT;
301+
let _g = LOCK.lock();
302302

303303
try!(writeln!(w, "stack backtrace:"));
304304

@@ -667,7 +667,7 @@ mod imp {
667667
use option::{Some, None};
668668
use path::Path;
669669
use result::{Ok, Err};
670-
use rustrt::mutex::{StaticNativeMutex, NATIVE_MUTEX_INIT};
670+
use sync::{StaticMutex, MUTEX_INIT};
671671
use slice::SlicePrelude;
672672
use str::StrPrelude;
673673
use dynamic_lib::DynamicLibrary;
@@ -928,8 +928,8 @@ mod imp {
928928
pub fn write(w: &mut Writer) -> IoResult<()> {
929929
// According to windows documentation, all dbghelp functions are
930930
// single-threaded.
931-
static LOCK: StaticNativeMutex = NATIVE_MUTEX_INIT;
932-
let _g = unsafe { LOCK.lock() };
931+
static LOCK: StaticMutex = MUTEX_INIT;
932+
let _g = LOCK.lock();
933933

934934
// Open up dbghelp.dll, we don't link to it explicitly because it can't
935935
// always be found. Additionally, it's nice having fewer dependencies.

src/libstd/sync/condvar.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,14 @@ impl Condvar {
143143
///
144144
/// Like `wait`, the lock specified will be re-acquired when this function
145145
/// returns, regardless of whether the timeout elapsed or not.
146-
pub fn wait_timeout<T: AsMutexGuard>(&self, mutex_guard: &T,
147-
dur: Duration) -> bool {
146+
// Note that this method is *not* public, and this is quite intentional
147+
// because we're not quite sure about the semantics of relative vs absolute
148+
// durations or how the timing guarantees play into what the system APIs
149+
// provide. There are also additional concerns about the unix-specific
150+
// implementation which may need to be addressed.
151+
#[allow(dead_code)]
152+
fn wait_timeout<T: AsMutexGuard>(&self, mutex_guard: &T,
153+
dur: Duration) -> bool {
148154
unsafe {
149155
let me: &'static Condvar = &*(self as *const _);
150156
me.inner.wait_timeout(mutex_guard, dur)
@@ -195,8 +201,9 @@ impl StaticCondvar {
195201
/// specified duration.
196202
///
197203
/// See `Condvar::wait_timeout`.
198-
pub fn wait_timeout<T: AsMutexGuard>(&'static self, mutex_guard: &T,
199-
dur: Duration) -> bool {
204+
#[allow(dead_code)] // may want to stabilize this later, see wait_timeout above
205+
fn wait_timeout<T: AsMutexGuard>(&'static self, mutex_guard: &T,
206+
dur: Duration) -> bool {
200207
unsafe {
201208
let lock = mutex_guard.as_mutex_guard();
202209
let sys = mutex::guard_lock(lock);

src/libstd/sync/mutex.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ use sys_common::mutex as sys;
4545
/// let data = Arc::new(Mutex::new(0));
4646
///
4747
/// let (tx, rx) = channel();
48-
/// for _ in range(0, 10) {
48+
/// for _ in range(0u, 10) {
4949
/// let (data, tx) = (data.clone(), tx.clone());
5050
/// spawn(proc() {
5151
/// // The shared static can only be accessed once the lock is held.

src/libstd/sys/common/helper_thread.rs

+15-6
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,14 @@
2020
//! can be created in the future and there must be no active timers at that
2121
//! time.
2222
23+
use prelude::*;
24+
25+
use cell::UnsafeCell;
2326
use mem;
2427
use rustrt::bookkeeping;
25-
use rustrt::mutex::StaticNativeMutex;
2628
use rustrt;
27-
use cell::UnsafeCell;
29+
use sync::{StaticMutex, StaticCondvar};
2830
use sys::helper_signal;
29-
use prelude::*;
3031

3132
use task;
3233

@@ -39,7 +40,8 @@ use task;
3940
/// is for static initialization.
4041
pub struct Helper<M> {
4142
/// Internal lock which protects the remaining fields
42-
pub lock: StaticNativeMutex,
43+
pub lock: StaticMutex,
44+
pub cond: StaticCondvar,
4345

4446
// You'll notice that the remaining fields are UnsafeCell<T>, and this is
4547
// because all helper thread operations are done through &self, but we need
@@ -53,6 +55,9 @@ pub struct Helper<M> {
5355

5456
/// Flag if this helper thread has booted and been initialized yet.
5557
pub initialized: UnsafeCell<bool>,
58+
59+
/// Flag if this helper thread has shut down
60+
pub shutdown: UnsafeCell<bool>,
5661
}
5762

5863
impl<M: Send> Helper<M> {
@@ -80,7 +85,9 @@ impl<M: Send> Helper<M> {
8085
task::spawn(proc() {
8186
bookkeeping::decrement();
8287
helper(receive, rx, t);
83-
self.lock.lock().signal()
88+
let _g = self.lock.lock();
89+
*self.shutdown.get() = true;
90+
self.cond.notify_one()
8491
});
8592

8693
rustrt::at_exit(proc() { self.shutdown() });
@@ -119,7 +126,9 @@ impl<M: Send> Helper<M> {
119126
helper_signal::signal(*self.signal.get() as helper_signal::signal);
120127

121128
// Wait for the child to exit
122-
guard.wait();
129+
while !*self.shutdown.get() {
130+
self.cond.wait(&guard);
131+
}
123132
drop(guard);
124133

125134
// Clean up after ourselves

src/libstd/sys/common/net.rs

+6-6
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,13 @@ use libc::{mod, c_char, c_int};
1616
use mem;
1717
use num::Int;
1818
use ptr::{mod, null, null_mut};
19-
use rustrt::mutex;
2019
use io::net::ip::{SocketAddr, IpAddr, Ipv4Addr, Ipv6Addr};
2120
use io::net::addrinfo;
2221
use io::{IoResult, IoError};
2322
use sys::{mod, retry, c, sock_t, last_error, last_net_error, last_gai_error, close_sock,
2423
wrlen, msglen_t, os, wouldblock, set_nonblocking, timer, ms_to_timeval,
2524
decode_error_detailed};
25+
use sync::{Mutex, MutexGuard};
2626
use sys_common::{mod, keep_going, short_write, timeout};
2727
use prelude::*;
2828
use cmp;
@@ -557,12 +557,12 @@ struct Inner {
557557

558558
// Unused on Linux, where this lock is not necessary.
559559
#[allow(dead_code)]
560-
lock: mutex::NativeMutex
560+
lock: Mutex<()>,
561561
}
562562

563563
impl Inner {
564564
fn new(fd: sock_t) -> Inner {
565-
Inner { fd: fd, lock: unsafe { mutex::NativeMutex::new() } }
565+
Inner { fd: fd, lock: Mutex::new(()) }
566566
}
567567
}
568568

@@ -572,7 +572,7 @@ impl Drop for Inner {
572572

573573
pub struct Guard<'a> {
574574
pub fd: sock_t,
575-
pub guard: mutex::LockGuard<'a>,
575+
pub guard: MutexGuard<'a, ()>,
576576
}
577577

578578
#[unsafe_destructor]
@@ -666,7 +666,7 @@ impl TcpStream {
666666
fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
667667
let ret = Guard {
668668
fd: self.fd(),
669-
guard: unsafe { self.inner.lock.lock() },
669+
guard: self.inner.lock.lock(),
670670
};
671671
assert!(set_nonblocking(self.fd(), true).is_ok());
672672
ret
@@ -805,7 +805,7 @@ impl UdpSocket {
805805
fn lock_nonblocking<'a>(&'a self) -> Guard<'a> {
806806
let ret = Guard {
807807
fd: self.fd(),
808-
guard: unsafe { self.inner.lock.lock() },
808+
guard: self.inner.lock.lock(),
809809
};
810810
assert!(set_nonblocking(self.fd(), true).is_ok());
811811
ret

0 commit comments

Comments
 (0)