pub struct LocalOnceEventPool<T> { /* private fields */ }Expand description
A pool that manages single-threaded events with automatic cleanup.
The pool creates local events on demand and automatically cleans them up when both sender and receiver endpoints are dropped.
This is the single-threaded variant that cannot be shared across threads but has
lower overhead than the thread-safe super::OnceEventPool.
The pool provides zero-allocation event reuse for high-frequency eventing scenarios within a single thread.
§Example
use events::LocalOnceEventPool;
let pool = LocalOnceEventPool::<i32>::new();
// First usage - creates new event
let (sender1, receiver1) = pool.bind_by_ref();
sender1.send(42);
let value1 = futures::executor::block_on(receiver1).unwrap();
assert_eq!(value1, 42);
// Event returned to pool when sender1/receiver1 are dropped
// Second usage - reuses the same event instance for efficiency
let (sender2, receiver2) = pool.bind_by_ref();
sender2.send(100);
let value2 = futures::executor::block_on(receiver2).unwrap();
assert_eq!(value2, 100);
// Same event reused - no additional allocation overheadImplementations§
Source§impl<T> LocalOnceEventPool<T>
impl<T> LocalOnceEventPool<T>
Sourcepub fn new() -> Self
pub fn new() -> Self
Creates a new empty local event pool.
§Example
use events::LocalOnceEventPool;
let pool = LocalOnceEventPool::<String>::new();Sourcepub fn bind_by_ref(
&self,
) -> (PooledLocalOnceSender<RefLocalPool<'_, T>>, PooledLocalOnceReceiver<RefLocalPool<'_, T>>)
pub fn bind_by_ref( &self, ) -> (PooledLocalOnceSender<RefLocalPool<'_, T>>, PooledLocalOnceReceiver<RefLocalPool<'_, T>>)
Creates sender and receiver endpoints connected by reference to the pool.
The pool will create a new local event and return endpoints that reference it. When both endpoints are dropped, the event will be automatically cleaned up.
§Example
use events::LocalOnceEventPool;
let pool = LocalOnceEventPool::<i32>::new();
// First usage
let (sender1, receiver1) = pool.bind_by_ref();
sender1.send(42);
let value1 = futures::executor::block_on(receiver1).unwrap();
assert_eq!(value1, 42);
// Second usage - efficiently reuses the same underlying event
let (sender2, receiver2) = pool.bind_by_ref();
sender2.send(100);
let value2 = futures::executor::block_on(receiver2).unwrap();
assert_eq!(value2, 100);Sourcepub fn bind_by_rc(
self: &Rc<Self>,
) -> (PooledLocalOnceSender<RcLocalPool<T>>, PooledLocalOnceReceiver<RcLocalPool<T>>)
pub fn bind_by_rc( self: &Rc<Self>, ) -> (PooledLocalOnceSender<RcLocalPool<T>>, PooledLocalOnceReceiver<RcLocalPool<T>>)
Creates sender and receiver endpoints connected by Rc to the pool.
The pool will create a new local event and return endpoints that hold Rc references. When both endpoints are dropped, the event will be automatically cleaned up.
§Example
use std::rc::Rc;
use events::LocalOnceEventPool;
let pool = Rc::new(LocalOnceEventPool::<i32>::new());
// First usage
let (sender1, receiver1) = pool.bind_by_rc();
sender1.send(42);
let value1 = futures::executor::block_on(receiver1).unwrap();
assert_eq!(value1, 42);
// Second usage - reuses the same event from the pool
let (sender2, receiver2) = pool.bind_by_rc();
sender2.send(200);
let value2 = futures::executor::block_on(receiver2).unwrap();
assert_eq!(value2, 200);Sourcepub unsafe fn bind_by_ptr(
self: Pin<&Self>,
) -> (PooledLocalOnceSender<PtrLocalPool<T>>, PooledLocalOnceReceiver<PtrLocalPool<T>>)
pub unsafe fn bind_by_ptr( self: Pin<&Self>, ) -> (PooledLocalOnceSender<PtrLocalPool<T>>, PooledLocalOnceReceiver<PtrLocalPool<T>>)
Creates sender and receiver endpoints connected by raw pointer to the pool.
The pool will create a new local event and return endpoints that hold raw pointers. When both endpoints are dropped, the event will be automatically cleaned up.
§Safety
The caller must ensure that:
- The pool remains valid and pinned for the entire lifetime of the sender and receiver
- The sender and receiver are dropped before the pool is dropped
§Example
use std::pin::Pin;
use events::LocalOnceEventPool;
let pool = Box::pin(LocalOnceEventPool::<i32>::new());
// First usage
// SAFETY: We ensure the pool is pinned and outlives the sender and receiver
let (sender1, receiver1) = unsafe { pool.as_ref().bind_by_ptr() };
sender1.send(42);
let value1 = receiver1.await.unwrap();
assert_eq!(value1, 42);
// Second usage - reuses the same event efficiently
// SAFETY: Pool is still valid and pinned
let (sender2, receiver2) = unsafe { pool.as_ref().bind_by_ptr() };
sender2.send(100);
let value2 = receiver2.await.unwrap();
assert_eq!(value2, 100);
// Both sender and receiver pairs are dropped here, before poolSourcepub fn len(&self) -> usize
pub fn len(&self) -> usize
Returns the number of events currently in the pool.
This represents the count of events that are currently allocated in the pool, including those that are currently bound to sender/receiver endpoints. Events are removed from the pool only when both endpoints are dropped.
§Example
use events::LocalOnceEventPool;
let pool = LocalOnceEventPool::<i32>::new();
assert_eq!(pool.len(), 0);
let (sender, receiver) = pool.bind_by_ref();
assert_eq!(pool.len(), 1); // Event is in pool while endpoints exist
drop(sender);
drop(receiver);
assert_eq!(pool.len(), 0); // Event cleaned up after both endpoints droppedSourcepub fn is_empty(&self) -> bool
pub fn is_empty(&self) -> bool
Returns whether the pool is empty.
This is equivalent to pool.len() == 0 but may be more efficient.
An empty pool may still have reserved capacity.
§Example
use events::LocalOnceEventPool;
let pool = LocalOnceEventPool::<i32>::new();
assert!(pool.is_empty());
let (sender, receiver) = pool.bind_by_ref();
assert!(!pool.is_empty()); // Pool has event while endpoints exist
drop(sender);
drop(receiver);
assert!(pool.is_empty()); // Pool empty after both endpoints droppedSourcepub fn shrink_to_fit(&self)
pub fn shrink_to_fit(&self)
Shrinks the capacity of the pool to reduce memory usage.
This method attempts to release unused memory by reducing the pool’s capacity. The actual reduction is implementation-dependent and may vary - some capacity may be released, or none at all.
§Example
use events::LocalOnceEventPool;
let pool = LocalOnceEventPool::<i32>::new();
// Use the pool which may grow its capacity
for _ in 0..100 {
let (sender, receiver) = pool.bind_by_ref();
sender.send(42);
let _value = futures::executor::block_on(receiver);
}
// Attempt to shrink to reduce memory usage
pool.shrink_to_fit();Sourcepub fn inspect_awaiters(&self, f: impl FnMut(Option<&Backtrace>))
pub fn inspect_awaiters(&self, f: impl FnMut(Option<&Backtrace>))
Uses the provided closure to inspect the backtraces of the most recent awaiter of each
event in the pool (or None if it has never been awaited).
This method is only available in debug builds (cfg(debug_assertions)).
For any data to be present, RUST_BACKTRACE=1 or RUST_LIB_BACKTRACE=1 must be set.
The closure is called once for each event in the pool that is currently being awaited by someone.
Trait Implementations§
Source§impl<T> Debug for LocalOnceEventPool<T>
impl<T> Debug for LocalOnceEventPool<T>
Auto Trait Implementations§
impl<T> !Freeze for LocalOnceEventPool<T>
impl<T> !RefUnwindSafe for LocalOnceEventPool<T>
impl<T> !Send for LocalOnceEventPool<T>
impl<T> !Sync for LocalOnceEventPool<T>
impl<T> !Unpin for LocalOnceEventPool<T>
impl<T> UnwindSafe for LocalOnceEventPool<T>where
T: UnwindSafe,
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> FmtForward for T
impl<T> FmtForward for T
Source§fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
fn fmt_binary(self) -> FmtBinary<Self>where
Self: Binary,
self to use its Binary implementation when Debug-formatted.Source§fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
fn fmt_display(self) -> FmtDisplay<Self>where
Self: Display,
self to use its Display implementation when
Debug-formatted.Source§fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
fn fmt_lower_exp(self) -> FmtLowerExp<Self>where
Self: LowerExp,
self to use its LowerExp implementation when
Debug-formatted.Source§fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
fn fmt_lower_hex(self) -> FmtLowerHex<Self>where
Self: LowerHex,
self to use its LowerHex implementation when
Debug-formatted.Source§fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
fn fmt_octal(self) -> FmtOctal<Self>where
Self: Octal,
self to use its Octal implementation when Debug-formatted.Source§fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
fn fmt_pointer(self) -> FmtPointer<Self>where
Self: Pointer,
self to use its Pointer implementation when
Debug-formatted.Source§fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
fn fmt_upper_exp(self) -> FmtUpperExp<Self>where
Self: UpperExp,
self to use its UpperExp implementation when
Debug-formatted.Source§fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
fn fmt_upper_hex(self) -> FmtUpperHex<Self>where
Self: UpperHex,
self to use its UpperHex implementation when
Debug-formatted.Source§impl<T> Pipe for Twhere
T: ?Sized,
impl<T> Pipe for Twhere
T: ?Sized,
Source§fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
fn pipe<R>(self, func: impl FnOnce(Self) -> R) -> Rwhere
Self: Sized,
Source§fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref<'a, R>(&'a self, func: impl FnOnce(&'a Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
fn pipe_ref_mut<'a, R>(&'a mut self, func: impl FnOnce(&'a mut Self) -> R) -> Rwhere
R: 'a,
self and passes that borrow into the pipe function. Read moreSource§fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
fn pipe_borrow<'a, B, R>(&'a self, func: impl FnOnce(&'a B) -> R) -> R
Source§fn pipe_borrow_mut<'a, B, R>(
&'a mut self,
func: impl FnOnce(&'a mut B) -> R,
) -> R
fn pipe_borrow_mut<'a, B, R>( &'a mut self, func: impl FnOnce(&'a mut B) -> R, ) -> R
Source§fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
fn pipe_as_ref<'a, U, R>(&'a self, func: impl FnOnce(&'a U) -> R) -> R
self, then passes self.as_ref() into the pipe function.Source§fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
fn pipe_as_mut<'a, U, R>(&'a mut self, func: impl FnOnce(&'a mut U) -> R) -> R
self, then passes self.as_mut() into the pipe
function.Source§fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
fn pipe_deref<'a, T, R>(&'a self, func: impl FnOnce(&'a T) -> R) -> R
self, then passes self.deref() into the pipe function.Source§impl<T> Tap for T
impl<T> Tap for T
Source§fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow<B>(self, func: impl FnOnce(&B)) -> Self
Borrow<B> of a value. Read moreSource§fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut<B>(self, func: impl FnOnce(&mut B)) -> Self
BorrowMut<B> of a value. Read moreSource§fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref<R>(self, func: impl FnOnce(&R)) -> Self
AsRef<R> view of a value. Read moreSource§fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut<R>(self, func: impl FnOnce(&mut R)) -> Self
AsMut<R> view of a value. Read moreSource§fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref<T>(self, func: impl FnOnce(&T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
fn tap_deref_mut<T>(self, func: impl FnOnce(&mut T)) -> Self
Deref::Target of a value. Read moreSource§fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
fn tap_dbg(self, func: impl FnOnce(&Self)) -> Self
.tap() only in debug builds, and is erased in release builds.Source§fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
fn tap_mut_dbg(self, func: impl FnOnce(&mut Self)) -> Self
.tap_mut() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
fn tap_borrow_dbg<B>(self, func: impl FnOnce(&B)) -> Self
.tap_borrow() only in debug builds, and is erased in release
builds.Source§fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
fn tap_borrow_mut_dbg<B>(self, func: impl FnOnce(&mut B)) -> Self
.tap_borrow_mut() only in debug builds, and is erased in release
builds.Source§fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
fn tap_ref_dbg<R>(self, func: impl FnOnce(&R)) -> Self
.tap_ref() only in debug builds, and is erased in release
builds.Source§fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
fn tap_ref_mut_dbg<R>(self, func: impl FnOnce(&mut R)) -> Self
.tap_ref_mut() only in debug builds, and is erased in release
builds.Source§fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
fn tap_deref_dbg<T>(self, func: impl FnOnce(&T)) -> Self
.tap_deref() only in debug builds, and is erased in release
builds.