From 47d4b31dc9703024784af6af0a906d9458f648bf Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 4 Feb 2020 15:44:55 -0500 Subject: [PATCH] lib ring buffer iterator: introduce lib_ring_buffer_put_current_record Ensure that the current subbuffer is put after client code has read the payload of the current record. Signed-off-by: Mathieu Desnoyers Change-Id: Id2173ea67213f7ef8e7395b49c5aa8fff0aefffc --- include/ringbuffer/iterator.h | 9 +++++++++ src/lib/ringbuffer/ring_buffer_iterator.c | 24 +++++++++++++++++++++-- 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/include/ringbuffer/iterator.h b/include/ringbuffer/iterator.h index a006ed00..a9879903 100644 --- a/include/ringbuffer/iterator.h +++ b/include/ringbuffer/iterator.h @@ -23,6 +23,15 @@ extern ssize_t lib_ring_buffer_get_next_record(struct channel *chan, struct lib_ring_buffer *buf); +/* + * Ensure that the current subbuffer is put after client code has read the + * payload of the current record. Has an effect when the end of subbuffer is + * reached. It is not required if get_next_record is called successively. + * However, it should be invoked before returning data to user-space to ensure + * that the get/put subbuffer state is quiescent. + */ +extern void lib_ring_buffer_put_current_record(struct lib_ring_buffer *buf); + /* * channel_get_next_record advances the buffer read position to the next record. * It returns either the size of the next record, -EAGAIN if there is currently diff --git a/src/lib/ringbuffer/ring_buffer_iterator.c b/src/lib/ringbuffer/ring_buffer_iterator.c index a136a8fa..da19d280 100644 --- a/src/lib/ringbuffer/ring_buffer_iterator.c +++ b/src/lib/ringbuffer/ring_buffer_iterator.c @@ -105,6 +105,24 @@ restart: } EXPORT_SYMBOL_GPL(lib_ring_buffer_get_next_record); +void lib_ring_buffer_put_current_record(struct lib_ring_buffer *buf) +{ + struct lib_ring_buffer_iter *iter; + + if (!buf) + return; + iter = &buf->iter; + if (iter->state != ITER_NEXT_RECORD) + return; + iter->read_offset += iter->payload_len; + iter->state = ITER_TEST_RECORD; + if (iter->read_offset - iter->consumed >= iter->data_size) { + lib_ring_buffer_put_next_subbuf(buf); + iter->state = ITER_GET_SUBBUF; + } +} +EXPORT_SYMBOL_GPL(lib_ring_buffer_put_current_record); + static int buf_is_higher(void *a, void *b) { struct lib_ring_buffer *bufa = a; @@ -696,12 +714,14 @@ skip_get_next: return -EFAULT; } read_count += copy_len; - }; - return read_count; + } + goto put_record; nodata: *ppos = 0; chan->iter.len_left = 0; +put_record: + lib_ring_buffer_put_current_record(buf); return read_count; } -- 2.34.1