]> git.ipfire.org Git - pakfire.git/commitdiff
log buffer: Implemnent ring buffer behaviour
authorMichael Tremer <michael.tremer@ipfire.org>
Wed, 5 Feb 2025 10:07:52 +0000 (10:07 +0000)
committerMichael Tremer <michael.tremer@ipfire.org>
Wed, 5 Feb 2025 10:07:52 +0000 (10:07 +0000)
I don't know why I didn't implement this straight away as this was
always intended to be a ring buffer.

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
src/pakfire/log_buffer.c
tests/libpakfire/log_buffer.c

index ee3b3e1470880f2b868badd3661308a393ca63c8..3cfafac8a5c427b3675fbf6d6022e126c99c7b8a 100644 (file)
@@ -96,17 +96,35 @@ struct pakfire_log_buffer* pakfire_log_buffer_unref(struct pakfire_log_buffer* b
        return NULL;
 }
 
+static int pakfire_log_buffer_drop(struct pakfire_log_buffer* self) {
+       int priority = 0;
+       char* line = NULL;
+       int r;
+
+       // Dequeue one line
+       r = pakfire_log_buffer_dequeue(self, &priority, &line, NULL);
+       if (r < 0)
+               return r;
+
+       // Free the line
+       free(line);
+
+       return 0;
+}
+
 int pakfire_log_buffer_enqueue(struct pakfire_log_buffer* buffer, int priority, const char* line, ssize_t length) {
        struct pakfire_log_line* l = NULL;
+       int r;
 
        // Check input
        if (priority <= 0 || !line)
                return -EINVAL;
 
-       // Fail if the buffer is full
-       if (buffer->max_length > 0) {
-               if (buffer->length >= buffer->max_length)
-                       return -ENOBUFS;
+       // Drop a previously inserted message if the buffer is full
+       while ((buffer->max_length > 0) && (buffer->length >= buffer->max_length)) {
+               r = pakfire_log_buffer_drop(buffer);
+               if (r < 0)
+                       return r;
        }
 
        // Automatically determine the length
index a8204a0be1dd31cea19cc03eda2a54ad27eb3ab6..d7a5c3a4358b9afe061731204aa8e3825461e754 100644 (file)
@@ -106,6 +106,9 @@ FAIL:
 
 static int test_full(const struct test* t) {
        struct pakfire_log_buffer* buffer = NULL;
+       char* line = NULL;
+       size_t length = 0;
+       int priority = 0;
        int r = EXIT_FAILURE;
 
        // Create buffer
@@ -115,8 +118,20 @@ static int test_full(const struct test* t) {
        ASSERT_SUCCESS(pakfire_log_buffer_enqueue(buffer, LOG_DEBUG, "Line 1", -1));
        ASSERT_SUCCESS(pakfire_log_buffer_enqueue(buffer, LOG_DEBUG, "Line 2", -1));
 
-       // There should be no more space for a third line
-       ASSERT_ERROR(pakfire_log_buffer_enqueue(buffer, LOG_DEBUG, "Line 3", -1), ENOBUFS);
+       // There should be no more space for a third line, so the first line should get dropped
+       ASSERT_SUCCESS(pakfire_log_buffer_enqueue(buffer, LOG_DEBUG, "Line 3", -1));
+
+       // On dequeue we should now miss Line 1, but get Line 2 instead
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_STRING_EQUALS(line, "Line 2");
+
+       // On the next iteration, we should get Line 3
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT_STRING_EQUALS(line, "Line 3");
+
+       // On the next iteration, the buffer should be empty
+       ASSERT_SUCCESS(pakfire_log_buffer_dequeue(buffer, &priority, &line, &length));
+       ASSERT(line == NULL);
 
        // Everything passed
        r = EXIT_SUCCESS;