Signed-off-by: Angus Salkeld <asalkeld(a)redhat.com>
---
include/qb/qbrb.h | 2 +-
lib/ringbuffer.c | 25 +++++++++++++++++++++----
tests/check_rb.c | 6 +++---
3 files changed, 25 insertions(+), 8 deletions(-)
diff --git a/include/qb/qbrb.h b/include/qb/qbrb.h
index 94aaa91..0776a5b 100644
--- a/include/qb/qbrb.h
+++ b/include/qb/qbrb.h
@@ -183,7 +183,7 @@ int32_t qb_rb_chunk_commit(qb_ringbuffer_t * rb, size_t len);
*
* @return the size of the chunk (0 if buffer empty).
*/
-ssize_t qb_rb_chunk_peek(qb_ringbuffer_t * rb, void **data_out);
+ssize_t qb_rb_chunk_peek(qb_ringbuffer_t * rb, void **data_out, int32_t ms_timeout);
/**
* Reclaim the oldest chunk.
diff --git a/lib/ringbuffer.c b/lib/ringbuffer.c
index 8bbff84..e006e6f 100644
--- a/lib/ringbuffer.c
+++ b/lib/ringbuffer.c
@@ -452,12 +452,29 @@ void qb_rb_chunk_reclaim(qb_ringbuffer_t * rb)
rb->unlock_fn(rb);
}
-ssize_t qb_rb_chunk_peek(qb_ringbuffer_t * rb, void **data_out)
+ssize_t qb_rb_chunk_peek(qb_ringbuffer_t * rb, void **data_out, int32_t
+ timeout)
{
- uint32_t read_pt = rb->shared_hdr->read_pt;
- uint32_t chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
- uint32_t chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt);
+ uint32_t read_pt;
+ uint32_t chunk_size;
+ uint32_t chunk_magic;
+ int32_t res;
+ res = rb->sem_timedwait_fn(rb, timeout);
+ if (res == -1 && errno == ETIMEDOUT && rb->shared_hdr->count >
0) {
+ qb_util_log(LOG_ERR,
+ "sem timedout but count is %d",
+ rb->shared_hdr->count);
+ } else if (res == -1 && errno != EIDRM) {
+ if (errno != ETIMEDOUT) {
+ qb_util_log(LOG_ERR,
+ "sem_timedwait %s", strerror(errno));
+ }
+ return -1;
+ }
+ read_pt = rb->shared_hdr->read_pt;
+ chunk_size = QB_RB_CHUNK_SIZE_GET(rb, read_pt);
+ chunk_magic = QB_RB_CHUNK_MAGIC_GET(rb, read_pt);
*data_out = &rb->shared_data[read_pt + QB_RB_CHUNK_HEADER_WORDS];
if (chunk_magic != QB_RB_CHUNK_MAGIC) {
diff --git a/tests/check_rb.c b/tests/check_rb.c
index f01bed2..9b8a2c2 100644
--- a/tests/check_rb.c
+++ b/tests/check_rb.c
@@ -100,7 +100,7 @@ START_TEST(test_ring_buffer2)
ck_assert_int_eq(l, sizeof(v));
}
for (i = 0; i < 100; i++) {
- l = qb_rb_chunk_peek(t, (void **)&new_data);
+ l = qb_rb_chunk_peek(t, (void **)&new_data, 0);
if (l == -1) {
/* no more to read */
break;
@@ -114,7 +114,7 @@ START_TEST(test_ring_buffer2)
ck_assert_int_eq(l, sizeof(v));
}
for (i = 0; i < 100; i++) {
- l = qb_rb_chunk_peek(t, (void **)&new_data);
+ l = qb_rb_chunk_peek(t, (void **)&new_data, 0);
if (l == -1) {
/* no more to read */
break;
@@ -175,7 +175,7 @@ END_TEST START_TEST(test_ring_buffer4)
}
}
for (i = 0; i < 2000; i++) {
- l = qb_rb_chunk_peek(t, (void **)&new_data);
+ l = qb_rb_chunk_peek(t, (void **)&new_data, 0);
if (l == -1 && errno == ENODATA) {
break;
}
--
1.6.6.1