twinsies

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

```rust 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);

asserteq!(lock.get(), 20); lock.set(30); asserteq!(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()); ```