mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-22 06:59:59 -05:00
ringbuffer: simplify the API
Use absolute indexes that we let wrap around. We can then easily detect how much we under of overflowed by using serial number arithmetic. Remove the Areas, we can trivially compute this ourselves, move the logic in read/write_data.
This commit is contained in:
parent
90ea120d3c
commit
0b508db9fc
6 changed files with 107 additions and 138 deletions
|
|
@ -182,32 +182,45 @@ loop_invoke (SpaLoop *loop,
|
|||
{
|
||||
PinosLoopImpl *impl = SPA_CONTAINER_OF (loop, PinosLoopImpl, loop);
|
||||
bool in_thread = pthread_equal (impl->thread, pthread_self());
|
||||
SpaRingbufferArea areas[2];
|
||||
InvokeItem *item;
|
||||
SpaResult res;
|
||||
|
||||
if (in_thread) {
|
||||
res = func (loop, false, seq, size, data, user_data);
|
||||
} else {
|
||||
spa_ringbuffer_get_write_areas (&impl->buffer, areas);
|
||||
if (areas[0].len < sizeof (InvokeItem)) {
|
||||
pinos_log_warn ("data-loop %p: queue full", impl);
|
||||
int32_t filled, avail;
|
||||
uint32_t offset, l0;
|
||||
|
||||
filled = spa_ringbuffer_get_write_index (&impl->buffer, &offset);
|
||||
if (filled < 0 || filled > impl->buffer.size) {
|
||||
pinos_log_warn ("data-loop %p: queue xrun %d", impl, filled);
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
item = SPA_MEMBER (impl->buffer_data, areas[0].offset, InvokeItem);
|
||||
avail = impl->buffer.size - filled;
|
||||
if (avail < sizeof (InvokeItem)) {
|
||||
pinos_log_warn ("data-loop %p: queue full %d", impl, avail);
|
||||
return SPA_RESULT_ERROR;
|
||||
}
|
||||
offset &= impl->buffer.mask;
|
||||
|
||||
l0 = offset + avail;
|
||||
if (l0 > impl->buffer.size)
|
||||
l0 = impl->buffer.size - l0;
|
||||
|
||||
item = SPA_MEMBER (impl->buffer_data, offset, InvokeItem);
|
||||
item->func = func;
|
||||
item->seq = seq;
|
||||
item->size = size;
|
||||
item->user_data = user_data;
|
||||
|
||||
if (areas[0].len > sizeof (InvokeItem) + size) {
|
||||
if (l0 > sizeof (InvokeItem) + size) {
|
||||
item->data = SPA_MEMBER (item, sizeof (InvokeItem), void);
|
||||
item->item_size = sizeof (InvokeItem) + size;
|
||||
if (areas[0].len < sizeof (InvokeItem) + item->item_size)
|
||||
item->item_size = areas[0].len;
|
||||
if (l0 < sizeof (InvokeItem) + item->item_size)
|
||||
item->item_size = l0;
|
||||
} else {
|
||||
item->data = SPA_MEMBER (impl->buffer_data, areas[1].offset, void);
|
||||
item->item_size = areas[0].len + 1 + size;
|
||||
item->data = impl->buffer_data;
|
||||
item->item_size = l0 + 1 + size;
|
||||
}
|
||||
memcpy (item->data, data, size);
|
||||
|
||||
|
|
@ -231,8 +244,8 @@ event_func (SpaLoopUtils *utils,
|
|||
PinosLoopImpl *impl = data;
|
||||
uint32_t offset;
|
||||
|
||||
while (spa_ringbuffer_get_read_offset (&impl->buffer, &offset) > 0) {
|
||||
InvokeItem *item = SPA_MEMBER (impl->buffer_data, offset, InvokeItem);
|
||||
while (spa_ringbuffer_get_read_index (&impl->buffer, &offset) > 0) {
|
||||
InvokeItem *item = SPA_MEMBER (impl->buffer_data, offset & impl->buffer.mask, InvokeItem);
|
||||
item->func (impl->this.loop, true, item->seq, item->size, item->data, item->user_data);
|
||||
spa_ringbuffer_read_advance (&impl->buffer, item->item_size);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -38,8 +38,8 @@ typedef struct {
|
|||
PinosMemblock mem;
|
||||
size_t offset;
|
||||
|
||||
SpaRingbufferArea areas[2];
|
||||
SpaEvent current;
|
||||
uint32_t current_offset;
|
||||
} PinosTransportImpl;
|
||||
|
||||
static size_t
|
||||
|
|
@ -206,20 +206,21 @@ pinos_transport_add_event (PinosTransport *trans,
|
|||
SpaEvent *event)
|
||||
{
|
||||
PinosTransportImpl *impl = (PinosTransportImpl *) trans;
|
||||
SpaRingbufferArea areas[2];
|
||||
size_t avail, size;
|
||||
int32_t filled, avail;
|
||||
uint32_t size, index;
|
||||
|
||||
if (impl == NULL || event == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
filled = spa_ringbuffer_get_write_index (trans->output_buffer, &index);
|
||||
avail = trans->output_buffer->size - filled;
|
||||
size = SPA_POD_SIZE (event);
|
||||
avail = spa_ringbuffer_get_write_areas (trans->output_buffer, areas);
|
||||
if (avail < size)
|
||||
return SPA_RESULT_ERROR;
|
||||
|
||||
spa_ringbuffer_write_data (trans->output_buffer,
|
||||
trans->output_data,
|
||||
areas,
|
||||
index & trans->output_buffer->mask,
|
||||
event,
|
||||
size);
|
||||
spa_ringbuffer_write_advance (trans->output_buffer, size);
|
||||
|
|
@ -232,18 +233,21 @@ pinos_transport_next_event (PinosTransport *trans,
|
|||
SpaEvent *event)
|
||||
{
|
||||
PinosTransportImpl *impl = (PinosTransportImpl *) trans;
|
||||
size_t avail;
|
||||
int32_t avail;
|
||||
uint32_t index;
|
||||
|
||||
if (impl == NULL || event == NULL)
|
||||
return SPA_RESULT_INVALID_ARGUMENTS;
|
||||
|
||||
avail = spa_ringbuffer_get_read_areas (trans->input_buffer, impl->areas);
|
||||
avail = spa_ringbuffer_get_read_index (trans->input_buffer, &index);
|
||||
if (avail < sizeof (SpaEvent))
|
||||
return SPA_RESULT_ENUM_END;
|
||||
|
||||
impl->current_offset = index & trans->input_buffer->mask;
|
||||
|
||||
spa_ringbuffer_read_data (trans->input_buffer,
|
||||
trans->input_data,
|
||||
impl->areas,
|
||||
impl->current_offset,
|
||||
&impl->current,
|
||||
sizeof (SpaEvent));
|
||||
|
||||
|
|
@ -266,7 +270,7 @@ pinos_transport_parse_event (PinosTransport *trans,
|
|||
|
||||
spa_ringbuffer_read_data (trans->input_buffer,
|
||||
trans->input_data,
|
||||
impl->areas,
|
||||
impl->current_offset,
|
||||
event,
|
||||
size);
|
||||
spa_ringbuffer_read_advance (trans->input_buffer, size);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue