* 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
This commit is contained in:
Axel Dörfler 2009-04-07 00:18:40 +00:00
parent ab134c0a9a
commit 68dd93a652
1 changed files with 16 additions and 5 deletions

View File

@ -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);
}
}