MEDIUM: listener: remove the second pass of fd manipulation at the end

The receiver FDs must not be manipulated by the listener_accept()
function anymore, it must exclusively rely on the job performed by
its listeners, as it is also the only way to keep the receivers
working for established connections regardless of the listener's
state (typically for multiplexed protocols like QUIC). This used
to be necessary when the FDs were adjusted at once only but now
that fd_done() is gone and the need for polling enabled by the
accept_conn() function which detects the EAGAIN, we have nothing
to do there to fixup any possible previous bad decision anymore.

Interestingly, as a side effect of making the code not depend on
the FD anymore, it also removes the need for a second lock, which
increase the accept rate by about 1% on 8 threads.
This commit is contained in:
Willy Tarreau 2020-10-15 20:27:02 +02:00
parent 9378bbe0be
commit caa91de718

View File

@ -1042,23 +1042,6 @@ void listener_accept(int fd)
(!p->fe_sps_lim || freq_ctr_remain(&p->fe_sess_per_sec, p->fe_sps_lim, 0) > 0))
dequeue_proxy_listeners(p);
}
/* Now it's getting tricky. The listener was supposed to be in LI_READY
* state but in the mean time we might have changed it to LI_FULL or
* LI_LIMITED, and another thread might also have turned it to
* LI_PAUSED, LI_LISTEN or even LI_INI when stopping a proxy. We must
* be certain to keep the FD enabled when in the READY state but we
* must also stop it for other states that we might have switched to
* while others re-enabled polling.
*/
HA_SPIN_LOCK(LISTENER_LOCK, &l->lock);
if (l->state == LI_READY) {
if (max_accept > 0)
fd_cant_recv(fd);
} else if (l->state > LI_ASSIGNED) {
fd_stop_recv(l->rx.fd);
}
HA_SPIN_UNLOCK(LISTENER_LOCK, &l->lock);
return;
transient_error: