Added new function fixed_queue_flush() and the unit test
Change-Id: Ic90e3ffdcaea9573b135bd26ef102a1740fb2d3d
diff --git a/osi/include/fixed_queue.h b/osi/include/fixed_queue.h
index a125336..54f0093 100644
--- a/osi/include/fixed_queue.h
+++ b/osi/include/fixed_queue.h
@@ -40,10 +40,18 @@
// the returned queue with |fixed_queue_free|.
fixed_queue_t *fixed_queue_new(size_t capacity);
+// Frees a queue and (optionally) the enqueued elements.
+// |queue| is the queue to free. If the |free_cb| callback is not null,
+// it is called on each queue element to free it.
// Freeing a queue that is currently in use (i.e. has waiters
// blocked on it) results in undefined behaviour.
void fixed_queue_free(fixed_queue_t *queue, fixed_queue_free_cb free_cb);
+// Flushes a queue and (optionally) frees the enqueued elements.
+// |queue| is the queue to flush. If the |free_cb| callback is not null,
+// it is called on each queue element to free it.
+void fixed_queue_flush(fixed_queue_t *queue, fixed_queue_free_cb free_cb);
+
// Returns a value indicating whether the given |queue| is empty. If |queue|
// is NULL, the return value is true.
bool fixed_queue_is_empty(fixed_queue_t *queue);
diff --git a/osi/src/fixed_queue.c b/osi/src/fixed_queue.c
index be4f292..7f4f0ab 100644
--- a/osi/src/fixed_queue.c
+++ b/osi/src/fixed_queue.c
@@ -83,6 +83,18 @@
osi_free(queue);
}
+void fixed_queue_flush(fixed_queue_t *queue, fixed_queue_free_cb free_cb) {
+ if (!queue)
+ return;
+
+ while (!fixed_queue_is_empty(queue)) {
+ void *data = fixed_queue_try_dequeue(queue);
+ if (free_cb != NULL) {
+ free_cb(data);
+ }
+ }
+}
+
bool fixed_queue_is_empty(fixed_queue_t *queue) {
if (queue == NULL)
return true;
diff --git a/osi/test/fixed_queue_test.cc b/osi/test/fixed_queue_test.cc
index da7cf5c..675bd39 100644
--- a/osi/test/fixed_queue_test.cc
+++ b/osi/test/fixed_queue_test.cc
@@ -19,6 +19,8 @@
static const char *DUMMY_DATA_STRING3 = "Dummy data string3";
static future_t *received_message_future = NULL;
+static int test_queue_entry_free_counter = 0;
+
// Test whether a file descriptor |fd| is readable.
// Return true if the file descriptor is readable, otherwise false.
static bool is_fd_readable(int fd)
@@ -46,6 +48,14 @@
future_ready(received_message_future, msg);
}
+static void
+test_queue_entry_free_cb(void *data)
+{
+ // Don't free the data, because we are testing only whether the callback
+ // is called.
+ test_queue_entry_free_counter++;
+}
+
class FixedQueueTest : public AllocationTestHarness {};
TEST_F(FixedQueueTest, test_fixed_queue_new_free) {
@@ -76,6 +86,48 @@
fixed_queue_free(NULL, osi_free);
}
+TEST_F(FixedQueueTest, test_fixed_queue_flush) {
+ fixed_queue_t *queue;
+
+ // Test a corner case: queue of size 0 and no callback to free entries
+ queue = fixed_queue_new(0);
+ EXPECT_TRUE(queue != NULL);
+ fixed_queue_flush(queue, NULL);
+ EXPECT_TRUE(fixed_queue_is_empty(queue));
+ fixed_queue_free(queue, osi_free);
+
+ // Test a corner case: queue of size 0 and a callback to free entries
+ queue = fixed_queue_new(0);
+ EXPECT_TRUE(queue != NULL);
+ fixed_queue_flush(queue, osi_free);
+ EXPECT_TRUE(fixed_queue_is_empty(queue));
+ fixed_queue_free(queue, osi_free);
+
+ // Test a queue of some size and no callback to free entries
+ queue = fixed_queue_new(TEST_QUEUE_SIZE);
+ EXPECT_TRUE(queue != NULL);
+ fixed_queue_try_enqueue(queue, (void *)DUMMY_DATA_STRING1);
+ fixed_queue_try_enqueue(queue, (void *)DUMMY_DATA_STRING2);
+ fixed_queue_try_enqueue(queue, (void *)DUMMY_DATA_STRING3);
+ EXPECT_FALSE(fixed_queue_is_empty(queue));
+ fixed_queue_flush(queue, NULL);
+ EXPECT_TRUE(fixed_queue_is_empty(queue));
+ fixed_queue_free(queue, osi_free);
+
+ // Test a queue of some size and a callback to free entries
+ test_queue_entry_free_counter = 0;
+ queue = fixed_queue_new(TEST_QUEUE_SIZE);
+ EXPECT_TRUE(queue != NULL);
+ fixed_queue_try_enqueue(queue, (void *)DUMMY_DATA_STRING1);
+ fixed_queue_try_enqueue(queue, (void *)DUMMY_DATA_STRING2);
+ fixed_queue_try_enqueue(queue, (void *)DUMMY_DATA_STRING3);
+ EXPECT_FALSE(fixed_queue_is_empty(queue));
+ fixed_queue_flush(queue, test_queue_entry_free_cb);
+ EXPECT_TRUE(test_queue_entry_free_counter == 3);
+ EXPECT_TRUE(fixed_queue_is_empty(queue));
+ fixed_queue_free(queue, osi_free);
+}
+
TEST_F(FixedQueueTest, test_fixed_queue_is_empty) {
fixed_queue_t *queue;