Merge pull request #3126 from phire/remove-logging-lock
Refactor logging code to get rid of a mutex.
This commit is contained in:
commit
a759883ae5
|
@ -164,8 +164,7 @@ public:
|
|||
BitSet& operator|=(BitSet other) { return *this = *this | other; }
|
||||
BitSet& operator&=(BitSet other) { return *this = *this & other; }
|
||||
BitSet& operator^=(BitSet other) { return *this = *this ^ other; }
|
||||
operator u32() = delete;
|
||||
operator bool() { return m_val != 0; }
|
||||
explicit operator bool() const { return m_val != 0; }
|
||||
|
||||
// Warning: Even though on modern CPUs this is a single fast instruction,
|
||||
// Dolphin's official builds do not currently assume POPCNT support on x86,
|
||||
|
|
|
@ -32,9 +32,16 @@ set(SRCS BreakPoints.cpp
|
|||
x64Emitter.cpp
|
||||
Crypto/bn.cpp
|
||||
Crypto/ec.cpp
|
||||
Logging/ConsoleListenerNix.cpp
|
||||
Logging/LogManager.cpp)
|
||||
|
||||
if(ANDROID)
|
||||
set(SRCS ${SRCS}
|
||||
Logging/ConsoleListenerDroid.cpp)
|
||||
else()
|
||||
set(SRCS ${SRCS}
|
||||
Logging/ConsoleListenerNix.cpp)
|
||||
endif()
|
||||
|
||||
set(LIBS enet)
|
||||
if(_M_ARM_64)
|
||||
set(SRCS ${SRCS}
|
||||
|
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright 2015 Dolphin Emulator Project
|
||||
// Licensed under GPLv2+
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <android/log.h>
|
||||
|
||||
#include "Common/Logging/ConsoleListener.h"
|
||||
|
||||
ConsoleListener::ConsoleListener()
|
||||
{
|
||||
}
|
||||
|
||||
ConsoleListener::~ConsoleListener()
|
||||
{
|
||||
}
|
||||
|
||||
void ConsoleListener::Log(LogTypes::LOG_LEVELS level, const char *text)
|
||||
{
|
||||
android_LogPriority logLevel = ANDROID_LOG_UNKNOWN;
|
||||
|
||||
// Map dolphin's log levels to android's
|
||||
switch(level)
|
||||
{
|
||||
case LogTypes::LOG_LEVELS::LDEBUG:
|
||||
logLevel = ANDROID_LOG_DEBUG;
|
||||
break;
|
||||
case LogTypes::LOG_LEVELS::LINFO:
|
||||
logLevel = ANDROID_LOG_INFO;
|
||||
break;
|
||||
case LogTypes::LOG_LEVELS::LWARNING:
|
||||
logLevel = ANDROID_LOG_WARN;
|
||||
break;
|
||||
case LogTypes::LOG_LEVELS::LERROR:
|
||||
logLevel = ANDROID_LOG_ERROR;
|
||||
break;
|
||||
case LogTypes::LOG_LEVELS::LNOTICE:
|
||||
logLevel = ANDROID_LOG_INFO;
|
||||
break;
|
||||
}
|
||||
|
||||
__android_log_write(logLevel, "Dolphinemu", text);
|
||||
}
|
|
@ -9,9 +9,6 @@
|
|||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#ifdef ANDROID
|
||||
#include <android/log.h>
|
||||
#endif
|
||||
#include "Common/FileUtil.h"
|
||||
#include "Common/IniFile.h"
|
||||
#include "Common/StringUtil.h"
|
||||
|
@ -83,8 +80,8 @@ LogManager::LogManager()
|
|||
m_Log[LogTypes::WII_IPC_WC24] = new LogContainer("WII_IPC_WC24", "WII IPC WC24");
|
||||
m_Log[LogTypes::WII_IPC_WIIMOTE] = new LogContainer("WII_IPC_WIIMOTE", "WII IPC WIIMOTE");
|
||||
|
||||
m_fileLog = new FileLogListener(File::GetUserPath(F_MAINLOG_IDX));
|
||||
m_consoleLog = new ConsoleListener();
|
||||
RegisterListener(LogListener::FILE_LISTENER, new FileLogListener(File::GetUserPath(F_MAINLOG_IDX)));
|
||||
RegisterListener(LogListener::CONSOLE_LISTENER, new ConsoleListener());
|
||||
|
||||
IniFile ini;
|
||||
ini.Load(File::GetUserPath(F_LOGGERCONFIG_IDX));
|
||||
|
@ -101,25 +98,20 @@ LogManager::LogManager()
|
|||
logs->Get(container->GetShortName(), &enable, false);
|
||||
container->SetEnable(enable);
|
||||
if (enable && write_file)
|
||||
container->AddListener(m_fileLog);
|
||||
container->AddListener(LogListener::FILE_LISTENER);
|
||||
if (enable && write_console)
|
||||
container->AddListener(m_consoleLog);
|
||||
container->AddListener(LogListener::CONSOLE_LISTENER);
|
||||
}
|
||||
}
|
||||
|
||||
LogManager::~LogManager()
|
||||
{
|
||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
|
||||
{
|
||||
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_fileLog);
|
||||
m_logManager->RemoveListener((LogTypes::LOG_TYPE)i, m_consoleLog);
|
||||
}
|
||||
|
||||
for (LogContainer* container : m_Log)
|
||||
delete container;
|
||||
|
||||
delete m_fileLog;
|
||||
delete m_consoleLog;
|
||||
// The log window listener pointer is owned by the GUI code.
|
||||
delete m_listeners[LogListener::CONSOLE_LISTENER];
|
||||
delete m_listeners[LogListener::FILE_LISTENER];
|
||||
}
|
||||
|
||||
void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,
|
||||
|
@ -138,10 +130,9 @@ void LogManager::Log(LogTypes::LOG_LEVELS level, LogTypes::LOG_TYPE type,
|
|||
file, line,
|
||||
LogTypes::LOG_LEVEL_TO_CHAR[(int)level],
|
||||
log->GetShortName().c_str(), temp);
|
||||
#ifdef ANDROID
|
||||
__android_log_write(ANDROID_LOG_INFO, "Dolphinemu", msg.c_str());
|
||||
#endif
|
||||
log->Trigger(level, msg.c_str());
|
||||
|
||||
for (auto listener_id : *log)
|
||||
m_listeners[listener_id]->Log(level, msg.c_str());
|
||||
}
|
||||
|
||||
void LogManager::Init()
|
||||
|
@ -163,29 +154,6 @@ LogContainer::LogContainer(const std::string& shortName, const std::string& full
|
|||
{
|
||||
}
|
||||
|
||||
// LogContainer
|
||||
void LogContainer::AddListener(LogListener *listener)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_listeners_lock);
|
||||
m_listeners.insert(listener);
|
||||
}
|
||||
|
||||
void LogContainer::RemoveListener(LogListener *listener)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_listeners_lock);
|
||||
m_listeners.erase(listener);
|
||||
}
|
||||
|
||||
void LogContainer::Trigger(LogTypes::LOG_LEVELS level, const char *msg)
|
||||
{
|
||||
std::lock_guard<std::mutex> lk(m_listeners_lock);
|
||||
|
||||
for (LogListener* listener : m_listeners)
|
||||
{
|
||||
listener->Log(level, msg);
|
||||
}
|
||||
}
|
||||
|
||||
FileLogListener::FileLogListener(const std::string& filename)
|
||||
{
|
||||
OpenFStream(m_logfile, filename, std::ios::app);
|
||||
|
|
|
@ -4,20 +4,20 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstdarg>
|
||||
#include <fstream>
|
||||
#include <mutex>
|
||||
#include <set>
|
||||
#include <string>
|
||||
|
||||
#include "Common/BitSet.h"
|
||||
#include "Common/CommonTypes.h"
|
||||
#include "Common/NonCopyable.h"
|
||||
#include "Common/Logging/Log.h"
|
||||
|
||||
#define MAX_MESSAGES 8000
|
||||
#define MAX_MSGLEN 1024
|
||||
|
||||
|
||||
// pure virtual interface
|
||||
class LogListener
|
||||
{
|
||||
|
@ -25,6 +25,15 @@ public:
|
|||
virtual ~LogListener() {}
|
||||
|
||||
virtual void Log(LogTypes::LOG_LEVELS, const char *msg) = 0;
|
||||
|
||||
enum LISTENER
|
||||
{
|
||||
FILE_LISTENER = 0,
|
||||
CONSOLE_LISTENER,
|
||||
LOG_WINDOW_LISTENER,
|
||||
|
||||
NUMBER_OF_LISTENERS // Must be last
|
||||
};
|
||||
};
|
||||
|
||||
class FileLogListener : public LogListener
|
||||
|
@ -54,8 +63,8 @@ public:
|
|||
std::string GetShortName() const { return m_shortName; }
|
||||
std::string GetFullName() const { return m_fullName; }
|
||||
|
||||
void AddListener(LogListener* listener);
|
||||
void RemoveListener(LogListener* listener);
|
||||
void AddListener(LogListener::LISTENER id) { m_listener_ids[id] = 1; }
|
||||
void RemoveListener(LogListener::LISTENER id) { m_listener_ids[id] = 0; }
|
||||
|
||||
void Trigger(LogTypes::LOG_LEVELS, const char *msg);
|
||||
|
||||
|
@ -66,15 +75,18 @@ public:
|
|||
|
||||
void SetLevel(LogTypes::LOG_LEVELS level) { m_level = level; }
|
||||
|
||||
bool HasListeners() const { return !m_listeners.empty(); }
|
||||
bool HasListeners() const { return bool(m_listener_ids); }
|
||||
|
||||
typedef class BitSet32::Iterator iterator;
|
||||
iterator begin() const { return m_listener_ids.begin(); }
|
||||
iterator end() const { return m_listener_ids.end(); }
|
||||
|
||||
private:
|
||||
std::string m_fullName;
|
||||
std::string m_shortName;
|
||||
bool m_enable;
|
||||
LogTypes::LOG_LEVELS m_level;
|
||||
std::mutex m_listeners_lock;
|
||||
std::set<LogListener*> m_listeners;
|
||||
BitSet32 m_listener_ids;
|
||||
};
|
||||
|
||||
class ConsoleListener;
|
||||
|
@ -83,9 +95,8 @@ class LogManager : NonCopyable
|
|||
{
|
||||
private:
|
||||
LogContainer* m_Log[LogTypes::NUMBER_OF_LOGS];
|
||||
FileLogListener *m_fileLog;
|
||||
ConsoleListener *m_consoleLog;
|
||||
static LogManager *m_logManager; // Singleton. Ugh.
|
||||
std::array<LogListener*, LogListener::NUMBER_OF_LISTENERS> m_listeners;
|
||||
|
||||
LogManager();
|
||||
~LogManager();
|
||||
|
@ -121,24 +132,19 @@ public:
|
|||
return m_Log[type]->GetFullName();
|
||||
}
|
||||
|
||||
void AddListener(LogTypes::LOG_TYPE type, LogListener *listener)
|
||||
void RegisterListener(LogListener::LISTENER id, LogListener *listener)
|
||||
{
|
||||
m_Log[type]->AddListener(listener);
|
||||
m_listeners[id] = listener;
|
||||
}
|
||||
|
||||
void RemoveListener(LogTypes::LOG_TYPE type, LogListener *listener)
|
||||
void AddListener(LogTypes::LOG_TYPE type, LogListener::LISTENER id)
|
||||
{
|
||||
m_Log[type]->RemoveListener(listener);
|
||||
m_Log[type]->AddListener(id);
|
||||
}
|
||||
|
||||
FileLogListener *GetFileListener() const
|
||||
void RemoveListener(LogTypes::LOG_TYPE type, LogListener::LISTENER id)
|
||||
{
|
||||
return m_fileLog;
|
||||
}
|
||||
|
||||
ConsoleListener *GetConsoleListener() const
|
||||
{
|
||||
return m_consoleLog;
|
||||
m_Log[type]->RemoveListener(id);
|
||||
}
|
||||
|
||||
static LogManager* GetInstance()
|
||||
|
|
|
@ -170,9 +170,9 @@ void LogConfigWindow::OnWriteFileChecked(wxCommandEvent& event)
|
|||
if (m_checks->IsChecked(i))
|
||||
{
|
||||
if (m_writeFile)
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener());
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER);
|
||||
else
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener());
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -185,9 +185,9 @@ void LogConfigWindow::OnWriteConsoleChecked(wxCommandEvent& event)
|
|||
if (m_checks->IsChecked(i))
|
||||
{
|
||||
if (m_writeConsole)
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, m_LogManager->GetConsoleListener());
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::CONSOLE_LISTENER);
|
||||
else
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, m_LogManager->GetConsoleListener());
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::CONSOLE_LISTENER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -200,9 +200,9 @@ void LogConfigWindow::OnWriteWindowChecked(wxCommandEvent& event)
|
|||
if (m_checks->IsChecked(i))
|
||||
{
|
||||
if (m_writeWindow)
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, (LogListener *)m_LogWindow);
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER);
|
||||
else
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, (LogListener *)m_LogWindow);
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,17 +226,17 @@ void LogConfigWindow::ToggleLog(int _logType, bool enable)
|
|||
if (enable)
|
||||
{
|
||||
if (m_writeWindow)
|
||||
m_LogManager->AddListener(logType, (LogListener *)m_LogWindow);
|
||||
m_LogManager->AddListener(logType, LogListener::LOG_WINDOW_LISTENER);
|
||||
if (m_writeFile)
|
||||
m_LogManager->AddListener(logType, m_LogManager->GetFileListener());
|
||||
m_LogManager->AddListener(logType, LogListener::FILE_LISTENER);
|
||||
if (m_writeConsole)
|
||||
m_LogManager->AddListener(logType, m_LogManager->GetConsoleListener());
|
||||
m_LogManager->AddListener(logType, LogListener::CONSOLE_LISTENER);
|
||||
}
|
||||
else
|
||||
{
|
||||
m_LogManager->RemoveListener(logType, (LogListener *)m_LogWindow);
|
||||
m_LogManager->RemoveListener(logType, m_LogManager->GetFileListener());
|
||||
m_LogManager->RemoveListener(logType, m_LogManager->GetConsoleListener());
|
||||
m_LogManager->RemoveListener(logType, LogListener::LOG_WINDOW_LISTENER);
|
||||
m_LogManager->RemoveListener(logType, LogListener::FILE_LISTENER);
|
||||
m_LogManager->RemoveListener(logType, LogListener::CONSOLE_LISTENER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -45,6 +45,7 @@ CLogWindow::CLogWindow(CFrame *parent, wxWindowID id, const wxPoint& pos,
|
|||
Bind(wxEVT_TIMER, &CLogWindow::OnLogTimer, this);
|
||||
|
||||
m_LogManager = LogManager::GetInstance();
|
||||
m_LogManager->RegisterListener(LogListener::LOG_WINDOW_LISTENER, this);
|
||||
|
||||
CreateGUIControls();
|
||||
|
||||
|
@ -84,14 +85,14 @@ void CLogWindow::CreateGUIControls()
|
|||
logs->Get(m_LogManager->GetShortName((LogTypes::LOG_TYPE)i), &enable, false);
|
||||
|
||||
if (m_writeWindow && enable)
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, this);
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER);
|
||||
else
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, this);
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER);
|
||||
|
||||
if (m_writeFile && enable)
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener());
|
||||
m_LogManager->AddListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER);
|
||||
else
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, m_LogManager->GetFileListener());
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::FILE_LISTENER);
|
||||
|
||||
m_LogManager->SetLogLevel((LogTypes::LOG_TYPE)i, (LogTypes::LOG_LEVELS)(verbosity));
|
||||
}
|
||||
|
@ -153,7 +154,7 @@ CLogWindow::~CLogWindow()
|
|||
{
|
||||
for (int i = 0; i < LogTypes::NUMBER_OF_LOGS; ++i)
|
||||
{
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, this);
|
||||
m_LogManager->RemoveListener((LogTypes::LOG_TYPE)i, LogListener::LOG_WINDOW_LISTENER);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue