#include "reader_common.h"
#include "logger_internal.h"
-static void free_reader_logger(struct reader_common *reader)
+static void free_reader_logger(struct reader_common *_reader)
{
- /* Nothing to cleanup. The Android Logger reader
- * does everything via sub-readers. */
+ struct reader_logger *const reader = (struct reader_logger *) _reader;
+
+ /* reader_logger is now in a transitory phase where it uses both
+ * the device_fd and the source FD entity, meaning that this FD is
+ * referenced twice (by both). Reset the FD entity because that's
+ * the one that is going to be removed in the future. */
+ assert(reader->common.fd_entity_source.fd == reader->device_fd);
+ reader->common.fd_entity_source.fd = -1;
+
+ if (reader->device_fd != -1)
+ close(reader->device_fd);
}
static void handle_single_log(struct reader_logger *reader, struct now_t time, int read_count)
* starvation under heavy load. */
int max_loop_iterations = g_backend.logger_device_throttling[reader->buf_id];
while (max_loop_iterations--) {
- int r = TEMP_FAILURE_RETRY(read(reader->common.fd_entity_source.fd, reader->read_buffer, sizeof reader->read_buffer - 1));
+ /* Note, nominally we had been polling the source FD entity and not
+ * `device_fd`, but that is the same FD (see the init and free ops).
+ * This is temporary redundancy due to the migration to threads. */
+ int r = TEMP_FAILURE_RETRY(read(reader->device_fd, reader->read_buffer, sizeof reader->read_buffer - 1));
if (r == 0)
break;
else if (r == -1) {
reader_common_init(&ret->common);
+ ret->device_fd = -1;
ret->buf_id = LOG_ID_INVALID;
ret->common.service_reader = service_reader_logger;
ret->common.free_reader = free_reader_logger;
return -ENOENT;
ret->buf_id = buf_id;
- int read_fd = -1;
- int r = logger_open_buffer(buf_id, config_list, O_RDONLY | O_NONBLOCK, &read_fd);
+ int r = logger_open_buffer(buf_id, config_list, O_RDONLY | O_NONBLOCK, &ret->device_fd);
if (r <= 0)
return r;
- ret->skip_count = skip ? logger_get_log_len(read_fd) : 0;
+ ret->skip_count = skip ? logger_get_log_len(ret->device_fd) : 0;
init_fd_entity(&ret->common.fd_entity_source, dispatch_event_reader_logger, ret);
- set_read_fd_entity(&ret->common.fd_entity_source, read_fd);
+ set_read_fd_entity(&ret->common.fd_entity_source, ret->device_fd);
*reader = ret;
ret = NULL;