atomic-take 0.1.0

Atomically take a value out of a container once.
# Atomic Take


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.

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.

assert_eq!(recv.try_recv().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.

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 take_clone = Arc::clone(&take);
    let join_handle = 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.

// Wait for all three threads to finish.
for handle in handles {

// After all the threads finished, try to send again.
if let Some(send) = take.take() {
    // This will definitely not happen.

// 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.