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};
25 unsafe impl Send for Inner {}
26 unsafe impl Sync for Inner {}
29 pub struct SignalToken {
33 pub struct WaitToken {
37 impl !Send for WaitToken {}
39 impl !Sync for WaitToken {}
41 pub fn tokens() -> (WaitToken, SignalToken) {
42 let inner = Arc::new(Inner {
43 thread: Thread::current(),
44 woken: ATOMIC_BOOL_INIT,
46 let wait_token = WaitToken {
49 let signal_token = SignalToken {
52 (wait_token, signal_token)
56 pub fn signal(&self) -> bool {
57 let wake = !self.inner.woken.compare_and_swap(false, true, Ordering::SeqCst);
59 self.inner.thread.unpark();
64 /// Convert to an unsafe uint value. Useful for storing in a pipe's state
67 pub unsafe fn cast_to_uint(self) -> uint {
68 mem::transmute(self.inner)
71 /// Convert from an unsafe uint value. Useful for retrieving a pipe's state
74 pub unsafe fn cast_from_uint(signal_ptr: uint) -> SignalToken {
75 SignalToken { inner: mem::transmute(signal_ptr) }
82 while !self.inner.woken.load(Ordering::SeqCst) {