summaryrefslogtreecommitdiffstats
path: root/third_party/rust/crossbeam-channel/examples
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/rust/crossbeam-channel/examples')
-rw-r--r--third_party/rust/crossbeam-channel/examples/fibonacci.rs25
-rw-r--r--third_party/rust/crossbeam-channel/examples/matching.rs72
-rw-r--r--third_party/rust/crossbeam-channel/examples/stopwatch.rs56
3 files changed, 153 insertions, 0 deletions
diff --git a/third_party/rust/crossbeam-channel/examples/fibonacci.rs b/third_party/rust/crossbeam-channel/examples/fibonacci.rs
new file mode 100644
index 0000000000..e6f5e89c04
--- /dev/null
+++ b/third_party/rust/crossbeam-channel/examples/fibonacci.rs
@@ -0,0 +1,25 @@
+//! An asynchronous fibonacci sequence generator.
+
+use std::thread;
+
+use crossbeam_channel::{bounded, Sender};
+
+// Sends the Fibonacci sequence into the channel until it becomes disconnected.
+fn fibonacci(sender: Sender<u64>) {
+ let (mut x, mut y) = (0, 1);
+ while sender.send(x).is_ok() {
+ let tmp = x;
+ x = y;
+ y += tmp;
+ }
+}
+
+fn main() {
+ let (s, r) = bounded(0);
+ thread::spawn(|| fibonacci(s));
+
+ // Print the first 20 Fibonacci numbers.
+ for num in r.iter().take(20) {
+ println!("{}", num);
+ }
+}
diff --git a/third_party/rust/crossbeam-channel/examples/matching.rs b/third_party/rust/crossbeam-channel/examples/matching.rs
new file mode 100644
index 0000000000..5421169b9d
--- /dev/null
+++ b/third_party/rust/crossbeam-channel/examples/matching.rs
@@ -0,0 +1,72 @@
+//! Using `select!` to send and receive on the same channel at the same time.
+//!
+//! This example is based on the following program in Go.
+//!
+//! Source:
+//! - https://web.archive.org/web/20171209034309/https://www.nada.kth.se/~snilsson/concurrency
+//! - http://www.nada.kth.se/~snilsson/concurrency/src/matching.go
+//!
+//! Copyright & License:
+//! - Stefan Nilsson
+//! - Creative Commons Attribution 3.0 Unported License
+//! - https://creativecommons.org/licenses/by/3.0/
+//!
+//! ```go
+//! func main() {
+//! people := []string{"Anna", "Bob", "Cody", "Dave", "Eva"}
+//! match := make(chan string, 1) // Make room for one unmatched send.
+//! wg := new(sync.WaitGroup)
+//! for _, name := range people {
+//! wg.Add(1)
+//! go Seek(name, match, wg)
+//! }
+//! wg.Wait()
+//! select {
+//! case name := <-match:
+//! fmt.Printf("No one received %s’s message.\n", name)
+//! default:
+//! // There was no pending send operation.
+//! }
+//! }
+//!
+//! // Seek either sends or receives, whichever possible, a name on the match
+//! // channel and notifies the wait group when done.
+//! func Seek(name string, match chan string, wg *sync.WaitGroup) {
+//! select {
+//! case peer := <-match:
+//! fmt.Printf("%s received a message from %s.\n", name, peer)
+//! case match <- name:
+//! // Wait for someone to receive my message.
+//! }
+//! wg.Done()
+//! }
+//! ```
+
+use crossbeam_channel::{bounded, select};
+use crossbeam_utils::thread;
+
+fn main() {
+ let people = vec!["Anna", "Bob", "Cody", "Dave", "Eva"];
+ let (s, r) = bounded(1); // Make room for one unmatched send.
+
+ // Either send my name into the channel or receive someone else's, whatever happens first.
+ let seek = |name, s, r| {
+ select! {
+ recv(r) -> peer => println!("{} received a message from {}.", name, peer.unwrap()),
+ send(s, name) -> _ => {}, // Wait for someone to receive my message.
+ }
+ };
+
+ thread::scope(|scope| {
+ for name in people {
+ let (s, r) = (s.clone(), r.clone());
+ scope.spawn(move |_| seek(name, s, r));
+ }
+ })
+ .unwrap();
+
+ // Check if there is a pending send operation.
+ if let Ok(name) = r.try_recv() {
+ println!("No one received {}’s message.", name);
+ }
+}
diff --git a/third_party/rust/crossbeam-channel/examples/stopwatch.rs b/third_party/rust/crossbeam-channel/examples/stopwatch.rs
new file mode 100644
index 0000000000..3a7578e00d
--- /dev/null
+++ b/third_party/rust/crossbeam-channel/examples/stopwatch.rs
@@ -0,0 +1,56 @@
+//! Prints the elapsed time every 1 second and quits on Ctrl+C.
+
+#[cfg(windows)] // signal_hook::iterator does not work on windows
+fn main() {
+ println!("This example does not work on Windows");
+}
+
+#[cfg(not(windows))]
+fn main() {
+ use std::io;
+ use std::thread;
+ use std::time::{Duration, Instant};
+
+ use crossbeam_channel::{bounded, select, tick, Receiver};
+ use signal_hook::consts::SIGINT;
+ use signal_hook::iterator::Signals;
+
+ // Creates a channel that gets a message every time `SIGINT` is signalled.
+ fn sigint_notifier() -> io::Result<Receiver<()>> {
+ let (s, r) = bounded(100);
+ let mut signals = Signals::new(&[SIGINT])?;
+
+ thread::spawn(move || {
+ for _ in signals.forever() {
+ if s.send(()).is_err() {
+ break;
+ }
+ }
+ });
+
+ Ok(r)
+ }
+
+ // Prints the elapsed time.
+ fn show(dur: Duration) {
+ println!("Elapsed: {}.{:03} sec", dur.as_secs(), dur.subsec_millis());
+ }
+
+ let start = Instant::now();
+ let update = tick(Duration::from_secs(1));
+ let ctrl_c = sigint_notifier().unwrap();
+
+ loop {
+ select! {
+ recv(update) -> _ => {
+ show(start.elapsed());
+ }
+ recv(ctrl_c) -> _ => {
+ println!();
+ println!("Goodbye!");
+ show(start.elapsed());
+ break;
+ }
+ }
+ }
+}