Skip to content

Commit 9326e21

Browse files
committed
---
yaml --- r: 206316 b: refs/heads/beta c: 5c8ca26 h: refs/heads/master v: v3
1 parent ff9bac8 commit 9326e21

File tree

2 files changed

+25
-3
lines changed

2 files changed

+25
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ refs/tags/0.12.0: f0c419429ef30723ceaf6b42f9b5a2aeb5d2e2d1
2929
refs/heads/automation-fail: 1bf06495443584539b958873e04cc2f864ab10e4
3030
refs/heads/batch: b7fd822592a4fb577552d93010c4a4e14f314346
3131
refs/heads/building: 126db549b038c84269a1e4fe46f051b2c15d6970
32-
refs/heads/beta: 4288a08e9a640e2b24d2f5974f6785f0ab82694b
32+
refs/heads/beta: 5c8ca26ad7fd6bbe0e7d4f5ddc10a891b2e74512
3333
refs/heads/windistfix: 7608dbad651f02e837ed05eef3d74a6662a6e928
3434
refs/tags/1.0.0-alpha: e42bd6d93a1d3433c486200587f8f9e12590a4d7
3535
refs/heads/tmp: 579e31929feff51dcaf8d444648eff8de735f91a

branches/beta/src/libstd/sys/unix/rwlock.rs

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
use prelude::v1::*;
1212

13+
use libc;
1314
use cell::UnsafeCell;
1415
use sys::sync as ffi;
1516

@@ -26,7 +27,23 @@ impl RWLock {
2627
#[inline]
2728
pub unsafe fn read(&self) {
2829
let r = ffi::pthread_rwlock_rdlock(self.inner.get());
29-
debug_assert_eq!(r, 0);
30+
31+
// According to the pthread_rwlock_rdlock spec, this function **may**
32+
// fail with EDEADLK if a deadlock is detected. On the other hand
33+
// pthread mutexes will *never* return EDEADLK if they are initialized
34+
// as the "fast" kind (which ours always are). As a result, a deadlock
35+
// situation may actually return from the call to pthread_rwlock_rdlock
36+
// instead of blocking forever (as mutexes and Windows rwlocks do). Note
37+
// that not all unix implementations, however, will return EDEADLK for
38+
// their rwlocks.
39+
//
40+
// We roughly maintain the deadlocking behavior by panicking to ensure
41+
// that this lock acquisition does not succeed.
42+
if r == libc::EDEADLK {
43+
panic!("rwlock read lock would result in deadlock");
44+
} else {
45+
debug_assert_eq!(r, 0);
46+
}
3047
}
3148
#[inline]
3249
pub unsafe fn try_read(&self) -> bool {
@@ -35,7 +52,12 @@ impl RWLock {
3552
#[inline]
3653
pub unsafe fn write(&self) {
3754
let r = ffi::pthread_rwlock_wrlock(self.inner.get());
38-
debug_assert_eq!(r, 0);
55+
// see comments above for why we check for EDEADLK
56+
if r == libc::EDEADLK {
57+
panic!("rwlock write lock would result in deadlock");
58+
} else {
59+
debug_assert_eq!(r, 0);
60+
}
3961
}
4062
#[inline]
4163
pub unsafe fn try_write(&self) -> bool {

0 commit comments

Comments
 (0)