unix: Implement SO_RCVBUF

Implemented `UnixBufferQueue::SetCapacity` so that `setsockopt`
with `SO_RCVBUF` will not always return an error.

Change-Id: I2d9be84633f84474fac64b379e9f89ef2751a094
Reviewed-on: https://review.haiku-os.org/c/haiku/+/6816
Reviewed-by: waddlesplash <[email protected]>
Tested-by: Commit checker robot <[email protected]>
This commit is contained in:
Trung Nguyen
2023-08-13 21:14:51 +00:00
committed by waddlesplash
parent 2b514ce830
commit 303ff56a5f
3 changed files with 56 additions and 2 deletions
@@ -44,6 +44,7 @@ ssize_t ring_buffer_user_write(struct ring_buffer *buffer, const uint8 *data, ss
size_t ring_buffer_peek(struct ring_buffer *buffer, size_t offset, void *data,
size_t length);
int32 ring_buffer_get_vecs(struct ring_buffer *buffer, struct iovec *vecs);
size_t ring_buffer_move(struct ring_buffer *to, ssize_t length, struct ring_buffer *from);
#ifdef __cplusplus
}
@@ -316,8 +316,20 @@ UnixBufferQueue::Write(UnixRequest& request)
status_t
UnixBufferQueue::SetCapacity(size_t capacity)
{
// TODO:...
return B_ERROR;
if (capacity <= fCapacity)
return B_OK;
ring_buffer* newBuffer = create_ring_buffer(capacity);
if (newBuffer == NULL)
return B_NO_MEMORY;
ring_buffer_move(newBuffer, ring_buffer_readable(fBuffer), fBuffer);
delete_ring_buffer(fBuffer);
fBuffer = newBuffer;
fCapacity = capacity;
return B_OK;
}
+41
View File
@@ -302,6 +302,47 @@ ring_buffer_get_vecs(struct ring_buffer* buffer, struct iovec* vecs)
}
/*! Moves data from one ring buffer to another.
\param to The destination ring buffer.
\param length The maximum number of bytes to move.
\param from The source ring buffer.
\return The number of bytes actually moved.
*/
size_t
ring_buffer_move(struct ring_buffer *to, ssize_t length,
struct ring_buffer *from)
{
if (length > from->in)
length = from->in;
if (length > (to->size - to->in))
length = to->size - to->in;
size_t bytesMoved = 0;
if ((from->first + length) <= from->size) {
// simple move
bytesMoved = ring_buffer_write(to, from->buffer + from->first, length);
} else {
// need to move both ends
size_t upper = from->size - from->first;
size_t lower = length - upper;
bytesMoved = ring_buffer_write(to, from->buffer + from->first, upper);
if (bytesMoved == upper) {
// only continue writing if the first part was completely written
bytesMoved += ring_buffer_write(to, from->buffer, lower);
}
}
from->first = (from->first + bytesMoved) % from->size;
from->in -= bytesMoved;
return bytesMoved;
}
#if 0
/** Sends the contents of the ring buffer to a port.
* The buffer will be empty afterwards only if sending the data actually works.