use std::pin::Pin;
use std::sync::{Arc, Mutex};
use crate::buffer::PinnedBuffer;
use super::PoolInner;
pub struct PooledBuffer {
buffer: Option<PinnedBuffer<[u8]>>,
pool: Arc<Mutex<PoolInner>>,
}
impl PooledBuffer {
pub(super) fn new(buffer: PinnedBuffer<[u8]>, pool: Arc<Mutex<PoolInner>>) -> Self {
Self {
buffer: Some(buffer),
pool,
}
}
pub fn buffer(&self) -> &PinnedBuffer<[u8]> {
self.buffer
.as_ref()
.expect("Buffer should be present - this is a bug")
}
pub fn buffer_mut(&mut self) -> &mut PinnedBuffer<[u8]> {
self.buffer
.as_mut()
.expect("Buffer should be present - this is a bug")
}
pub fn as_mut_slice(&mut self) -> Pin<&mut [u8]> {
self.buffer_mut().as_mut_slice()
}
pub fn as_slice(&self) -> &[u8] {
self.buffer().as_slice()
}
pub fn len(&self) -> usize {
self.buffer().len()
}
pub fn is_empty(&self) -> bool {
self.buffer().is_empty()
}
pub fn detach(mut self) -> PinnedBuffer<[u8]> {
self.buffer
.take()
.expect("Buffer should be present - this is a bug")
}
}
impl Drop for PooledBuffer {
fn drop(&mut self) {
if let Some(buffer) = self.buffer.take() {
if let Ok(mut inner) = self.pool.lock() {
inner.available.push_back(buffer);
inner.in_use = inner.in_use.saturating_sub(1);
}
}
}
}
impl std::fmt::Debug for PooledBuffer {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("PooledBuffer")
.field("len", &self.len())
.field("has_buffer", &self.buffer.is_some())
.finish()
}
}
unsafe impl Send for PooledBuffer {}
unsafe impl Sync for PooledBuffer {}