1
0
mirror of https://github.com/fafhrd91/actix-net synced 2024-11-30 16:34:36 +01:00

Fix bug where paused Accept would register timed out sockets (#312)

This commit is contained in:
fakeshadow 2021-04-05 05:38:41 -07:00 committed by GitHub
parent f1573931dd
commit 995efcf427
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -300,27 +300,41 @@ impl Accept {
} }
fn deregister_all(&self, sockets: &mut Slab<ServerSocketInfo>) { fn deregister_all(&self, sockets: &mut Slab<ServerSocketInfo>) {
sockets.iter_mut().for_each(|(_, info)| { // This is a best effort implementation with following limitation:
self.deregister_logged(info); //
}); // Every ServerSocketInfo with associate timeout will be skipped and it's timeout
// is removed in the process.
//
// Therefore WakerInterest::Pause followed by WakerInterest::Resume in a very short
// gap (less than 500ms) would cause all timing out ServerSocketInfos be reregistered
// before expected timing.
sockets
.iter_mut()
// Take all timeout.
// This is to prevent Accept::process_timer method re-register a socket afterwards.
.map(|(_, info)| (info.timeout.take(), info))
// Socket info with a timeout is already deregistered so skip them.
.filter(|(timeout, _)| timeout.is_none())
.for_each(|(_, info)| self.deregister_logged(info));
} }
fn maybe_backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) { fn maybe_backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) {
// Only operate when server is in a different backpressure than the given flag. // Only operate when server is in a different backpressure than the given flag.
if self.backpressure != on { if self.backpressure != on {
if on { self.backpressure = on;
self.backpressure = true; sockets
// TODO: figure out if timing out sockets can be safely de-registered twice. .iter_mut()
self.deregister_all(sockets); // Only operate on sockets without associated timeout.
} else { // Sockets with it should be handled by `accept` and `process_timer` methods.
self.backpressure = false; // They are already deregistered or need to be reregister in the future.
sockets .filter(|(_, info)| info.timeout.is_none())
.iter_mut() .for_each(|(token, info)| {
// Only operate on sockets without associated timeout. if on {
// Sockets with it will attempt to re-register when their timeout expires. self.deregister_logged(info);
.filter(|(_, info)| info.timeout.is_none()) } else {
.for_each(|(token, info)| self.register_logged(token, info)); self.register_logged(token, info);
} }
});
} }
} }