Skip to content

Commit 2ba36ec

Browse files
committed
auto merge of #8327 : sstewartgallus/rust/factor_out_waitqueue, r=bblum
I'm a bit disappointed that I couldn't figure out how to factor out more of the code implementing `extra::sync` but I feel this is an okay start. Also I added some documentation explaining that `WaitQueue` isn't thread safe, and needs an exclusive lock. @bblum
2 parents e70aac5 + 1e576a3 commit 2ba36ec

File tree

1 file changed

+13
-13
lines changed

1 file changed

+13
-13
lines changed

src/libextra/sync.rs

+13-13
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,12 @@ impl WaitQueue {
7272
}
7373
count
7474
}
75+
76+
fn wait_end(&self) -> WaitEnd {
77+
let (wait_end, signal_end) = comm::oneshot();
78+
self.tail.send_deferred(signal_end);
79+
wait_end
80+
}
7581
}
7682

7783
// The building-block used to make semaphores, mutexes, and rwlocks.
@@ -100,12 +106,9 @@ impl<Q:Send> Sem<Q> {
100106
do (**self).with |state| {
101107
state.count -= 1;
102108
if state.count < 0 {
103-
// Create waiter nobe.
104-
let (WaitEnd, SignalEnd) = comm::oneshot();
105-
// Tell outer scope we need to block.
106-
waiter_nobe = Some(WaitEnd);
107-
// Enqueue ourself.
108-
state.waiters.tail.send_deferred(SignalEnd);
109+
// Create waiter nobe, enqueue ourself, and tell
110+
// outer scope we need to block.
111+
waiter_nobe = Some(state.waiters.wait_end());
109112
}
110113
}
111114
// Uncomment if you wish to test for sem races. Not valgrind-friendly.
@@ -201,10 +204,7 @@ impl<'self> Condvar<'self> {
201204
* wait() is equivalent to wait_on(0).
202205
*/
203206
pub fn wait_on(&self, condvar_id: uint) {
204-
// Create waiter nobe.
205-
let (WaitEnd, SignalEnd) = comm::oneshot();
206-
let mut WaitEnd = Some(WaitEnd);
207-
let mut SignalEnd = Some(SignalEnd);
207+
let mut WaitEnd = None;
208208
let mut out_of_bounds = None;
209209
do task::unkillable {
210210
// Release lock, 'atomically' enqueuing ourselves in so doing.
@@ -216,9 +216,9 @@ impl<'self> Condvar<'self> {
216216
if state.count <= 0 {
217217
state.waiters.signal();
218218
}
219-
// Enqueue ourself to be woken up by a signaller.
220-
let SignalEnd = SignalEnd.take_unwrap();
221-
state.blocked[condvar_id].tail.send_deferred(SignalEnd);
219+
// Create waiter nobe, and enqueue ourself to
220+
// be woken up by a signaller.
221+
WaitEnd = Some(state.blocked[condvar_id].wait_end());
222222
} else {
223223
out_of_bounds = Some(state.blocked.len());
224224
}

0 commit comments

Comments
 (0)