This crate allows you to store a value that you can later take out atomically. As this crate uses atomics, no locking is involved in taking the value out.
As an example, you could store the [Sender
] of an oneshot channel in an
[AtomicTake
], which would allow you to notify the first time a closure is called.
```rust use atomic_take::AtomicTake; use futures::sync::oneshot;
let (send, mut recv) = oneshot::channel();
let take = AtomicTake::new(send); let closure = move || { if let Some(send) = take.take() { // Notify the first time this closure is called. send.send(()).unwrap(); } };
closure(); asserteq!(recv.tryrecv().unwrap(), Some(()));
closure(); // This does nothing. ```
Additionally the closure above can be called concurrently from many threads. For
example, if you put the AtomicTake
in an [Arc
], you can share it between several
threads and receive a message from the first thread to run.
```rust use std::thread; use std::sync::Arc; use atomic_take::AtomicTake; use futures::sync::oneshot;
let (send, mut recv) = oneshot::channel();
// Use an Arc to share the AtomicTake between several threads. let take = Arc::new(AtomicTake::new(send));
// Spawn three threads and try to send a message from each. let mut handles = Vec::new(); for i in 0..3 { let takeclone = Arc::clone(&take); let joinhandle = thread::spawn(move || {
// Check if this thread is first and send a message if so.
if let Some(send) = take_clone.take() {
// Send the index of the thread.
send.send(i).unwrap();
}
});
handles.push(join_handle);
} // Wait for all three threads to finish. for handle in handles { handle.join().unwrap(); }
// After all the threads finished, try to send again. if let Some(send) = take.take() { // This will definitely not happen. send.send(100).unwrap(); }
// Confirm that one of the first three threads got to send the message first. assert!(recv.try_recv().unwrap().unwrap() < 3); ```
This crate does not require the standard library.