use super::{Error, server::ServerInner, session::SessionInner};
use std::sync::Weak;
#[derive(Clone, Debug)]
pub struct Closer {
target: Target,
}
#[derive(Clone, Debug)]
enum Target {
Session(Weak<SessionInner>),
Server(Weak<ServerInner>),
}
impl Closer {
pub fn close(&self) {
match &self.target {
Target::Session(target) => {
if let Some(session) = target.upgrade() {
session.close(Error::Closed);
}
}
Target::Server(target) => {
if let Some(server) = target.upgrade() {
server.close(Error::Closed);
}
}
}
}
pub(super) fn session(target: Weak<SessionInner>) -> Self {
Self {
target: Target::Session(target),
}
}
pub(super) fn server(target: Weak<ServerInner>) -> Self {
Self {
target: Target::Server(target),
}
}
}
#[cfg(test)]
#[cfg_attr(coverage_nightly, coverage(off))]
mod tests {
use crate::protocol::{Closer, Server, Session};
use std::fmt::Debug;
#[allow(dead_code)]
fn cross_thread_close(session: &Session, server: &Server) {
let session_closer: Closer = session.closer();
let server_closer: Closer = server.closer();
let session_copy = session_closer.clone();
let server_copy = server_closer.clone();
std::thread::spawn(move || session_copy.close());
std::thread::spawn(move || server_copy.close());
session.close();
server.close();
}
#[test]
fn test_thread_capabilities() {
fn shared<T: Clone + Debug + Send + Sync + 'static>() {}
shared::<Closer>();
}
}