Atomic Take

License Cargo Documentation

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.