diff options
Diffstat (limited to 'third_party/rust/crossbeam-channel/examples/matching.rs')
-rw-r--r-- | third_party/rust/crossbeam-channel/examples/matching.rs | 72 |
1 files changed, 72 insertions, 0 deletions
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); + } +} |