Commit 2f80fdb6 authored by jan.koester's avatar jan.koester
Browse files

tetst

parent e14fb2dd
Loading
Loading
Loading
Loading
+24 −6
Original line number Diff line number Diff line
@@ -809,14 +809,32 @@ namespace netplus {
            // triggered + shared epoll fd meant every datagram woke all
            // `threads` workers, and only one could ever do anything
            // useful while the rest contended on that single mutex for
            // nothing. Each connection now has its own quic_mtx(), and
            // nothing.
            //
            // Each connection now has its own quic_mtx(), and
            // _child_connections lookups/mutations go through their own
            // short-lived _registry_mutex (see quic::accept()), so
            // multiple threads calling accept() concurrently on this fd
            // now actually process different connections in parallel
            // instead of serializing on one lock — recvmmsg on the same
            // fd from multiple threads is safe (the kernel hands out
            // disjoint datagrams, never duplicates).
            // different connections CAN be processed by different threads
            // in parallel instead of serializing on one lock. But plain
            // EPOLLIN without ONESHOT still wakes every worker per event
            // (thundering herd): measured under concurrent load (24
            // simultaneous new connections, see quic_concurrent_test) this
            // made things drastically worse, not better — `threads`
            // workers (one per core) all piling into accept()/recvmmsg for
            // the same handful of datagrams starved the CPU time actual
            // packet processing needed, cascading into handshake timeouts.
            // EPOLLEXCLUSIVE (Linux >= 4.5) is the fix purpose-built for
            // this: only one waiter is woken per readiness event instead
            // of all of them, but — unlike EPOLLONESHOT — no explicit
            // rearm is needed and a different thread is free to pick up
            // the next event, so cross-connection parallelism is kept
            // without the herd. (Not recommended to combine with
            // EPOLLONESHOT, which is why this is the only flag added.)
            // Scoped to QUIC only — TCP/SSL listeners weren't part of what
            // this was measured against, so left as before.
            if (ss->_Type == sockettype::QUIC) {
                setevent.events |= EPOLLEXCLUSIVE;
            }
            setevent.data.fd = ss->fd();

            if (epoll_ctl(_pollFD, EPOLL_CTL_ADD, ss->fd(), &setevent) < 0) {