Skip to content

Commit 74ece79

Browse files
committed
---
yaml --- r: 152499 b: refs/heads/try2 c: ac7b9dd h: refs/heads/master i: 152497: 1ccbb88 152495: a9dabad v: v3
1 parent af1d5fb commit 74ece79

File tree

4 files changed

+88
-5
lines changed

4 files changed

+88
-5
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ refs/heads/snap-stage3: 78a7676898d9f80ab540c6df5d4c9ce35bb50463
55
refs/heads/try: 519addf6277dbafccbb4159db4b710c37eaa2ec5
66
refs/tags/release-0.1: 1f5c5126e96c79d22cb7862f75304136e204f105
77
refs/heads/ndm: f3868061cd7988080c30d6d5bf352a5a5fe2460b
8-
refs/heads/try2: b612ae9edea26cb8704363c47a66d583b644ad09
8+
refs/heads/try2: ac7b9ddc545b7f62f00bf8f4d490d31ff4b90d1d
99
refs/heads/dist-snap: ba4081a5a8573875fed17545846f6f6902c8ba8d
1010
refs/tags/release-0.2: c870d2dffb391e14efb05aa27898f1f6333a9596
1111
refs/tags/release-0.3: b5f0d0f648d9a6153664837026ba1be43d3e2503

branches/try2/src/librustrt/mutex.rs

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,18 @@ impl StaticNativeMutex {
115115
/// // critical section...
116116
/// } // automatically unlocked in `_guard`'s destructor
117117
/// ```
118+
///
119+
/// # Unsafety
120+
///
121+
/// This method is unsafe because it will not function correctly if this
122+
/// mutex has been *moved* since it was last used. The mutex can move an
123+
/// arbitrary number of times before its first usage, but once a mutex has
124+
/// been used once it is no longer allowed to move (or otherwise it invokes
125+
/// undefined behavior).
126+
///
127+
/// Additionally, this type does not take into account any form of
128+
/// scheduling model. This will unconditionally block the *os thread* which
129+
/// is not always desired.
118130
pub unsafe fn lock<'a>(&'a self) -> LockGuard<'a> {
119131
self.inner.lock();
120132

@@ -123,6 +135,10 @@ impl StaticNativeMutex {
123135

124136
/// Attempts to acquire the lock. The value returned is `Some` if
125137
/// the attempt succeeded.
138+
///
139+
/// # Unsafety
140+
///
141+
/// This method is unsafe for the same reasons as `lock`.
126142
pub unsafe fn trylock<'a>(&'a self) -> Option<LockGuard<'a>> {
127143
if self.inner.trylock() {
128144
Some(LockGuard { lock: self })
@@ -135,6 +151,12 @@ impl StaticNativeMutex {
135151
///
136152
/// These needs to be paired with a call to `.unlock_noguard`. Prefer using
137153
/// `.lock`.
154+
///
155+
/// # Unsafety
156+
///
157+
/// This method is unsafe for the same reasons as `lock`. Additionally, this
158+
/// does not guarantee that the mutex will ever be unlocked, and it is
159+
/// undefined to drop an already-locked mutex.
138160
pub unsafe fn lock_noguard(&self) { self.inner.lock() }
139161

140162
/// Attempts to acquire the lock without creating a
@@ -143,22 +165,42 @@ impl StaticNativeMutex {
143165
///
144166
/// If `true` is returned, this needs to be paired with a call to
145167
/// `.unlock_noguard`. Prefer using `.trylock`.
168+
///
169+
/// # Unsafety
170+
///
171+
/// This method is unsafe for the same reasons as `lock_noguard`.
146172
pub unsafe fn trylock_noguard(&self) -> bool {
147173
self.inner.trylock()
148174
}
149175

150176
/// Unlocks the lock. This assumes that the current thread already holds the
151177
/// lock.
178+
///
179+
/// # Unsafety
180+
///
181+
/// This method is unsafe for the same reasons as `lock`. Additionally, it
182+
/// is not guaranteed that this is unlocking a previously locked mutex. It
183+
/// is undefined to unlock an unlocked mutex.
152184
pub unsafe fn unlock_noguard(&self) { self.inner.unlock() }
153185

154186
/// Block on the internal condition variable.
155187
///
156188
/// This function assumes that the lock is already held. Prefer
157189
/// using `LockGuard.wait` since that guarantees that the lock is
158190
/// held.
191+
///
192+
/// # Unsafety
193+
///
194+
/// This method is unsafe for the same reasons as `lock`. Additionally, this
195+
/// is unsafe because the mutex may not be currently locked.
159196
pub unsafe fn wait_noguard(&self) { self.inner.wait() }
160197

161198
/// Signals a thread in `wait` to wake up
199+
///
200+
/// # Unsafety
201+
///
202+
/// This method is unsafe for the same reasons as `lock`. Additionally, this
203+
/// is unsafe because the mutex may not be currently locked.
162204
pub unsafe fn signal_noguard(&self) { self.inner.signal() }
163205

164206
/// This function is especially unsafe because there are no guarantees made
@@ -181,6 +223,7 @@ impl NativeMutex {
181223
/// already hold the lock.
182224
///
183225
/// # Example
226+
///
184227
/// ```rust
185228
/// use std::rt::mutex::NativeMutex;
186229
/// unsafe {
@@ -192,12 +235,22 @@ impl NativeMutex {
192235
/// } // automatically unlocked in `_guard`'s destructor
193236
/// }
194237
/// ```
238+
///
239+
/// # Unsafety
240+
///
241+
/// This method is unsafe due to the same reasons as
242+
/// `StaticNativeMutex::lock`.
195243
pub unsafe fn lock<'a>(&'a self) -> LockGuard<'a> {
196244
self.inner.lock()
197245
}
198246

199247
/// Attempts to acquire the lock. The value returned is `Some` if
200248
/// the attempt succeeded.
249+
///
250+
/// # Unsafety
251+
///
252+
/// This method is unsafe due to the same reasons as
253+
/// `StaticNativeMutex::trylock`.
201254
pub unsafe fn trylock<'a>(&'a self) -> Option<LockGuard<'a>> {
202255
self.inner.trylock()
203256
}
@@ -206,6 +259,11 @@ impl NativeMutex {
206259
///
207260
/// These needs to be paired with a call to `.unlock_noguard`. Prefer using
208261
/// `.lock`.
262+
///
263+
/// # Unsafety
264+
///
265+
/// This method is unsafe due to the same reasons as
266+
/// `StaticNativeMutex::lock_noguard`.
209267
pub unsafe fn lock_noguard(&self) { self.inner.lock_noguard() }
210268

211269
/// Attempts to acquire the lock without creating a
@@ -214,22 +272,42 @@ impl NativeMutex {
214272
///
215273
/// If `true` is returned, this needs to be paired with a call to
216274
/// `.unlock_noguard`. Prefer using `.trylock`.
275+
///
276+
/// # Unsafety
277+
///
278+
/// This method is unsafe due to the same reasons as
279+
/// `StaticNativeMutex::trylock_noguard`.
217280
pub unsafe fn trylock_noguard(&self) -> bool {
218281
self.inner.trylock_noguard()
219282
}
220283

221284
/// Unlocks the lock. This assumes that the current thread already holds the
222285
/// lock.
286+
///
287+
/// # Unsafety
288+
///
289+
/// This method is unsafe due to the same reasons as
290+
/// `StaticNativeMutex::unlock_noguard`.
223291
pub unsafe fn unlock_noguard(&self) { self.inner.unlock_noguard() }
224292

225293
/// Block on the internal condition variable.
226294
///
227295
/// This function assumes that the lock is already held. Prefer
228296
/// using `LockGuard.wait` since that guarantees that the lock is
229297
/// held.
298+
///
299+
/// # Unsafety
300+
///
301+
/// This method is unsafe due to the same reasons as
302+
/// `StaticNativeMutex::wait_noguard`.
230303
pub unsafe fn wait_noguard(&self) { self.inner.wait_noguard() }
231304

232305
/// Signals a thread in `wait` to wake up
306+
///
307+
/// # Unsafety
308+
///
309+
/// This method is unsafe due to the same reasons as
310+
/// `StaticNativeMutex::signal_noguard`.
233311
pub unsafe fn signal_noguard(&self) { self.inner.signal_noguard() }
234312
}
235313

branches/try2/src/librustrt/unwind.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ use libc::c_void;
7373

7474
use local::Local;
7575
use task::{Task, Result};
76-
use exclusive::Exclusive;
7776

7877
use uw = libunwind;
7978

@@ -88,7 +87,6 @@ struct Exception {
8887
}
8988

9089
pub type Callback = fn(msg: &Any:Send, file: &'static str, line: uint);
91-
type Queue = Exclusive<Vec<Callback>>;
9290

9391
// Variables used for invoking callbacks when a task starts to unwind.
9492
//

branches/try2/src/libsync/mutex.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,14 @@ pub static NATIVE_BLOCKED: uint = 1 << 2;
9797
/// drop(guard); // unlock the lock
9898
/// ```
9999
pub struct Mutex {
100-
lock: StaticMutex,
100+
// Note that this static mutex is in a *box*, not inlined into the struct
101+
// itself. This is done for memory safety reasons with the usage of a
102+
// StaticNativeMutex inside the static mutex above. Once a native mutex has
103+
// been used once, its address can never change (it can't be moved). This
104+
// mutex type can be safely moved at any time, so to ensure that the native
105+
// mutex is used correctly we box the inner lock to give it a constant
106+
// address.
107+
lock: Box<StaticMutex>,
101108
}
102109

103110
#[deriving(PartialEq, Show)]
@@ -458,7 +465,7 @@ impl Mutex {
458465
/// Creates a new mutex in an unlocked state ready for use.
459466
pub fn new() -> Mutex {
460467
Mutex {
461-
lock: StaticMutex {
468+
lock: box StaticMutex {
462469
state: atomics::AtomicUint::new(0),
463470
flavor: Unsafe::new(Unlocked),
464471
green_blocker: Unsafe::new(0),

0 commit comments

Comments
 (0)