mirror of
https://github.com/fafhrd91/actix-net
synced 2024-11-24 00:01:11 +01:00
Fix bug where timed out socket would register itself when server in b… (#302)
Co-authored-by: Rob Ede <robjtede@icloud.com>
This commit is contained in:
parent
ee3a548a85
commit
2c5c9167a5
@ -187,21 +187,19 @@ impl Accept {
|
|||||||
let mut guard = self.waker.guard();
|
let mut guard = self.waker.guard();
|
||||||
match guard.pop_front() {
|
match guard.pop_front() {
|
||||||
// worker notify it becomes available. we may want to recover
|
// worker notify it becomes available. we may want to recover
|
||||||
// from backpressure.
|
// from backpressure.
|
||||||
Some(WakerInterest::WorkerAvailable) => {
|
Some(WakerInterest::WorkerAvailable) => {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
self.maybe_backpressure(&mut sockets, false);
|
self.maybe_backpressure(&mut sockets, false);
|
||||||
}
|
}
|
||||||
// a new worker thread is made and it's handle would be added
|
// a new worker thread is made and it's handle would be added to Accept
|
||||||
// to Accept
|
|
||||||
Some(WakerInterest::Worker(handle)) => {
|
Some(WakerInterest::Worker(handle)) => {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
// maybe we want to recover from a backpressure.
|
// maybe we want to recover from a backpressure.
|
||||||
self.maybe_backpressure(&mut sockets, false);
|
self.maybe_backpressure(&mut sockets, false);
|
||||||
self.handles.push(handle);
|
self.handles.push(handle);
|
||||||
}
|
}
|
||||||
// got timer interest and it's time to try register socket(s)
|
// got timer interest and it's time to try register socket(s) again
|
||||||
// again.
|
|
||||||
Some(WakerInterest::Timer) => {
|
Some(WakerInterest::Timer) => {
|
||||||
drop(guard);
|
drop(guard);
|
||||||
self.process_timer(&mut sockets)
|
self.process_timer(&mut sockets)
|
||||||
@ -238,16 +236,23 @@ impl Accept {
|
|||||||
|
|
||||||
fn process_timer(&self, sockets: &mut Slab<ServerSocketInfo>) {
|
fn process_timer(&self, sockets: &mut Slab<ServerSocketInfo>) {
|
||||||
let now = Instant::now();
|
let now = Instant::now();
|
||||||
sockets.iter_mut().for_each(|(token, info)| {
|
sockets
|
||||||
// only the ServerSocketInfo have an associate timeout value was de registered.
|
.iter_mut()
|
||||||
if let Some(inst) = info.timeout.take() {
|
// Only sockets that had an associated timeout were deregistered.
|
||||||
if now > inst {
|
.filter(|(_, info)| info.timeout.is_some())
|
||||||
self.register_logged(token, info);
|
.for_each(|(token, info)| {
|
||||||
} else {
|
let inst = info.timeout.take().unwrap();
|
||||||
|
|
||||||
|
if now < inst {
|
||||||
info.timeout = Some(inst);
|
info.timeout = Some(inst);
|
||||||
|
} else if !self.backpressure {
|
||||||
|
self.register_logged(token, info);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
});
|
// Drop the timeout if server is in backpressure and socket timeout is expired.
|
||||||
|
// When server recovers from backpressure it will register all sockets without
|
||||||
|
// a timeout value so this socket register will be delayed till then.
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(target_os = "windows"))]
|
#[cfg(not(target_os = "windows"))]
|
||||||
@ -301,20 +306,21 @@ impl Accept {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn maybe_backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) {
|
fn maybe_backpressure(&mut self, sockets: &mut Slab<ServerSocketInfo>, on: bool) {
|
||||||
if self.backpressure {
|
// Only operate when server is in a different backpressure than the given flag.
|
||||||
if !on {
|
if self.backpressure != on {
|
||||||
|
if on {
|
||||||
|
self.backpressure = true;
|
||||||
|
// TODO: figure out if timing out sockets can be safely de-registered twice.
|
||||||
|
self.deregister_all(sockets);
|
||||||
|
} else {
|
||||||
self.backpressure = false;
|
self.backpressure = false;
|
||||||
for (token, info) in sockets.iter_mut() {
|
sockets
|
||||||
if info.timeout.is_some() {
|
.iter_mut()
|
||||||
// socket will attempt to re-register itself when its timeout completes
|
// Only operate on sockets without associated timeout.
|
||||||
continue;
|
// Sockets with it will attempt to re-register when their timeout expires.
|
||||||
}
|
.filter(|(_, info)| info.timeout.is_none())
|
||||||
self.register_logged(token, info);
|
.for_each(|(token, info)| self.register_logged(token, info));
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if on {
|
|
||||||
self.backpressure = true;
|
|
||||||
self.deregister_all(sockets);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user