diff options
| author | bors <bors@rust-lang.org> | 2013-08-10 07:47:14 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-08-10 07:47:14 -0700 |
| commit | 2ba36ec62934c8b877766a6283633b6407c8d357 (patch) | |
| tree | 04185bd1ac2556cb5d97e87667164e28435d259a | |
| parent | e70aac572ac9dd6e1b8f7f434e77c602c1fa0d0e (diff) | |
| parent | 1e576a35eb7e1eeb2c4a2d0c03955490337891c1 (diff) | |
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
| -rw-r--r-- | src/libextra/sync.rs | 26 |
1 files changed, 13 insertions, 13 deletions
diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index f2a9914cc91..756a5c7da00 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -72,6 +72,12 @@ impl WaitQueue { } count } + + fn wait_end(&self) -> WaitEnd { + let (wait_end, signal_end) = comm::oneshot(); + self.tail.send_deferred(signal_end); + wait_end + } } // The building-block used to make semaphores, mutexes, and rwlocks. @@ -100,12 +106,9 @@ impl<Q:Send> Sem<Q> { do (**self).with |state| { state.count -= 1; if state.count < 0 { - // Create waiter nobe. - let (WaitEnd, SignalEnd) = comm::oneshot(); - // Tell outer scope we need to block. - waiter_nobe = Some(WaitEnd); - // Enqueue ourself. - state.waiters.tail.send_deferred(SignalEnd); + // Create waiter nobe, enqueue ourself, and tell + // outer scope we need to block. + waiter_nobe = Some(state.waiters.wait_end()); } } // Uncomment if you wish to test for sem races. Not valgrind-friendly. @@ -201,10 +204,7 @@ impl<'self> Condvar<'self> { * wait() is equivalent to wait_on(0). */ pub fn wait_on(&self, condvar_id: uint) { - // Create waiter nobe. - let (WaitEnd, SignalEnd) = comm::oneshot(); - let mut WaitEnd = Some(WaitEnd); - let mut SignalEnd = Some(SignalEnd); + let mut WaitEnd = None; let mut out_of_bounds = None; do task::unkillable { // Release lock, 'atomically' enqueuing ourselves in so doing. @@ -216,9 +216,9 @@ impl<'self> Condvar<'self> { if state.count <= 0 { state.waiters.signal(); } - // Enqueue ourself to be woken up by a signaller. - let SignalEnd = SignalEnd.take_unwrap(); - state.blocked[condvar_id].tail.send_deferred(SignalEnd); + // Create waiter nobe, and enqueue ourself to + // be woken up by a signaller. + WaitEnd = Some(state.blocked[condvar_id].wait_end()); } else { out_of_bounds = Some(state.blocked.len()); } |
