1 // Copyright 2014 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
11 //! Generic support for building blocking abstractions.
14 use sync::atomic::{AtomicBool, ATOMIC_BOOL_INIT, Ordering};
16 use marker::{Sync, Send};
17 use marker::{NoSend, NoSync};
26 unsafe impl Send for Inner {}
27 unsafe impl Sync for Inner {}
30 pub struct SignalToken {
34 pub struct WaitToken {
40 pub fn tokens() -> (WaitToken, SignalToken) {
41 let inner = Arc::new(Inner {
42 thread: Thread::current(),
43 woken: ATOMIC_BOOL_INIT,
45 let wait_token = WaitToken {
50 let signal_token = SignalToken {
53 (wait_token, signal_token)
57 pub fn signal(&self) -> bool {
58 let wake = !self.inner.woken.compare_and_swap(false, true, Ordering::SeqCst);
60 self.inner.thread.unpark();
65 /// Convert to an unsafe uint value. Useful for storing in a pipe's state
68 pub unsafe fn cast_to_uint(self) -> uint {
69 mem::transmute(self.inner)
72 /// Convert from an unsafe uint value. Useful for retrieving a pipe's state
75 pub unsafe fn cast_from_uint(signal_ptr: uint) -> SignalToken {
76 SignalToken { inner: mem::transmute(signal_ptr) }
83 while !self.inner.woken.load(Ordering::SeqCst) {