From bd43295f7df4c1c1b019c0a71dae43296c89f974 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Wed, 1 Sep 2021 11:06:40 +0200 Subject: [PATCH] LOG: Send the messages to the queue in a thread safe way, clear the loggers from sink cache on destruction --- src/Lib/Log.cc | 25 +++++++++++++------------ src/Lib/Log.hh | 21 ++++++++++++++------- src/Lib/Utils.hh | 18 ++++++++++++++---- 3 files changed, 41 insertions(+), 23 deletions(-) diff --git a/src/Lib/Log.cc b/src/Lib/Log.cc index 461c6945..e09f7480 100644 --- a/src/Lib/Log.cc +++ b/src/Lib/Log.cc @@ -3,6 +3,7 @@ using namespace Vivy; LogSink::~LogSink() noexcept {} +Logger::~Logger() noexcept { parentLogSink->closeLoggerClients(); } LogMessage::~LogMessage() noexcept { parentLogger->sendLogMessage(*this); } const chrono::milliseconds @@ -30,12 +31,19 @@ Logger::sendLogMessage(const LogMessage &msg) const noexcept parentLogSink->recieveLogMessage(this, msg); } +const std::string_view +Logger::getCategoryView() const noexcept +{ + return std::string_view{ logCategory }; +} + // Get the log message from the logger and add it to the sink's queue. void LogSink::recieveLogMessage(const Logger *const logger, LogMessage const &msg) noexcept { const std::lock_guard<std::mutex> messageQueueLockGuard(messageQueueLock); - messageQueue.emplace_back(msg); + messageQueue.push_back( + std::tuple<const std::string_view, const LogMessage>{ logger->getCategoryView(), msg }); } std::shared_ptr<LogSink> @@ -54,18 +62,11 @@ LogSink::registerLoggerClient(std::shared_ptr<Logger> logger) noexcept } void -LogSink::closeLoggerClient(Logger *const logger) noexcept -{ - clientLoggers.erase(std::remove_if(std::begin(clientLoggers), std::end(clientLoggers), - [logger](const std::shared_ptr<Logger> &ptr) { - return ptr.get() == logger; - })); -} - -void -LogSink::closeLoggerClient(const std::shared_ptr<Logger> &ptr) noexcept +LogSink::closeLoggerClients() noexcept { - closeLoggerClient(ptr.get()); + clientLoggers.erase( + std::remove_if(std::begin(clientLoggers), std::end(clientLoggers), + [](const std::weak_ptr<Logger> &weakPtr) { return !weakPtr.expired(); })); } LogMessage diff --git a/src/Lib/Log.hh b/src/Lib/Log.hh index 227389ea..a9d4a22b 100644 --- a/src/Lib/Log.hh +++ b/src/Lib/Log.hh @@ -47,22 +47,21 @@ enum class LogLevel : int { class LogSink { VIVY_UNMOVABLE_OBJECT(LogSink) - LogSink() noexcept = default; + explicit LogSink() noexcept = default; public: static std::shared_ptr<LogSink> newSink() noexcept; ~LogSink() noexcept; void registerLoggerClient(std::shared_ptr<Logger>) noexcept; - void closeLoggerClient(Logger *const) noexcept; - void closeLoggerClient(const std::shared_ptr<Logger> &) noexcept; + void closeLoggerClients() noexcept; void recieveLogMessage(const Logger *const, LogMessage const &) noexcept; private: std::mutex messageQueueLock{}; - std::vector<LogMessage> messageQueue; - std::vector<std::shared_ptr<Logger>> clientLoggers; + std::vector<std::tuple<const std::string_view, const LogMessage>> messageQueue; + std::vector<std::weak_ptr<Logger>> clientLoggers; }; // Message to be logged, constructed by a logger then send @@ -75,7 +74,11 @@ public: const int lineNumberInFile; }; - LogMessage(Logger *const, const Header) noexcept; + VIVY_DEFAULT_COPY_CTOR(LogMessage) + VIVY_DEFAULT_MOVE_CTOR(LogMessage) + VIVY_DISABLE_ASSIGN_OPERATORS(LogMessage) + + explicit LogMessage(Logger *const, const Header) noexcept; ~LogMessage() noexcept; // The message will be send on destruction Header const &getHeader() const noexcept; @@ -123,7 +126,7 @@ class Logger : public std::enable_shared_from_this<Logger> { public: // Templated constructor, construct from anything that can be considered as // a string. - Logger(LogSink *const sink, const std::string_view category) noexcept + explicit Logger(LogSink *const sink, const std::string_view category) noexcept : parentLogSink(sink) , logCategory(anyStringToStdString(category)) { @@ -131,6 +134,10 @@ public: sink->registerLoggerClient(self); } + ~Logger() noexcept; + + const std::string_view getCategoryView() const noexcept; + void sendLogMessage(const LogMessage &) const noexcept; LogMessage logEvent(const char *fileName, const char *functionName, const int lineNumber, const LogLevel) noexcept; diff --git a/src/Lib/Utils.hh b/src/Lib/Utils.hh index da89c510..aca6e2ab 100644 --- a/src/Lib/Utils.hh +++ b/src/Lib/Utils.hh @@ -31,13 +31,23 @@ using chrono::duration_cast; #define parallel_for \ _Pragma("omp parallel for") for -// Don't move this object, create it in one place and never move it again. -#define VIVY_UNMOVABLE_OBJECT(classname) \ - classname(const classname &) = delete; /* Copy */ \ - classname(classname &&) = delete; /* Move */ \ +// Disable copy and move assign operators +#define VIVY_DISABLE_ASSIGN_OPERATORS(classname) \ classname &operator=(const classname &) = delete; /* Copy assign */ \ classname &operator=(classname &&) = delete; /* Move assign */ +// Don't move this object, create it in one place and never move it again. +#define VIVY_UNMOVABLE_OBJECT(classname) \ + classname(const classname &) = delete; /* Copy */ \ + classname(classname &&) = delete; /* Move */ \ + VIVY_DISABLE_ASSIGN_OPERATORS(classname) + +#define VIVY_DEFAULT_COPY_CTOR(classname) \ + explicit classname(const classname &) noexcept = default; /* Copy */ + +#define VIVY_DEFAULT_MOVE_CTOR(classname) \ + explicit classname(classname &&) noexcept = default; /* Move */ + // QStringLiteral but for regexes #define QRegExpLiteral(str) QRegExp(QStringLiteral(str)) -- GitLab