Loading test/httpd_h1_offload_test.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -95,21 +95,37 @@ public: // RunningServer: netplus::event's connection registry and Running/Restart // flags are process-wide statics, so a server's background threads must be // fully stopped and joined before the next one starts. // // Unlike that test, this one runs THREE server instances in the same // process (keep-alive, sync saturation, offload saturation) instead of two. // netplus's poll::poll() ctor unconditionally appends the listening socket // pointer to a process-wide static SSOCKETS registry that cleanupConnections() // (called at the end of every runEventloop()) later dereferences and // close()s -- but nothing ever removes a stale entry once its owning socket // is destroyed. A THIRD server whose predecessor's listener socket has // already been destructed hits a real use-after-free in that registry (not // anything this test's own H1-offload feature causes). Sidestep it here by // never destructing a listener socket mid-test: every one this test ever // binds is kept alive (in allListenerSocks below) until process exit, even // though each individual server only uses its own for one phase. struct RunningServer { std::unique_ptr<netplus::tcp> sock; std::unique_ptr<H1SlowServer> server; std::thread thread; }; std::vector<std::unique_ptr<netplus::tcp>> allListenerSocks; RunningServer startServer(int &port, size_t h1OffloadThreads) { RunningServer rs; rs.sock = std::make_unique<netplus::tcp>("127.0.0.1", 0, 128, -1); rs.sock->bind(); port = rawtcp::boundPort(*rs.sock); rs.sock->listen(); auto sock = std::make_unique<netplus::tcp>("127.0.0.1", 0, 128, -1); sock->bind(); port = rawtcp::boundPort(*sock); sock->listen(); netplus::tcp *sockPtr = sock.get(); allListenerSocks.push_back(std::move(sock)); RunningServer rs; rs.server = std::make_unique<H1SlowServer>( std::vector<netplus::socket*>{rs.sock.get()}, h1OffloadThreads); std::vector<netplus::socket*>{sockPtr}, h1OffloadThreads); netplus::event::Running = true; H1SlowServer *serverPtr = rs.server.get(); rs.thread = std::thread([serverPtr] { serverPtr->runEventloop(); }); Loading Loading
test/httpd_h1_offload_test.cpp +23 −7 Original line number Diff line number Diff line Loading @@ -95,21 +95,37 @@ public: // RunningServer: netplus::event's connection registry and Running/Restart // flags are process-wide statics, so a server's background threads must be // fully stopped and joined before the next one starts. // // Unlike that test, this one runs THREE server instances in the same // process (keep-alive, sync saturation, offload saturation) instead of two. // netplus's poll::poll() ctor unconditionally appends the listening socket // pointer to a process-wide static SSOCKETS registry that cleanupConnections() // (called at the end of every runEventloop()) later dereferences and // close()s -- but nothing ever removes a stale entry once its owning socket // is destroyed. A THIRD server whose predecessor's listener socket has // already been destructed hits a real use-after-free in that registry (not // anything this test's own H1-offload feature causes). Sidestep it here by // never destructing a listener socket mid-test: every one this test ever // binds is kept alive (in allListenerSocks below) until process exit, even // though each individual server only uses its own for one phase. struct RunningServer { std::unique_ptr<netplus::tcp> sock; std::unique_ptr<H1SlowServer> server; std::thread thread; }; std::vector<std::unique_ptr<netplus::tcp>> allListenerSocks; RunningServer startServer(int &port, size_t h1OffloadThreads) { RunningServer rs; rs.sock = std::make_unique<netplus::tcp>("127.0.0.1", 0, 128, -1); rs.sock->bind(); port = rawtcp::boundPort(*rs.sock); rs.sock->listen(); auto sock = std::make_unique<netplus::tcp>("127.0.0.1", 0, 128, -1); sock->bind(); port = rawtcp::boundPort(*sock); sock->listen(); netplus::tcp *sockPtr = sock.get(); allListenerSocks.push_back(std::move(sock)); RunningServer rs; rs.server = std::make_unique<H1SlowServer>( std::vector<netplus::socket*>{rs.sock.get()}, h1OffloadThreads); std::vector<netplus::socket*>{sockPtr}, h1OffloadThreads); netplus::event::Running = true; H1SlowServer *serverPtr = rs.server.get(); rs.thread = std::thread([serverPtr] { serverPtr->runEventloop(); }); Loading