twinsies

Crates.iotwinsies
lib.rstwinsies
version1.2.1
sourcesrc
created_at2023-01-28 03:09:32.743894
updated_at2024-03-27 17:39:15.694531
descriptionSmart pointer providing 2-way joint ownership of an object
homepage
repositoryhttps://github.com/Lucretiel/twinsies
max_upload_size
id770112
size43,925
Nathan West (Lucretiel)

documentation

README

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

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());
Commit count: 16

cargo fmt