return true;
}
+// TODO: Consider inlining struct now_t everywhere
+int get_now(struct now_t *now)
+{
+ if (clock_gettime(CLOCK_MONOTONIC, &now->mono))
+ return -errno;
+ if (clock_gettime(CLOCK_REALTIME, &now->real))
+ return -errno;
+ return 0;
+}
+
void qos_periodic_check(struct logger *server)
{
struct qos_module *const qos = &server->qos;
- struct timespec const now = server->time.mono;
+ struct timespec ts_mono;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts_mono))
+ return;
- if (now.tv_sec < qos->cancel_limits_at.tv_sec)
+ if (ts_mono.tv_sec < qos->cancel_limits_at.tv_sec)
return;
- if (now.tv_sec == qos->cancel_limits_at.tv_sec
- && now.tv_nsec < qos->cancel_limits_at.tv_nsec)
+ if (ts_mono.tv_sec == qos->cancel_limits_at.tv_sec
+ && ts_mono.tv_nsec < qos->cancel_limits_at.tv_nsec)
return;
if (metrics_get_total(qos->log_metrics) >= qos->threshold)
else
qos_relax_limits(qos);
- qos_set_next_update_time(qos, now);
+ qos_set_next_update_time(qos, ts_mono);
metrics_clear(qos->log_metrics);
}
"DLOG",
"\x1b[31m DLOG DAEMON FD LIMIT REACHED \x1b[0m" // make it stand out
);
- set_pipe_message_sent_timestamp((struct pipe_logger_entry *) &entry, &server->time.mono, &server->time.real);
+ struct now_t now;
+ int r = get_now(&now);
+ if (r < 0)
+ return;
+ set_pipe_message_sent_timestamp((struct pipe_logger_entry *) &entry, &now.mono, &now.real);
if (buffer_append(&entry.header, buf))
printf("ERROR: not enough memory either, please check platform settings as the daemon is seriously resource-starved!\n");
// don't signal an error: KMSG writer is too important to remove; besides, it would not get fixed that way.
return 0;
}
- add_recv_timestamp(&lem.header, server->time);
+
+ struct now_t now;
+ r = get_now(&now);
+ if (r < 0)
+ return r;
+ add_recv_timestamp(&lem.header, now);
+
r = buffer_append(&lem.header, wr->buf_ptr);
if (r < 0)
return r;
struct reader_pipe *reader = (struct reader_pipe *)ptr;
struct logger *logger = (struct logger *)user_data;
- int r = print_out_logs(reader, logger->time);
-
+ struct now_t now;
+ int r = get_now(&now);
+ if (r < 0) {
+ remove_reader_fd_entities(logger, &reader->common);
+ reader_pipe_free(reader);
+ return true;
+ }
+ r = print_out_logs(reader, now);
if (r > 0) {
remove_reader_fd_entities(logger, &reader->common);
reader_pipe_free(reader);
* like we can do anything about it either */
}
- flush_logfile_timely(&reader->file, logger->time.mono, logger->buf_params.time);
+ flush_logfile_timely(&reader->file, now.mono, logger->buf_params.time);
return false;
}
struct reader_logger *reader = (struct reader_logger *)ptr;
struct logger *logger = (struct logger *)user_data;
- int r = service_reader_logger(reader, logger->time);
+ struct now_t now;
+ int r = get_now(&now);
+ if (r < 0) {
+ remove_reader_fd_entities(logger, &reader->common);
+ reader_logger_free(reader);
+ return true;
+ }
+
+ r = service_reader_logger(reader, now);
if (r > 0) {
remove_reader_fd_entities(logger, &reader->common);
* like we can do anything about it either */
}
- reader_logger_flush(reader, logger->time.mono, logger->buf_params.time);
+ reader_logger_flush(reader, now.mono, logger->buf_params.time);
return false;
}
return 0;
}
- add_recv_timestamp(&lem.header, server->time);
+ struct now_t now;
+ r = get_now(&now);
+ if (r < 0)
+ return r;
+ add_recv_timestamp(&lem.header, now);
+
return buffer_append(&lem.header, wr->buf_ptr);
}
entity->dispatch_event(server, event, entity->dispatch_data);
}
-int handle_epoll_events_and_update_server_time(struct logger *server, struct epoll_metadata *metadata, int timeout)
+int handle_epoll_events(struct logger *server, struct epoll_metadata *metadata, int timeout)
{
ensure_epoll_size(&metadata->events, &metadata->events_size, metadata->cnt);
if (nfds < 0)
return errno == EINTR ? 0 : -errno;
- clock_gettime(CLOCK_MONOTONIC, &server->time.mono);
- clock_gettime(CLOCK_REALTIME, &server->time.real);
-
for (int i = 0; i < nfds; i++)
dispatch_epoll_event(server, metadata->events + i);
int sleep_while_handling_socket(struct logger *server, struct epoll_metadata *metadata, int timeout)
{
- struct timespec start = server->time.mono;
+ struct timespec ts_start;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts_start))
+ return -errno;
+ struct timespec ts_current;
do {
- int r = handle_epoll_events_and_update_server_time(server, metadata, timeout);
+ int r = handle_epoll_events(server, metadata, timeout);
if (r < 0)
return r;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts_current))
+ return -errno;
} while (
- timeout > (server->time.mono.tv_sec - start.tv_sec ) * S_TO_MS
- + (server->time.mono.tv_nsec - start.tv_nsec) / MS_TO_NS
+ timeout > (ts_current.tv_sec - ts_start.tv_sec ) * S_TO_MS
+ + (ts_current.tv_nsec - ts_start.tv_nsec) / MS_TO_NS
);
return 0;
bool use_lazy_polling = true;
while (g_logger_run) {
- clock_gettime(CLOCK_MONOTONIC, &server->time.mono);
- clock_gettime(CLOCK_REALTIME, &server->time.real);
-
if (server->lazy_polling_total >= 0) {
server->lazy_polling_total -= server->lazy_polling_sleep;
use_lazy_polling = (server->lazy_polling_total >= 0);
if (use_lazy_polling)
sleep_while_handling_socket(server, &server->epoll_socket, server->lazy_polling_sleep);
- int r = handle_epoll_events_and_update_server_time(server, &server->epoll_common, server->epolltime * !use_lazy_polling);
+ int r = handle_epoll_events(server, &server->epoll_common, server->epolltime * !use_lazy_polling);
if (r < 0)
break;
if (r < 0)
return r;
- // used to populate the first readers
- clock_gettime(CLOCK_MONOTONIC, &server->time.mono);
- clock_gettime(CLOCK_REALTIME, &server->time.real);
-
//create files after resetting self privileges
list_foreach(data->logfile_configs, server, parse_logfile_config);
return;
}
- int r = print_out_logs(rp, server->time);
+ struct now_t now;
+ int r = get_now(&now);
+ if (r < 0) {
+ remove_reader_fd_entities(server, &rp->common);
+ if (rp->buf_ptr)
+ list_remove(&rp->buf_ptr->readers_pipe, rp);
+ reader_pipe_free(rp);
+ return;
+ }
+
+ r = print_out_logs(rp, now);
if (r != 0) {
/* TODO: There is no reason not to free the reader in full. However, when I do so, some tests start to
* fail without any reasonable reason. You are welcome to *try* to figure out why does this happen. */
assert(server);
assert(filter);
- __attribute__((cleanup(reader_pipe_cleanup))) struct reader_pipe *ret = reader_pipe_alloc(filter, file, server->time.mono, monitor, is_dumping);
+ struct timespec ts_mono;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts_mono))
+ return -errno;
+
+ __attribute__((cleanup(reader_pipe_cleanup))) struct reader_pipe *ret = reader_pipe_alloc(filter, file, ts_mono, monitor, is_dumping);
if (!ret)
return -ENOMEM;
assert(server);
assert(filter);
- __attribute__((cleanup(reader_pipe_cleanup))) struct reader_pipe *ret = reader_pipe_alloc(filter, file, server->time.mono, monitor, is_dumping);
+ struct timespec ts_mono;
+ if (clock_gettime(CLOCK_MONOTONIC, &ts_mono))
+ return -errno;
+
+ __attribute__((cleanup(reader_pipe_cleanup))) struct reader_pipe *ret = reader_pipe_alloc(filter, file, ts_mono, monitor, is_dumping);
if (!ret)
return -ENOMEM;