return 0;
}
+__attribute__((noreturn)) static void thread_seppuku(struct reader_common *reader)
+{
+ const pthread_t self = reader->thread;
+ assert(self == pthread_self());
+
+ reader->thread = 0; // make sure the destructor won't join the thread
+ reader_free(reader);
+
+ pthread_detach(self); // since there's nobody to join us
+ pthread_cancel(self);
+ pthread_testcancel(); // force the cancel in case it didn't happen immediately
+ __builtin_unreachable();
+}
+
+void reader_thread_finished(struct reader_common *reader)
+{
+ assert(reader);
+
+ struct logger *const server = reader->server;
+ assert(server);
+
+ int r = pthread_mutex_lock(&server->drs_lock);
+ assert(!r);
+
+ bool ok = list_add(&server->dead_reader_storage, reader);
+
+ r = pthread_mutex_unlock(&server->drs_lock);
+ assert(!r);
+
+ if (ok)
+ return;
+
+ thread_seppuku(reader); // prevent a leak
+ __builtin_unreachable();
+}
+
int create_fifo_fds(struct logger *server, int pipe_fd[2], int flags, bool dump)
{
int ret = get_nonblocking_fifo(pipe_fd, flags);
if (r < 0)
return r;
+ r = pthread_mutex_init(&l->drs_lock, NULL);
+ if (r < 0)
+ return r;
+
l->epolltime = data->epoll_time;
l->sort_by = data->sort_by;
l->buf_params = data->buf_params;
return 0;
}
+static void cleanup_dead_readers(struct logger *server)
+{
+ int r = pthread_mutex_lock(&server->drs_lock);
+ assert(!r);
+
+ list_foreach(server->dead_reader_storage, server, reader_free_foreach);
+ list_clear(&server->dead_reader_storage);
+
+ r = pthread_mutex_unlock(&server->drs_lock);
+ assert(!r);
+}
+
static bool do_logger_one_iteration(struct logger *server, bool *use_lazy_polling)
{
return false;
service_all_readers(server);
+ cleanup_dead_readers(server);
if (server->qos)
qos_periodic_check(server->qos);
{
assert(l);
+ (void) pthread_mutex_destroy(&l->drs_lock);
+
list_foreach(l->writers, l, foreach_writer_free);
list_foreach(l->readers, l, reader_free_foreach);
+ list_foreach(l->dead_reader_storage, l, reader_free_foreach);
int j;
for (j = 0; j < LOG_ID_MAX; j++)
struct qos_module* qos;
struct signal_markup* sigmar;
list_head compressed_memories;
+
+ /* Dead Reader Storage */
+ list_head dead_reader_storage;
+ pthread_mutex_t drs_lock;
};
struct logger_config_data {
int add_reader_to_server(struct reader_common *reader, struct logger *server);
void flush_logfile_timely(struct log_file *file, struct timespec ts, int flush_time);
int get_now(struct now_t *now);
+void reader_thread_finished(struct reader_common *reader);
// these live in `logger_internal.c`, the earlier ones are scattered in various others
int handle_epoll_events(struct logger *server, struct epoll_metadata *metadata, int timeout);