fixed a bug in TCP where applications weren't properly signaled when the connection was terminated by the server and there was no more data to be read from the buffer.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@20534 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Hugo Santos
2007-04-03 14:25:53 +00:00
parent 2d1f81eb1d
commit 3537f0967f
2 changed files with 21 additions and 6 deletions
@@ -430,7 +430,7 @@ TRACE((" TCP:%p.Send() split buffer at %lu (buffer size %lu, mss %lu) -> %p\n",
}
size_t
ssize_t
TCPEndpoint::SendAvailable()
{
TRACE(("TCP:%p.SendAvailable()\n", this));
@@ -487,13 +487,13 @@ TCPEndpoint::ReadData(size_t numBytes, uint32 flags, net_buffer** _buffer)
}
size_t
ssize_t
TCPEndpoint::ReadAvailable()
{
TRACE(("TCP:%p.ReadAvailable()\n", this));
RecursiveLocker locker(fLock);
return fReceiveQueue.Available();
return _AvailableBytesOrDisconnect();
}
@@ -934,7 +934,7 @@ TCPEndpoint::Receive(tcp_segment_header &segment, net_buffer *buffer)
release_sem_etc(fReceiveLock, 1, B_DO_NOT_RESCHEDULE);
// TODO: real conditional locking needed!
gSocketModule->notify(socket, B_SELECT_READ, fReceiveQueue.Available());
gSocketModule->notify(socket, B_SELECT_READ, _AvailableBytesOrDisconnect());
// other side is closing connection; change states
switch (fState) {
@@ -1218,6 +1218,20 @@ TCPEndpoint::_GetMSS(const sockaddr *address) const
}
ssize_t
TCPEndpoint::_AvailableBytesOrDisconnect() const
{
size_t availableBytes = fReceiveQueue.Available();
if (availableBytes > 0)
return availableBytes;
if ((fFlags & FLAG_NO_RECEIVE) != 0)
return ENOTCONN;
return 0;
}
// #pragma mark - timer
@@ -41,9 +41,9 @@ class TCPEndpoint : public net_protocol {
status_t Listen(int count);
status_t Shutdown(int direction);
status_t SendData(net_buffer *buffer);
size_t SendAvailable();
ssize_t SendAvailable();
status_t ReadData(size_t numBytes, uint32 flags, net_buffer **_buffer);
size_t ReadAvailable();
ssize_t ReadAvailable();
tcp_state State() const { return fState; }
bool IsBound() const;
@@ -66,6 +66,7 @@ class TCPEndpoint : public net_protocol {
bool outstandingAcknowledge);
status_t _SendQueued(bool force = false);
int _GetMSS(const struct sockaddr *) const;
ssize_t _AvailableBytesOrDisconnect() const;
static void _TimeWaitTimer(net_timer *timer, void *data);
static void _RetransmitTimer(net_timer *timer, void *data);