Crate twinsies

source ·
Expand description

Twinsies is a special shared pointer, similar to an Arc, where two specific objects (called Joint) share joint ownership of the underlying object. The key difference compared to an Arc is that the underlying object is dropped when either of the Joint objects go out of scope.

Because a single Joint cannot, by itself, keep the shared object alive, it cannot be dereferenced directly like an Arc. Instead, it must be locked with .lock(). While locked, the object is guaranteed to stay alive as long as the JointLock is alive. If the a Joint is dropped while its partner is locked, the object stays alive, but it dropped immediately as soon as the other Joint is no longer locked.

Twinsies is intended to be used for things like unbuffered channels, join handles, and async Waker- cases where some piece of shared state should only be preserved as long as both halves are still interested in it.

§Example

use twinsies::Joint;
use std::cell::Cell;

let (first, second) = Joint::new(Cell::new(0));

assert_eq!(first.lock().unwrap().get(), 0);

first.lock().unwrap().set(10);
assert_eq!(second.lock().unwrap().get(), 10);

drop(second);

// Once `second` is dropped, the shared value is gone
assert!(first.lock().is_none())

§Locks preserve liveness

use twinsies::Joint;
use std::cell::Cell;

let (first, second) = Joint::new(Cell::new(0));

let lock = first.lock().unwrap();

lock.set(10);

assert_eq!(second.lock().unwrap().get(), 10);
second.lock().unwrap().set(20);

assert_eq!(lock.get(), 20);

drop(second);

assert_eq!(lock.get(), 20);
lock.set(30);
assert_eq!(lock.get(), 30);

// As soon as the lock is dropped, the shared value is gone, since `second` was
// dropped earlier
drop(lock);
assert!(first.lock().is_none());

Structs§

  • A thread-safe shared ownership type that shares ownership with a partner, such that the shared object is dropped when either Joint goes out of scope.
  • A lock associated with a Joint, providing shared access to the underlying value.