From 68dd93a65246c912ba098a3fd6eb388de4e33b3b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 7 Apr 2009 00:18:40 +0000 Subject: [PATCH] * Fixed TCPEndpoint::Listen() never setting the backlog on its socket, causing only a single pending connection to be accepted at once. * Fixed discarding endpoints that still had a parent, but were closed before they could be accepted (or even established). Previously, these were never deleted, slowly filling up the socket's backlog. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@29987 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../network/protocols/tcp/TCPEndpoint.cpp | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index cdc3b2e1ce..c6ec676e96 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -711,7 +711,7 @@ TCPEndpoint::Unbind(struct sockaddr *address) { TRACE("Unbind()"); - MutexLocker lock(fLock); + MutexLocker _(fLock); return fManager->Unbind(this); } @@ -721,7 +721,7 @@ TCPEndpoint::Listen(int count) { TRACE("Listen()"); - MutexLocker lock(fLock); + MutexLocker _(fLock); if (fState != CLOSED) return B_BAD_VALUE; @@ -731,12 +731,14 @@ TCPEndpoint::Listen(int count) return ENOBUFS; status_t status = fManager->SetPassive(this); - if (status < B_OK) { + if (status != B_OK) { delete_sem(fAcceptSemaphore); fAcceptSemaphore = -1; return status; } + gSocketModule->set_max_backlog(socket, count); + fState = LISTEN; T(State(this)); return B_OK; @@ -1179,8 +1181,8 @@ TCPEndpoint::_MarkEstablished() status_t TCPEndpoint::_WaitForEstablished(MutexLocker &locker, bigtime_t timeout) { -// TODO: Checking for CLOSED seems correct, but breaks several neon tests. -// When investigating this, also have a look at _Close() and _HandleReset(). + // TODO: Checking for CLOSED seems correct, but breaks several neon tests. + // When investigating this, also have a look at _Close() and _HandleReset(). while (fState < ESTABLISHED/* && fState != CLOSED*/) { if (socket->error != B_OK) return socket->error; @@ -1208,6 +1210,15 @@ TCPEndpoint::_Close() fSendList.Signal(); _NotifyReader(); + + if (socket->parent != NULL) { + // We still have a parent - obviously, we haven't been accepted yet, + // so no one could ever close us. + // Since we can't just delete ourself here, we trigger an immediate + // time-wait timer. + _CancelConnectionTimers(); + gStackModule->set_timer(&fTimeWaitTimer, 0); + } }