use std::net::UdpSocket;
use std::ops::{Deref, DerefMut};
use std::sync::{Mutex, MutexGuard};
use windows::Win32::Networking::WinSock::WSAPOLLFD;
use crate::reactor::registration::{RegistrationGeneration, RegistrationTable};
use crate::reactor::socket_owner::SocketLease;
pub struct WsaPollReactor {
pub(super) registrations: Mutex<RegistrationTable<usize>>,
pub(super) wake: UdpSocket,
pub(super) wake_addr: std::net::SocketAddr,
pub(super) poll_buffer: Mutex<PollBuffer>,
pub(super) lease_buffer: Mutex<Vec<SocketLease>>,
}
#[derive(Default)]
pub(super) struct PollBuffer {
pub(super) fds: Vec<WSAPOLLFD>,
pub(super) generations: Vec<RegistrationGeneration>,
}
pub(super) struct PollSnapshot<'a> {
lease_source: &'a Mutex<Vec<SocketLease>>,
buffer: Option<MutexGuard<'a, PollBuffer>>,
pub(super) leases: Vec<SocketLease>,
}
impl<'a> PollSnapshot<'a> {
pub(super) fn acquire(
source: &'a Mutex<PollBuffer>,
lease_source: &'a Mutex<Vec<SocketLease>>,
) -> Self {
let buffer = lock_mutex(source);
let leases = std::mem::take(&mut *lock_mutex(lease_source));
Self {
lease_source,
buffer: Some(buffer),
leases,
}
}
pub(super) fn finish(mut self) {
drop(self.buffer.take());
self.leases.clear();
std::mem::swap(&mut *lock_mutex(self.lease_source), &mut self.leases);
}
}
impl Deref for PollSnapshot<'_> {
type Target = PollBuffer;
fn deref(&self) -> &Self::Target {
self.buffer
.as_deref()
.expect("poll snapshot owns its buffer until release")
}
}
impl DerefMut for PollSnapshot<'_> {
fn deref_mut(&mut self) -> &mut Self::Target {
self.buffer
.as_deref_mut()
.expect("poll snapshot owns its buffer until release")
}
}
impl Drop for PollSnapshot<'_> {
fn drop(&mut self) {
drop(self.buffer.take());
self.leases.clear();
}
}
unsafe impl Send for WsaPollReactor {}
unsafe impl Sync for WsaPollReactor {}
pub(super) fn lock_mutex<T>(mutex: &Mutex<T>) -> MutexGuard<'_, T> {
mutex
.lock()
.unwrap_or_else(|poisoned| poisoned.into_inner())
}