myhandle

Crates.iomyhandle
lib.rsmyhandle
version0.1.2
created_at2025-12-14 04:10:27.843425+00
updated_at2025-12-14 07:11:47.212206+00
descriptionA smart pointer that allows early drop of `T`
homepage
repository
max_upload_size
id1983760
size8,319
zyl (zylthinking)

documentation

https://docs.rs/myhandle/

README

my_handle: Detachable Atomic Reference Counting Handle

my_handle provides the smart pointer MyHandle<T>, which is similar to std::sync::Arc<T> but adds explicit detachable semantics.

This allows the cleanup and deallocation of the inner value T to be triggered early by calling dettach(), even before the Arc reference count reaches zero.

💡 Core Concepts

  1. Safety Access Guarantee: Once a reference to T is successfully obtained via the get() method, that reference is guaranteed to be valid until the corresponding unsafe fn put() is called, even if dettach() is called by another thread during this time.
  2. Early Drop: The dettach() method immediately marks the inner value T as "dead." The actual destruction of T (T's drop) is deferred until no threads hold an active reference lock (i.e., the stack count reaches zero).

🚀 Usage

use std::sync::Arc;
use my_handle::MyHandle;

// 1. Create the handle
let handle = MyHandle::attach(String::from("Data to be shared"));
let clone_1 = Arc::clone(&handle);
let clone_2 = Arc::clone(&handle);

// 2. Thread A acquires the lock and accesses the data
let guard = clone_1.get().expect("Successfully acquired reference lock");

let ref_t1 = &*guard;
println!("Thread A access: {}", ref_t1);

// 3. Thread B calls detach
// This immediately prevents future get() calls from succeeding
clone_2.dettach();
println!("Thread B: Detach called.");

// 4. Verify the detached status
assert!(handle.get().is_none());

// 5. Thread A can still safely access the data
// Although T has been marked as detached, ref_t1 remains valid until put() is called
println!("Thread A is still safely accessing the detached value: {}", ref_t1);

// If this is the last active reference lock, the inner value (String) is deallocated at this moment.
drop(guard);

Dependencies

Add the following to your Cargo.toml:

[dependencies] my_handle = "0.1" # Please replace with the actual version

⚠️ Safety Warning (Unsafe)

unsafe fn put(&self)

This method is unsafe and requires the caller to adhere to a strict invariant:

put() MUST be called exactly once for every successful get() call.

  • Undercalling: Will cause T never to be freed, leading to memory leaks.
  • Overcalling: Will lead to reference count errors, potentially causing Double Free or Use After Free.

Sync and Send

The implementation of MyHandle<T> requires T: Sync + Send.

  • T: Sync: Allows &T to be accessed across threads.
  • T: Send: Required because the MyHandle drop logic (which frees T) can execute on any thread.
Commit count: 0

cargo fmt