mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-16 16:25:08 +00:00
Move the ref counts out
This commit is contained in:
committed by
Benjamin Saunders
parent
26a776626e
commit
404db1bc94
+13
-9
@@ -5,7 +5,10 @@ use std::{
|
||||
io,
|
||||
net::{IpAddr, SocketAddr},
|
||||
pin::Pin,
|
||||
sync::Arc,
|
||||
sync::{
|
||||
Arc,
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
},
|
||||
task::{Context, Poll, Waker, ready},
|
||||
};
|
||||
|
||||
@@ -917,17 +920,19 @@ impl ConnectionRef {
|
||||
|
||||
impl Clone for ConnectionRef {
|
||||
fn clone(&self) -> Self {
|
||||
self.state.lock("clone").ref_count += 1;
|
||||
self.shared.ref_count.fetch_add(1, Ordering::Relaxed);
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for ConnectionRef {
|
||||
fn drop(&mut self) {
|
||||
let conn = &mut *self.state.lock("drop");
|
||||
if let Some(x) = conn.ref_count.checked_sub(1) {
|
||||
conn.ref_count = x;
|
||||
if x == 0 && !conn.inner.is_closed() {
|
||||
let ref_count = self.shared.ref_count.fetch_sub(1, Ordering::Relaxed);
|
||||
|
||||
if ref_count == 0 {
|
||||
let conn = &mut *self.state.lock("drop");
|
||||
|
||||
if !conn.inner.is_closed() {
|
||||
// If the driver is alive, it's just it and us, so we'd better shut it down. If it's
|
||||
// not, we can't do any harm. If there were any streams being opened, then either
|
||||
// the connection will be closed for an unrelated reason or a fresh reference will
|
||||
@@ -962,6 +967,8 @@ pub(crate) struct Shared {
|
||||
datagram_received: Notify,
|
||||
datagrams_unblocked: Notify,
|
||||
closed: Notify,
|
||||
/// Number of live handles that can used to initiate or handle I/O; excludes the driver
|
||||
ref_count: AtomicUsize,
|
||||
}
|
||||
|
||||
pub(crate) struct State {
|
||||
@@ -981,8 +988,6 @@ pub(crate) struct State {
|
||||
pub(crate) stopped: FxHashMap<StreamId, Arc<Notify>>,
|
||||
/// Always set to Some before the connection becomes drained
|
||||
pub(crate) error: Option<ConnectionError>,
|
||||
/// Number of live handles that can be used to initiate or handle I/O; excludes the driver
|
||||
ref_count: usize,
|
||||
sender: Pin<Box<dyn UdpSender>>,
|
||||
runtime: Arc<dyn Runtime>,
|
||||
send_buffer: Vec<u8>,
|
||||
@@ -1018,7 +1023,6 @@ impl State {
|
||||
blocked_readers: FxHashMap::default(),
|
||||
stopped: FxHashMap::default(),
|
||||
error: None,
|
||||
ref_count: 0,
|
||||
sender,
|
||||
runtime,
|
||||
send_buffer: Vec::new(),
|
||||
|
||||
+19
-15
@@ -7,7 +7,10 @@ use std::{
|
||||
net::{SocketAddr, SocketAddrV6},
|
||||
pin::Pin,
|
||||
str,
|
||||
sync::{Arc, Mutex},
|
||||
sync::{
|
||||
Arc, Mutex,
|
||||
atomic::{AtomicUsize, Ordering},
|
||||
},
|
||||
task::{Context, Poll, RawWaker, RawWakerVTable, Waker},
|
||||
};
|
||||
|
||||
@@ -390,7 +393,9 @@ impl Future for EndpointDriver {
|
||||
self.0.shared.incoming.notify_waiters();
|
||||
}
|
||||
|
||||
if endpoint.ref_count == 0 && endpoint.recv_state.connections.is_empty() {
|
||||
if self.0.shared.ref_count.load(Ordering::Relaxed) == 0
|
||||
&& endpoint.recv_state.connections.is_empty()
|
||||
{
|
||||
Poll::Ready(Ok(()))
|
||||
} else {
|
||||
drop(endpoint);
|
||||
@@ -488,8 +493,6 @@ pub(crate) struct State {
|
||||
driver: Option<Waker>,
|
||||
ipv6: bool,
|
||||
events: mpsc::UnboundedReceiver<(ConnectionHandle, EndpointEvent)>,
|
||||
/// Number of live handles that can be used to initiate or handle I/O; excludes the driver
|
||||
ref_count: usize,
|
||||
driver_lost: bool,
|
||||
runtime: Arc<dyn Runtime>,
|
||||
stats: EndpointStats,
|
||||
@@ -500,6 +503,8 @@ pub(crate) struct State {
|
||||
pub(crate) struct Shared {
|
||||
incoming: Notify,
|
||||
idle: Notify,
|
||||
/// Number of live handles that can be used to initiate or handle I/O; excludes the driver
|
||||
ref_count: AtomicUsize,
|
||||
}
|
||||
|
||||
impl State {
|
||||
@@ -736,6 +741,7 @@ impl EndpointRef {
|
||||
shared: Shared {
|
||||
incoming: Notify::new(),
|
||||
idle: Notify::new(),
|
||||
ref_count: AtomicUsize::new(0),
|
||||
},
|
||||
state: Mutex::new(State {
|
||||
socket,
|
||||
@@ -745,7 +751,6 @@ impl EndpointRef {
|
||||
ipv6,
|
||||
events,
|
||||
driver: None,
|
||||
ref_count: 0,
|
||||
driver_lost: false,
|
||||
recv_state,
|
||||
runtime,
|
||||
@@ -758,22 +763,21 @@ impl EndpointRef {
|
||||
|
||||
impl Clone for EndpointRef {
|
||||
fn clone(&self) -> Self {
|
||||
self.0.state.lock().unwrap().ref_count += 1;
|
||||
self.0.shared.ref_count.fetch_add(1, Ordering::Relaxed);
|
||||
Self(self.0.clone())
|
||||
}
|
||||
}
|
||||
|
||||
impl Drop for EndpointRef {
|
||||
fn drop(&mut self) {
|
||||
let endpoint = &mut *self.0.state.lock().unwrap();
|
||||
if let Some(x) = endpoint.ref_count.checked_sub(1) {
|
||||
endpoint.ref_count = x;
|
||||
if x == 0 {
|
||||
// If the driver is about to be on its own, ensure it can shut down if the last
|
||||
// connection is gone.
|
||||
if let Some(task) = endpoint.driver.take() {
|
||||
task.wake();
|
||||
}
|
||||
let ref_count = self.shared.ref_count.fetch_sub(1, Ordering::Relaxed);
|
||||
|
||||
if ref_count == 0 {
|
||||
let endpoint = &mut *self.0.state.lock().unwrap();
|
||||
// If the driver is about to be on its own, ensure it can shut down if the last
|
||||
// connection is gone.
|
||||
if let Some(task) = endpoint.driver.take() {
|
||||
task.wake();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user