diff --git a/include/mp/proxy-io.h b/include/mp/proxy-io.h index c2a8d433..14edcf7c 100644 --- a/include/mp/proxy-io.h +++ b/include/mp/proxy-io.h @@ -905,6 +905,12 @@ void _Listen(const std::shared_ptr& listener, EventLoop& loop, InitImp if (resume_accept) _Listen(listener, loop, init); }); _Listen(listener, loop, init); + }, + // Keep listening if a single accept() fails, so the server does not + // stop accepting future connections. + [&loop, &init, listener](const kj::Exception& e) { + MP_LOG(loop, Log::Warning) << "IPC server: accept failed:" << kj::str(e).cStr(); + _Listen(listener, loop, init); })); } diff --git a/test/mp/test/listen_tests.cpp b/test/mp/test/listen_tests.cpp index 1506eaa4..54b4bd27 100644 --- a/test/mp/test/listen_tests.cpp +++ b/test/mp/test/listen_tests.cpp @@ -289,6 +289,21 @@ KJ_TEST("ListenConnections accepts multiple connections") KJ_EXPECT(client3->client->add(3, 4) == 7); } +KJ_TEST("ListenConnections survives a client that disconnects before being accepted") +{ + ListenSetup server; + + // Connect and close before the server has a chance to accept() the + // connection. + int fd = server.listener.MakeConnectedSocket(); + close(fd); + + // The server should still accept and serve later clients. + auto client = std::make_unique(server.listener.MakeConnectedSocket()); + server.WaitForConnectedCount(1); + KJ_EXPECT(client->client->add(1, 2) == 3); +} + } // namespace } // namespace test } // namespace mp