Replaced the LogWorker thread with Boost ASIO

This commit is contained in:
leak
2014-07-08 20:55:25 +02:00
parent c24bf2f028
commit d1594998f8
7 changed files with 31 additions and 115 deletions

View File

@@ -18,6 +18,7 @@
#ifndef _WORKERTHREAD_H
#define _WORKERTHREAD_H
#include <thread>
#include "ProducerConsumerQueue.h"
class MySQLConnection;

View File

@@ -29,7 +29,7 @@
#include <cstdio>
#include <sstream>
Log::Log() : worker(NULL)
Log::Log() : _ioService(nullptr), _strand(nullptr)
{
m_logsTimestamp = "_" + GetTimestampStr();
LoadFromConfig();
@@ -37,6 +37,7 @@ Log::Log() : worker(NULL)
Log::~Log()
{
delete _strand;
Close();
}
@@ -272,8 +273,13 @@ void Log::write(LogMessage* msg) const
Logger const* logger = GetLoggerByType(msg->type);
msg->text.append("\n");
if (worker)
worker->Enqueue(new LogOperation(logger, msg));
if (_ioService)
{
auto logOperation = std::shared_ptr<LogOperation>(new LogOperation(logger, msg));
_ioService->post(_strand->wrap([logOperation](){ logOperation->call(); }));
}
else
{
logger->write(*msg);
@@ -375,8 +381,6 @@ void Log::SetRealmId(uint32 id)
void Log::Close()
{
delete worker;
worker = NULL;
loggers.clear();
for (AppenderMap::iterator it = appenders.begin(); it != appenders.end(); ++it)
{
@@ -390,9 +394,6 @@ void Log::LoadFromConfig()
{
Close();
if (sConfigMgr->GetBoolDefault("Log.Async.Enable", false))
worker = new LogWorker();
AppenderId = 0;
m_logsDir = sConfigMgr->GetStringDefault("LogsDir", "");
if (!m_logsDir.empty())

View File

@@ -22,8 +22,9 @@
#include "Define.h"
#include "Appender.h"
#include "Logger.h"
#include "LogWorker.h"
#include <stdarg.h>
#include <boost/asio/io_service.hpp>
#include <boost/asio/strand.hpp>
#include <unordered_map>
#include <string>
@@ -39,9 +40,17 @@ class Log
~Log();
public:
static Log* instance()
static Log* instance(boost::asio::io_service* ioService = nullptr)
{
static Log* instance = new Log();
if (ioService != nullptr)
{
instance->_ioService = ioService;
instance->_strand = new boost::asio::strand(*ioService);
}
return instance;
}
@@ -77,7 +86,8 @@ class Log
std::string m_logsDir;
std::string m_logsTimestamp;
LogWorker* worker;
boost::asio::io_service* _ioService;
boost::asio::strand* _strand;
};
inline Logger const* Log::GetLoggerByType(std::string const& type) const

View File

@@ -1,56 +0,0 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "LogWorker.h"
#include <thread>
LogWorker::LogWorker()
{
_cancelationToken = false;
_workerThread = std::thread(&LogWorker::WorkerThread, this);
}
LogWorker::~LogWorker()
{
_cancelationToken = true;
_queue.Cancel();
_workerThread.join();
}
void LogWorker::Enqueue(LogOperation* op)
{
return _queue.Push(op);
}
void LogWorker::WorkerThread()
{
while (1)
{
LogOperation* operation = nullptr;
_queue.WaitAndPop(operation);
if (_cancelationToken)
return;
operation->call();
delete operation;
}
}

View File

@@ -1,46 +0,0 @@
/*
* Copyright (C) 2008-2014 TrinityCore <http://www.trinitycore.org/>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef LOGWORKER_H
#define LOGWORKER_H
#include <atomic>
#include <thread>
#include "LogOperation.h"
#include "ProducerConsumerQueue.h"
class LogWorker
{
public:
LogWorker();
~LogWorker();
void Enqueue(LogOperation *op);
private:
ProducerConsumerQueue<LogOperation*> _queue;
void WorkerThread();
std::thread _workerThread;
std::atomic_bool _cancelationToken;
};
#endif

View File

@@ -37,9 +37,9 @@ public:
_socket(ioService),
_acceptor(ioService, tcp::endpoint(boost::asio::ip::address::from_string(bindIp), port))
{
AsyncAccept();
_acceptor.set_option(boost::asio::ip::tcp::no_delay(tcpNoDelay));
_socket.set_option(boost::asio::ip::tcp::no_delay(tcpNoDelay));
AsyncAccept();
};
private:

View File

@@ -145,6 +145,12 @@ extern int main(int argc, char** argv)
return 1;
}
if (sConfigMgr->GetBoolDefault("Log.Async.Enable", false))
{
// If logs are supposed to be handled async then we need to pass the io_service into the Log singleton
Log::instance(&_ioService);
}
TC_LOG_INFO("server.worldserver", "%s (worldserver-daemon)", _FULLVERSION);
TC_LOG_INFO("server.worldserver", "<Ctrl-C> to stop.\n");
TC_LOG_INFO("server.worldserver", " ______ __");