Reduced thread contention
This commit is contained in:
parent
9768fddb19
commit
2d89708ea8
@ -215,7 +215,8 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone
|
|||||||
|
|
||||||
/// Send a packet over the network to another peer.
|
/// Send a packet over the network to another peer.
|
||||||
pub fn send(&self, peer: PeerId, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError> {
|
pub fn send(&self, peer: PeerId, packet_id: PacketId, data: Vec<u8>) -> Result<(), UtilError> {
|
||||||
if let Some(connection) = self.connections.read().unwrap().get(peer).cloned() {
|
let connection = { self.connections.read().unwrap().get(peer).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
match *connection.lock().unwrap().deref_mut() {
|
match *connection.lock().unwrap().deref_mut() {
|
||||||
ConnectionEntry::Session(ref mut s) => {
|
ConnectionEntry::Session(ref mut s) => {
|
||||||
s.send_packet(self.protocol, packet_id as u8, &data).unwrap_or_else(|e| {
|
s.send_packet(self.protocol, packet_id as u8, &data).unwrap_or_else(|e| {
|
||||||
@ -264,7 +265,8 @@ impl<'s, Message> NetworkContext<'s, Message> where Message: Send + Sync + Clone
|
|||||||
|
|
||||||
/// Returns peer identification string
|
/// Returns peer identification string
|
||||||
pub fn peer_info(&self, peer: PeerId) -> String {
|
pub fn peer_info(&self, peer: PeerId) -> String {
|
||||||
if let Some(connection) = self.connections.read().unwrap().get(peer).cloned() {
|
let connection = { self.connections.read().unwrap().get(peer).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
if let ConnectionEntry::Session(ref s) = *connection.lock().unwrap().deref() {
|
if let ConnectionEntry::Session(ref s) = *connection.lock().unwrap().deref() {
|
||||||
return s.info.client_version.clone()
|
return s.info.client_version.clone()
|
||||||
}
|
}
|
||||||
@ -525,7 +527,8 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
|||||||
fn connection_writable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
fn connection_writable(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||||
let mut create_session = false;
|
let mut create_session = false;
|
||||||
let mut kill = false;
|
let mut kill = false;
|
||||||
if let Some(connection) = self.connections.read().unwrap().get(token).cloned() {
|
let connection = { self.connections.read().unwrap().get(token).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
match *connection.lock().unwrap().deref_mut() {
|
match *connection.lock().unwrap().deref_mut() {
|
||||||
ConnectionEntry::Handshake(ref mut h) => {
|
ConnectionEntry::Handshake(ref mut h) => {
|
||||||
match h.writable(io, &self.info.read().unwrap()) {
|
match h.writable(io, &self.info.read().unwrap()) {
|
||||||
@ -569,7 +572,8 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
|||||||
let mut packet_data: Option<(ProtocolId, PacketId, Vec<u8>)> = None;
|
let mut packet_data: Option<(ProtocolId, PacketId, Vec<u8>)> = None;
|
||||||
let mut create_session = false;
|
let mut create_session = false;
|
||||||
let mut kill = false;
|
let mut kill = false;
|
||||||
if let Some(connection) = self.connections.read().unwrap().get(token).cloned() {
|
let connection = { self.connections.read().unwrap().get(token).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
match *connection.lock().unwrap().deref_mut() {
|
match *connection.lock().unwrap().deref_mut() {
|
||||||
ConnectionEntry::Handshake(ref mut h) => {
|
ConnectionEntry::Handshake(ref mut h) => {
|
||||||
if let Err(e) = h.readable(io, &self.info.read().unwrap()) {
|
if let Err(e) = h.readable(io, &self.info.read().unwrap()) {
|
||||||
@ -628,20 +632,28 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
|||||||
|
|
||||||
fn start_session(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
fn start_session(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||||
let mut connections = self.connections.write().unwrap();
|
let mut connections = self.connections.write().unwrap();
|
||||||
if connections.get(token).is_none() {
|
let replace = {
|
||||||
return; // handshake expired
|
let connection = { connections.get(token).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
|
match *connection.lock().unwrap().deref_mut() {
|
||||||
|
ConnectionEntry::Handshake(_) => true,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
} else { false }
|
||||||
|
};
|
||||||
|
if replace {
|
||||||
|
connections.replace_with(token, |c| {
|
||||||
|
match Arc::try_unwrap(c).ok().unwrap().into_inner().unwrap() {
|
||||||
|
ConnectionEntry::Handshake(h) => {
|
||||||
|
let session = Session::new(h, io, &self.info.read().unwrap()).expect("Session creation error");
|
||||||
|
io.update_registration(token).expect("Error updating session registration");
|
||||||
|
self.stats.inc_sessions();
|
||||||
|
Some(Arc::new(Mutex::new(ConnectionEntry::Session(session))))
|
||||||
|
},
|
||||||
|
_ => { None } // handshake expired
|
||||||
|
}
|
||||||
|
}).ok();
|
||||||
}
|
}
|
||||||
connections.replace_with(token, |c| {
|
|
||||||
match Arc::try_unwrap(c).ok().unwrap().into_inner().unwrap() {
|
|
||||||
ConnectionEntry::Handshake(h) => {
|
|
||||||
let session = Session::new(h, io, &self.info.read().unwrap()).expect("Session creation error");
|
|
||||||
io.update_registration(token).expect("Error updating session registration");
|
|
||||||
self.stats.inc_sessions();
|
|
||||||
Some(Arc::new(Mutex::new(ConnectionEntry::Session(session))))
|
|
||||||
},
|
|
||||||
_ => { None } // handshake expired
|
|
||||||
}
|
|
||||||
}).ok();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn connection_timeout(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
fn connection_timeout(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>) {
|
||||||
@ -650,15 +662,14 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
|||||||
|
|
||||||
fn kill_connection(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>, remote: bool) {
|
fn kill_connection(&self, token: StreamToken, io: &IoContext<NetworkIoMessage<Message>>, remote: bool) {
|
||||||
let mut to_disconnect: Vec<ProtocolId> = Vec::new();
|
let mut to_disconnect: Vec<ProtocolId> = Vec::new();
|
||||||
|
let mut failure_id = None;
|
||||||
{
|
{
|
||||||
let mut connections = self.connections.write().unwrap();
|
let mut connections = self.connections.write().unwrap();
|
||||||
if let Some(connection) = connections.get(token).cloned() {
|
if let Some(connection) = connections.get(token).cloned() {
|
||||||
match *connection.lock().unwrap().deref_mut() {
|
match *connection.lock().unwrap().deref_mut() {
|
||||||
ConnectionEntry::Handshake(ref h) => {
|
ConnectionEntry::Handshake(ref h) => {
|
||||||
connections.remove(token);
|
connections.remove(token);
|
||||||
if remote {
|
failure_id = Some(h.id().clone());
|
||||||
self.nodes.write().unwrap().note_failure(h.id());
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
ConnectionEntry::Session(ref mut s) if s.is_ready() => {
|
ConnectionEntry::Session(ref mut s) if s.is_ready() => {
|
||||||
for (p, _) in self.handlers.read().unwrap().iter() {
|
for (p, _) in self.handlers.read().unwrap().iter() {
|
||||||
@ -667,15 +678,18 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
connections.remove(token);
|
connections.remove(token);
|
||||||
if remote {
|
failure_id = Some(s.id().clone());
|
||||||
self.nodes.write().unwrap().note_failure(s.id());
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
_ => {},
|
_ => {},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
io.deregister_stream(token).expect("Error deregistering stream");
|
io.deregister_stream(token).expect("Error deregistering stream");
|
||||||
}
|
}
|
||||||
|
if let Some(id) = failure_id {
|
||||||
|
if remote {
|
||||||
|
self.nodes.write().unwrap().note_failure(&id);
|
||||||
|
}
|
||||||
|
}
|
||||||
for p in to_disconnect {
|
for p in to_disconnect {
|
||||||
let h = self.handlers.read().unwrap().get(p).unwrap().clone();
|
let h = self.handlers.read().unwrap().get(p).unwrap().clone();
|
||||||
h.disconnected(&NetworkContext::new(io, p, Some(token), self.connections.clone()), &token);
|
h.disconnected(&NetworkContext::new(io, p, Some(token), self.connections.clone()), &token);
|
||||||
@ -683,18 +697,20 @@ impl<Message> Host<Message> where Message: Send + Sync + Clone {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn update_nodes(&self, io: &IoContext<NetworkIoMessage<Message>>, node_changes: TableUpdates) {
|
fn update_nodes(&self, io: &IoContext<NetworkIoMessage<Message>>, node_changes: TableUpdates) {
|
||||||
let connections = self.connections.write().unwrap();
|
|
||||||
let mut to_remove: Vec<PeerId> = Vec::new();
|
let mut to_remove: Vec<PeerId> = Vec::new();
|
||||||
for c in connections.iter() {
|
{
|
||||||
match *c.lock().unwrap().deref_mut() {
|
let connections = self.connections.write().unwrap();
|
||||||
ConnectionEntry::Handshake(ref h) => {
|
for c in connections.iter() {
|
||||||
if node_changes.removed.contains(&h.id()) {
|
match *c.lock().unwrap().deref_mut() {
|
||||||
to_remove.push(h.token());
|
ConnectionEntry::Handshake(ref h) => {
|
||||||
|
if node_changes.removed.contains(&h.id()) {
|
||||||
|
to_remove.push(h.token());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
ConnectionEntry::Session(ref s) => {
|
||||||
ConnectionEntry::Session(ref s) => {
|
if node_changes.removed.contains(&s.id()) {
|
||||||
if node_changes.removed.contains(&s.id()) {
|
to_remove.push(s.token());
|
||||||
to_remove.push(s.token());
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -804,7 +820,8 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
|||||||
io.register_timer(handler_token, *delay).expect("Error registering timer");
|
io.register_timer(handler_token, *delay).expect("Error registering timer");
|
||||||
},
|
},
|
||||||
NetworkIoMessage::Disconnect(ref peer) => {
|
NetworkIoMessage::Disconnect(ref peer) => {
|
||||||
if let Some(connection) = self.connections.read().unwrap().get(*peer).cloned() {
|
let connection = { self.connections.read().unwrap().get(*peer).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
match *connection.lock().unwrap().deref_mut() {
|
match *connection.lock().unwrap().deref_mut() {
|
||||||
ConnectionEntry::Handshake(_) => {},
|
ConnectionEntry::Handshake(_) => {},
|
||||||
ConnectionEntry::Session(ref mut s) => { s.disconnect(DisconnectReason::DisconnectRequested); }
|
ConnectionEntry::Session(ref mut s) => { s.disconnect(DisconnectReason::DisconnectRequested); }
|
||||||
@ -823,7 +840,8 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
|||||||
fn register_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
|
fn register_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
|
||||||
match stream {
|
match stream {
|
||||||
FIRST_CONNECTION ... LAST_CONNECTION => {
|
FIRST_CONNECTION ... LAST_CONNECTION => {
|
||||||
if let Some(connection) = self.connections.read().unwrap().get(stream).cloned() {
|
let connection = { self.connections.read().unwrap().get(stream).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
match *connection.lock().unwrap().deref() {
|
match *connection.lock().unwrap().deref() {
|
||||||
ConnectionEntry::Handshake(ref h) => h.register_socket(reg, event_loop).expect("Error registering socket"),
|
ConnectionEntry::Handshake(ref h) => h.register_socket(reg, event_loop).expect("Error registering socket"),
|
||||||
ConnectionEntry::Session(_) => warn!("Unexpected session stream registration")
|
ConnectionEntry::Session(_) => warn!("Unexpected session stream registration")
|
||||||
@ -857,7 +875,8 @@ impl<Message> IoHandler<NetworkIoMessage<Message>> for Host<Message> where Messa
|
|||||||
fn update_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
|
fn update_stream(&self, stream: StreamToken, reg: Token, event_loop: &mut EventLoop<IoManager<NetworkIoMessage<Message>>>) {
|
||||||
match stream {
|
match stream {
|
||||||
FIRST_CONNECTION ... LAST_CONNECTION => {
|
FIRST_CONNECTION ... LAST_CONNECTION => {
|
||||||
if let Some(connection) = self.connections.read().unwrap().get(stream).cloned() {
|
let connection = { self.connections.read().unwrap().get(stream).cloned() };
|
||||||
|
if let Some(connection) = connection {
|
||||||
match *connection.lock().unwrap().deref() {
|
match *connection.lock().unwrap().deref() {
|
||||||
ConnectionEntry::Handshake(ref h) => h.update_socket(reg, event_loop).expect("Error updating socket"),
|
ConnectionEntry::Handshake(ref h) => h.update_socket(reg, event_loop).expect("Error updating socket"),
|
||||||
ConnectionEntry::Session(ref s) => s.update_socket(reg, event_loop).expect("Error updating socket"),
|
ConnectionEntry::Session(ref s) => s.update_socket(reg, event_loop).expect("Error updating socket"),
|
||||||
|
Loading…
Reference in New Issue
Block a user