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
}
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;
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;
}