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 #[cfg(stage0)] // NOTE remove use after next snapshot
18 use marker::{NoSend, NoSync};
27 unsafe impl Send for Inner {}
28 unsafe impl Sync for Inner {}
31 pub struct SignalToken {
35 #[cfg(stage0)] // NOTE remove impl after next snapshot
36 pub struct WaitToken {
42 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
43 pub struct WaitToken {
47 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
48 impl !Send for WaitToken {}
50 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
51 impl !Sync for WaitToken {}
53 #[cfg(stage0)] // NOTE remove impl after next snapshot
54 pub fn tokens() -> (WaitToken, SignalToken) {
55 let inner = Arc::new(Inner {
56 thread: Thread::current(),
57 woken: ATOMIC_BOOL_INIT,
59 let wait_token = WaitToken {
64 let signal_token = SignalToken {
67 (wait_token, signal_token)
70 #[cfg(not(stage0))] // NOTE remove cfg after next snapshot
71 pub fn tokens() -> (WaitToken, SignalToken) {
72 let inner = Arc::new(Inner {
73 thread: Thread::current(),
74 woken: ATOMIC_BOOL_INIT,
76 let wait_token = WaitToken {
79 let signal_token = SignalToken {
82 (wait_token, signal_token)
86 pub fn signal(&self) -> bool {
87 let wake = !self.inner.woken.compare_and_swap(false, true, Ordering::SeqCst);
89 self.inner.thread.unpark();
94 /// Convert to an unsafe uint value. Useful for storing in a pipe's state
97 pub unsafe fn cast_to_uint(self) -> uint {
98 mem::transmute(self.inner)
101 /// Convert from an unsafe uint value. Useful for retrieving a pipe's state
104 pub unsafe fn cast_from_uint(signal_ptr: uint) -> SignalToken {
105 SignalToken { inner: mem::transmute(signal_ptr) }
112 while !self.inner.woken.load(Ordering::SeqCst) {