# 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
```rust
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.