]> git.lizzy.rs Git - dragonfireclient.git/commitdiff
Add missing concurrency protection in logger (#12325)
authorparadust7 <102263465+paradust7@users.noreply.github.com>
Mon, 23 May 2022 20:50:25 +0000 (13:50 -0700)
committerGitHub <noreply@github.com>
Mon, 23 May 2022 20:50:25 +0000 (22:50 +0200)
src/log.cpp
src/log.h

index 51652fe0a059eeaa918b6a313e272c489fdd2498..ef998f16196c38251a98eba5cd8d93905399cd3c 100644 (file)
@@ -152,12 +152,14 @@ void Logger::addOutput(ILogOutput *out)
 
 void Logger::addOutput(ILogOutput *out, LogLevel lev)
 {
+       MutexAutoLock lock(m_mutex);
        m_outputs[lev].push_back(out);
        m_has_outputs[lev] = true;
 }
 
 void Logger::addOutputMasked(ILogOutput *out, LogLevelMask mask)
 {
+       MutexAutoLock lock(m_mutex);
        for (size_t i = 0; i < LL_MAX; i++) {
                if (mask & LOGLEVEL_TO_MASKLEVEL(i)) {
                        m_outputs[i].push_back(out);
@@ -168,6 +170,7 @@ void Logger::addOutputMasked(ILogOutput *out, LogLevelMask mask)
 
 void Logger::addOutputMaxLevel(ILogOutput *out, LogLevel lev)
 {
+       MutexAutoLock lock(m_mutex);
        assert(lev < LL_MAX);
        for (size_t i = 0; i <= lev; i++) {
                m_outputs[i].push_back(out);
@@ -177,6 +180,7 @@ void Logger::addOutputMaxLevel(ILogOutput *out, LogLevel lev)
 
 LogLevelMask Logger::removeOutput(ILogOutput *out)
 {
+       MutexAutoLock lock(m_mutex);
        LogLevelMask ret_mask = 0;
        for (size_t i = 0; i < LL_MAX; i++) {
                std::vector<ILogOutput *>::iterator it;
@@ -386,6 +390,6 @@ void LogOutputBuffer::logRaw(LogLevel lev, const std::string &line)
                default: break;
                }
        }
-
-       m_buffer.push(color.append(line));
+       MutexAutoLock lock(m_buffer_mutex);
+       m_buffer.emplace(color.append(line));
 }
index 5c6ba7d64ff41e559cdddef2e08be9f1975f8db1..0a84332e70b80416fcff76f500556b053a63e6e1 100644 (file)
--- a/src/log.h
+++ b/src/log.h
@@ -29,6 +29,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #if !defined(_WIN32)  // POSIX
        #include <unistd.h>
 #endif
+#include "threading/mutex_auto_lock.h"
 #include "util/basic_macros.h"
 #include "util/stream.h"
 #include "irrlichttypes.h"
@@ -168,24 +169,31 @@ class LogOutputBuffer : public ICombinedLogOutput {
 
        void clear()
        {
+               MutexAutoLock lock(m_buffer_mutex);
                m_buffer = std::queue<std::string>();
        }
 
        bool empty() const
        {
+               MutexAutoLock lock(m_buffer_mutex);
                return m_buffer.empty();
        }
 
        std::string get()
        {
-               if (empty())
+               MutexAutoLock lock(m_buffer_mutex);
+               if (m_buffer.empty())
                        return "";
-               std::string s = m_buffer.front();
+               std::string s = std::move(m_buffer.front());
                m_buffer.pop();
                return s;
        }
 
 private:
+       // g_logger serializes calls to logRaw() with a mutex, but that
+       // doesn't prevent get() / clear() from being called on top of it.
+       // This mutex prevents that.
+       mutable std::mutex m_buffer_mutex;
        std::queue<std::string> m_buffer;
        Logger &m_logger;
 };