Fixed a race condition where in multiple thread environment that wasteful (#25176)
Duplicate and useless connections are being created which overloads the server and cause unreliable connections on the client side.
This commit is contained in:
parent
35d2a0fd69
commit
abd4ef889e
|
@ -267,6 +267,27 @@ fn get_or_add_connection(addr: &SocketAddr) -> GetConnectionResult {
|
|||
num_evictions,
|
||||
eviction_timing_ms,
|
||||
) = match map.map.get(addr) {
|
||||
Some(connection) => {
|
||||
let mut stats = None;
|
||||
// update connection stats
|
||||
if let Connection::Quic(conn) = connection {
|
||||
stats = conn.stats().map(|s| (conn.base_stats(), s));
|
||||
}
|
||||
(connection.clone(), true, map.stats.clone(), stats, 0, 0)
|
||||
}
|
||||
None => {
|
||||
// Upgrade to write access by dropping read lock and acquire write lock
|
||||
drop(map);
|
||||
let mut get_connection_map_lock_measure =
|
||||
Measure::start("get_connection_map_lock_measure");
|
||||
let mut map = (*CONNECTION_MAP).write().unwrap();
|
||||
get_connection_map_lock_measure.stop();
|
||||
|
||||
lock_timing_ms = lock_timing_ms.saturating_add(get_connection_map_lock_measure.as_ms());
|
||||
|
||||
// Read again, as it is possible that between read lock dropped and the write lock acquired
|
||||
// another thread could have setup the connection.
|
||||
match map.map.get(addr) {
|
||||
Some(connection) => {
|
||||
let mut stats = None;
|
||||
// update connection stats
|
||||
|
@ -288,15 +309,6 @@ fn get_or_add_connection(addr: &SocketAddr) -> GetConnectionResult {
|
|||
Connection::Udp(Arc::new(UdpTpuConnection::new(send_socket, *addr)))
|
||||
};
|
||||
|
||||
// Upgrade to write access by dropping read lock and acquire write lock
|
||||
drop(map);
|
||||
let mut get_connection_map_lock_measure =
|
||||
Measure::start("get_connection_map_lock_measure");
|
||||
let mut map = (*CONNECTION_MAP).write().unwrap();
|
||||
get_connection_map_lock_measure.stop();
|
||||
|
||||
lock_timing_ms = lock_timing_ms.saturating_add(get_connection_map_lock_measure.as_ms());
|
||||
|
||||
// evict a connection if the cache is reaching upper bounds
|
||||
let mut num_evictions = 0;
|
||||
let mut get_connection_cache_eviction_measure =
|
||||
|
@ -319,6 +331,8 @@ fn get_or_add_connection(addr: &SocketAddr) -> GetConnectionResult {
|
|||
get_connection_cache_eviction_measure.as_ms(),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
get_connection_map_measure.stop();
|
||||
|
||||
|
|
Loading…
Reference in New Issue