about summary refs log tree commit diff
path: root/src/libstd/sync/mpsc/blocking.rs
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-01-02 09:15:54 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-01-02 09:15:54 -0800
commit8b7d032014ccbc9256abdc56e633e7c0a3b8342c (patch)
treef411361a5fa24c4ccacbd0acb5b839c526244e04 /src/libstd/sync/mpsc/blocking.rs
parent5696ea58946f077f815dc5f74b883cf948c7e1ea (diff)
parentbc83a009f655dd3896be4a7cd33cac8032a605f2 (diff)
downloadrust-8b7d032014ccbc9256abdc56e633e7c0a3b8342c.tar.gz
rust-8b7d032014ccbc9256abdc56e633e7c0a3b8342c.zip
rollup merge of #20273: alexcrichton/second-pass-comm
Conflicts:
	src/doc/guide.md
	src/libcollections/bit.rs
	src/libcollections/btree/node.rs
	src/libcollections/slice.rs
	src/libcore/ops.rs
	src/libcore/prelude.rs
	src/librand/rand_impls.rs
	src/librustc/middle/check_match.rs
	src/librustc/middle/infer/region_inference/mod.rs
	src/librustc_driver/lib.rs
	src/librustdoc/test.rs
	src/libstd/bitflags.rs
	src/libstd/io/comm_adapters.rs
	src/libstd/io/mem.rs
	src/libstd/io/mod.rs
	src/libstd/io/net/pipe.rs
	src/libstd/io/net/tcp.rs
	src/libstd/io/net/udp.rs
	src/libstd/io/pipe.rs
	src/libstd/io/process.rs
	src/libstd/io/stdio.rs
	src/libstd/io/timer.rs
	src/libstd/io/util.rs
	src/libstd/macros.rs
	src/libstd/os.rs
	src/libstd/path/posix.rs
	src/libstd/path/windows.rs
	src/libstd/prelude/v1.rs
	src/libstd/rand/mod.rs
	src/libstd/rand/os.rs
	src/libstd/sync/barrier.rs
	src/libstd/sync/condvar.rs
	src/libstd/sync/future.rs
	src/libstd/sync/mpsc/mod.rs
	src/libstd/sync/mpsc/mpsc_queue.rs
	src/libstd/sync/mpsc/select.rs
	src/libstd/sync/mpsc/spsc_queue.rs
	src/libstd/sync/mutex.rs
	src/libstd/sync/once.rs
	src/libstd/sync/rwlock.rs
	src/libstd/sync/semaphore.rs
	src/libstd/sync/task_pool.rs
	src/libstd/sys/common/helper_thread.rs
	src/libstd/sys/unix/process.rs
	src/libstd/sys/unix/timer.rs
	src/libstd/sys/windows/c.rs
	src/libstd/sys/windows/timer.rs
	src/libstd/sys/windows/tty.rs
	src/libstd/thread.rs
	src/libstd/thread_local/mod.rs
	src/libstd/thread_local/scoped.rs
	src/libtest/lib.rs
	src/test/auxiliary/cci_capture_clause.rs
	src/test/bench/shootout-reverse-complement.rs
	src/test/bench/shootout-spectralnorm.rs
	src/test/compile-fail/array-old-syntax-2.rs
	src/test/compile-fail/bind-by-move-no-guards.rs
	src/test/compile-fail/builtin-superkinds-self-type.rs
	src/test/compile-fail/comm-not-freeze-receiver.rs
	src/test/compile-fail/comm-not-freeze.rs
	src/test/compile-fail/issue-12041.rs
	src/test/compile-fail/unsendable-class.rs
	src/test/run-pass/builtin-superkinds-capabilities-transitive.rs
	src/test/run-pass/builtin-superkinds-capabilities-xc.rs
	src/test/run-pass/builtin-superkinds-capabilities.rs
	src/test/run-pass/builtin-superkinds-self-type.rs
	src/test/run-pass/capturing-logging.rs
	src/test/run-pass/closure-bounds-can-capture-chan.rs
	src/test/run-pass/comm.rs
	src/test/run-pass/core-run-destroy.rs
	src/test/run-pass/drop-trait-enum.rs
	src/test/run-pass/hashmap-memory.rs
	src/test/run-pass/issue-13494.rs
	src/test/run-pass/issue-3609.rs
	src/test/run-pass/issue-4446.rs
	src/test/run-pass/issue-4448.rs
	src/test/run-pass/issue-8827.rs
	src/test/run-pass/issue-9396.rs
	src/test/run-pass/ivec-tag.rs
	src/test/run-pass/rust-log-filter.rs
	src/test/run-pass/send-resource.rs
	src/test/run-pass/send-type-inference.rs
	src/test/run-pass/sendable-class.rs
	src/test/run-pass/spawn-types.rs
	src/test/run-pass/task-comm-0.rs
	src/test/run-pass/task-comm-10.rs
	src/test/run-pass/task-comm-11.rs
	src/test/run-pass/task-comm-13.rs
	src/test/run-pass/task-comm-14.rs
	src/test/run-pass/task-comm-15.rs
	src/test/run-pass/task-comm-16.rs
	src/test/run-pass/task-comm-3.rs
	src/test/run-pass/task-comm-4.rs
	src/test/run-pass/task-comm-5.rs
	src/test/run-pass/task-comm-6.rs
	src/test/run-pass/task-comm-7.rs
	src/test/run-pass/task-comm-9.rs
	src/test/run-pass/task-comm-chan-nil.rs
	src/test/run-pass/task-spawn-move-and-copy.rs
	src/test/run-pass/task-stderr.rs
	src/test/run-pass/tcp-accept-stress.rs
	src/test/run-pass/tcp-connect-timeouts.rs
	src/test/run-pass/tempfile.rs
	src/test/run-pass/trait-bounds-in-arc.rs
	src/test/run-pass/trivial-message.rs
	src/test/run-pass/unique-send-2.rs
	src/test/run-pass/unique-send.rs
	src/test/run-pass/unwind-resource.rs
Diffstat (limited to 'src/libstd/sync/mpsc/blocking.rs')
-rw-r--r--src/libstd/sync/mpsc/blocking.rs87
1 files changed, 87 insertions, 0 deletions
diff --git a/src/libstd/sync/mpsc/blocking.rs b/src/libstd/sync/mpsc/blocking.rs
new file mode 100644
index 00000000000..412b7161305
--- /dev/null
+++ b/src/libstd/sync/mpsc/blocking.rs
@@ -0,0 +1,87 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! Generic support for building blocking abstractions.
+
+use thread::Thread;
+use sync::atomic::{AtomicBool, INIT_ATOMIC_BOOL, Ordering};
+use sync::Arc;
+use kinds::{Sync, Send};
+use kinds::marker::{NoSend, NoSync};
+use mem;
+use clone::Clone;
+
+struct Inner {
+    thread: Thread,
+    woken: AtomicBool,
+}
+
+unsafe impl Send for Inner {}
+unsafe impl Sync for Inner {}
+
+#[deriving(Clone)]
+pub struct SignalToken {
+    inner: Arc<Inner>,
+}
+
+pub struct WaitToken {
+    inner: Arc<Inner>,
+    no_send: NoSend,
+    no_sync: NoSync,
+}
+
+pub fn tokens() -> (WaitToken, SignalToken) {
+    let inner = Arc::new(Inner {
+        thread: Thread::current(),
+        woken: INIT_ATOMIC_BOOL,
+    });
+    let wait_token = WaitToken {
+        inner: inner.clone(),
+        no_send: NoSend,
+        no_sync: NoSync,
+    };
+    let signal_token = SignalToken {
+        inner: inner
+    };
+    (wait_token, signal_token)
+}
+
+impl SignalToken {
+    pub fn signal(&self) -> bool {
+        let wake = !self.inner.woken.compare_and_swap(false, true, Ordering::SeqCst);
+        if wake {
+            self.inner.thread.unpark();
+        }
+        wake
+    }
+
+    /// Convert to an unsafe uint value. Useful for storing in a pipe's state
+    /// flag.
+    #[inline]
+    pub unsafe fn cast_to_uint(self) -> uint {
+        mem::transmute(self.inner)
+    }
+
+    /// Convert from an unsafe uint value. Useful for retrieving a pipe's state
+    /// flag.
+    #[inline]
+    pub unsafe fn cast_from_uint(signal_ptr: uint) -> SignalToken {
+        SignalToken { inner: mem::transmute(signal_ptr) }
+    }
+
+}
+
+impl WaitToken {
+    pub fn wait(self) {
+        while !self.inner.woken.load(Ordering::SeqCst) {
+            Thread::park()
+        }
+    }
+}