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());