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