mirror of
http://git.haproxy.org/git/haproxy.git
synced 2026-02-10 15:52:47 +02:00
There is one point where we can migrate a connection to another thread without taking risk, it's when we accept it : the new FD is not yet in the fd cache and no task was created yet. It's still possible to assign it a different thread than the one which accepted the connection. The only requirement for this is to have one accept queue per thread and their respective processing tasks that have to be woken up each time an entry is added to the queue. This is a multiple-producer, single-consumer model. Entries are added at the queue's tail and the processing task is woken up. The consumer picks entries at the head and processes them in order. The accept queue contains the fd, the source address, and the listener. Each entry of the accept queue was rounded up to 64 bytes (one cache line) to avoid cache aliasing because tests have shown that otherwise performance suffers a lot (5%). A test has shown that it's important to have at least 256 entries for the rings, as at 128 it's still possible to fill them often at high loads on small thread counts. The processing task does almost nothing except calling the listener's accept() function and updating the global session and SSL rate counters just like listener_accept() does on synchronous calls. At this point the accept queue is implemented but not used.