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:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user