diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp index 95965aed79..49fe0283fe 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.cpp @@ -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 diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h index ee5ff14ba5..816a2aad4c 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h +++ b/src/add-ons/kernel/network/protocols/tcp/TCPEndpoint.h @@ -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);