diff --git a/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp b/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp index 2c03ce361b..89e30ead2f 100644 --- a/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/BufferQueue.cpp @@ -287,10 +287,9 @@ BufferQueue::Get(size_t bytes, bool remove, net_buffer **_buffer) } else { // we can reuse this buffer bytesLeft -= buffer->size; - fList.Remove(buffer); + fFirstSequence += buffer->size; - if (fList.First() != NULL) - fFirstSequence = fList.First()->sequence; + fList.Remove(buffer); } // clone/copy the remaining data @@ -311,11 +310,15 @@ BufferQueue::Get(size_t bytes, bool remove, net_buffer **_buffer) // remove either the whole buffer or only the part we cloned + fFirstSequence += size; + if (size == source->size) { iterator.Remove(); gBufferModule->free(source); - } else + } else { gBufferModule->remove_header(source, size); + source->sequence += size; + } } if (status == B_OK) { diff --git a/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp b/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp index 355909cf27..60e32dcb5f 100644 --- a/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp +++ b/src/add-ons/kernel/network/protocols/tcp/TCPConnection.cpp @@ -384,6 +384,19 @@ TCPConnection::SendData(net_buffer *buffer) { TRACE(("TCP:%p.SendData()\n", this)); + // TODO: hangs if the buffer size is larger than the maximum! + while (fSendQueue.Free() < buffer->size) { + status_t status = acquire_sem_etc(fSendLock, 1, + B_RELATIVE_TIMEOUT | B_CAN_INTERRUPT, socket->send.timeout); + if (status < B_OK) + return status; + } + + // TODO: check state! + + if (buffer->size == 0) + return B_OK; + RecursiveLocker locker(fLock); fSendQueue.Add(buffer); return _SendQueued();