use std::ops::Deref;
use super::inner::ConnectionPool;
use crate::netlink::{connection::Connection, protocol::ProtocolState};
#[non_exhaustive]
pub struct PooledConnection<'p, P: ProtocolState> {
pool: &'p ConnectionPool<P>,
conn: Option<Connection<P>>,
}
impl<'p, P: ProtocolState> PooledConnection<'p, P> {
pub(super) fn new(pool: &'p ConnectionPool<P>, conn: Connection<P>) -> Self {
Self {
pool,
conn: Some(conn),
}
}
pub fn invalidate(mut self) {
if let Some(conn) = self.conn.take() {
tracing::warn!(
ns = ?self.pool.namespace(),
"PooledConnection::invalidate: dropping pooled connection"
);
drop(conn);
}
}
}
impl<P: ProtocolState> Deref for PooledConnection<'_, P> {
type Target = Connection<P>;
fn deref(&self) -> &Connection<P> {
debug_assert!(
self.conn.is_some(),
"PooledConnection::conn cleared without consuming \
the guard — would imply a use-after-move past the \
Rust borrow checker. Bug."
);
self.conn
.as_ref()
.expect("PooledConnection holds a Connection until drop (see invariant above)")
}
}
impl<P: ProtocolState> Drop for PooledConnection<'_, P> {
fn drop(&mut self) {
if let Some(conn) = self.conn.take() {
let _ = self.pool.inner.available.try_send(conn);
}
}
}