infinity_pool/handles/
managed_mut.rs1use std::borrow::{Borrow, BorrowMut};
2use std::ops::{Deref, DerefMut};
3use std::pin::Pin;
4use std::ptr::NonNull;
5use std::sync::{Arc, Mutex};
6use std::{fmt, mem, ptr};
7
8use crate::{ERR_POISONED_LOCK, Pooled, RawOpaquePoolSend, RawPooledMut};
9
10#[doc = include_str!("../../doc/snippets/ref_counted_handle_implications.md")]
16#[doc = include_str!("../../doc/snippets/unique_handle_implications.md")]
17#[doc = include_str!("../../doc/snippets/nonlocal_handle_thread_safety.md")]
18pub struct PooledMut<T: ?Sized> {
19 inner: RawPooledMut<T>,
20 pool: Arc<Mutex<RawOpaquePoolSend>>,
21}
22
23impl<T: ?Sized> PooledMut<T> {
24 #[must_use]
25 pub(crate) fn new(inner: RawPooledMut<T>, pool: Arc<Mutex<RawOpaquePoolSend>>) -> Self {
26 Self { inner, pool }
27 }
28
29 #[doc = include_str!("../../doc/snippets/handle_ptr.md")]
30 #[must_use]
31 #[inline]
32 pub fn ptr(&self) -> NonNull<T> {
33 self.inner.ptr()
34 }
35
36 #[doc = include_str!("../../doc/snippets/handle_erase.md")]
37 #[must_use]
38 #[inline]
39 pub fn erase(self) -> PooledMut<()> {
40 let (inner, pool) = self.into_parts();
41
42 PooledMut {
43 inner: inner.erase(),
44 pool,
45 }
46 }
47
48 #[doc = include_str!("../../doc/snippets/handle_into_shared.md")]
49 #[must_use]
50 #[inline]
51 pub fn into_shared(self) -> Pooled<T> {
52 let (inner, pool) = self.into_parts();
53
54 Pooled::new(inner, pool)
55 }
56
57 fn into_parts(self) -> (RawPooledMut<T>, Arc<Mutex<RawOpaquePoolSend>>) {
58 let pool = unsafe { ptr::read(&raw const self.pool) };
63 let inner = unsafe { ptr::read(&raw const self.inner) };
65
66 mem::forget(self);
68
69 (inner, pool)
70 }
71
72 #[doc = include_str!("../../doc/snippets/ref_counted_as_pin.md")]
73 #[must_use]
74 #[inline]
75 pub fn as_pin(&self) -> Pin<&T> {
76 unsafe { Pin::new_unchecked(self) }
78 }
79
80 #[doc = include_str!("../../doc/snippets/ref_counted_as_pin_mut.md")]
81 #[must_use]
82 #[inline]
83 pub fn as_pin_mut(&mut self) -> Pin<&mut T> {
84 let as_mut = unsafe { self.ptr().as_mut() };
87
88 unsafe { Pin::new_unchecked(as_mut) }
90 }
91
92 #[doc(hidden)]
102 #[must_use]
103 #[inline]
104 pub unsafe fn __private_cast_dyn_with_fn<U: ?Sized, F>(self, cast_fn: F) -> PooledMut<U>
105 where
106 F: FnOnce(&mut T) -> &mut U,
107 {
108 let (inner, pool) = self.into_parts();
109
110 let new_inner = unsafe { inner.__private_cast_dyn_with_fn(cast_fn) };
114
115 PooledMut {
116 inner: new_inner,
117 pool,
118 }
119 }
120}
121
122impl<T> PooledMut<T>
123where
124 T: Unpin,
125{
126 #[doc = include_str!("../../doc/snippets/ref_counted_into_inner.md")]
127 #[must_use]
128 #[inline]
129 pub fn into_inner(self) -> T {
130 let (inner, pool) = self.into_parts();
131
132 let mut pool = pool.lock().expect(ERR_POISONED_LOCK);
133 pool.remove_mut_unpin(inner)
134 }
135}
136
137impl<T: ?Sized> fmt::Debug for PooledMut<T> {
138 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
139 f.debug_struct("PooledMut")
140 .field("inner", &self.inner)
141 .field("pool", &self.pool)
142 .finish()
143 }
144}
145
146impl<T: ?Sized> Deref for PooledMut<T> {
147 type Target = T;
148
149 #[inline]
150 fn deref(&self) -> &Self::Target {
151 unsafe { self.ptr().as_ref() }
155 }
156}
157
158impl<T> DerefMut for PooledMut<T>
159where
160 T: ?Sized + Unpin,
161{
162 #[inline]
163 fn deref_mut(&mut self) -> &mut Self::Target {
164 unsafe { self.ptr().as_mut() }
168 }
169}
170
171impl<T: ?Sized> Borrow<T> for PooledMut<T> {
172 #[inline]
173 fn borrow(&self) -> &T {
174 self
175 }
176}
177
178impl<T> BorrowMut<T> for PooledMut<T>
179where
180 T: ?Sized + Unpin,
181{
182 #[inline]
183 fn borrow_mut(&mut self) -> &mut T {
184 self
185 }
186}
187
188impl<T: ?Sized> AsRef<T> for PooledMut<T> {
189 #[inline]
190 fn as_ref(&self) -> &T {
191 self
192 }
193}
194
195impl<T> AsMut<T> for PooledMut<T>
196where
197 T: ?Sized + Unpin,
198{
199 #[inline]
200 fn as_mut(&mut self) -> &mut T {
201 self
202 }
203}
204
205impl<T: ?Sized> Drop for PooledMut<T> {
206 fn drop(&mut self) {
207 let inner = unsafe { ptr::read(&raw const self.inner) };
215
216 let mut pool = self.pool.lock().expect(ERR_POISONED_LOCK);
217 pool.remove_mut(inner);
218 }
219}
220
221#[cfg(test)]
222mod tests {
223 use std::cell::Cell;
224
225 use static_assertions::{assert_impl_all, assert_not_impl_any};
226
227 use super::*;
228
229 assert_impl_all!(PooledMut<u32>: Send);
231 assert_not_impl_any!(PooledMut<u32>: Sync);
232
233 assert_not_impl_any!(PooledMut<Cell<u32>>: Send, Sync);
235
236 assert_not_impl_any!(RawPooledMut<()>: Drop);
238}