Implements rudimentary thread-safety for EventBus and Logger classes.
This commit is contained in:
1 parent
34e1dd0c33
commit
fb35fbd350
6 files changed
+62
-27
No files matched your search
+14
-6
@@ -5,21 +5,28 @@ namespace Core {
|
|||||||
|
|
||||||
// ============================== EventBus Class ==============================
|
// ============================== EventBus Class ==============================
|
||||||
|
|
||||||
EventBus::EventBus(Logger& logger) : _logger(logger) {
|
EventBus::EventBus(Logger& logger) :
|
||||||
|
_logger(logger)
|
||||||
|
{
|
||||||
_logger.debug.ln ("Starting Event Bus...");
|
_logger.debug.ln ("Starting Event Bus...");
|
||||||
_thread = thread(&EventBus::run, this);
|
_thread = thread(&EventBus::run, this);
|
||||||
|
_logger.debug.ln ("Event Bus Started");
|
||||||
}
|
}
|
||||||
|
|
||||||
EventBus::~EventBus() {
|
EventBus::~EventBus() {
|
||||||
|
_logger.debug.ln ("Stopping Event Bus...");
|
||||||
_thread.join();
|
_thread.join();
|
||||||
// destroy all events in _events vector
|
// destroy all events in _events vector
|
||||||
_logger.debug.ln ("EventBus has been shut down.");
|
for (auto event : _events) { delete event; }
|
||||||
|
_logger.debug.ln ("Event Bus stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
Event& EventBus::registerEvent(const string& eventID) {
|
Event& EventBus::registerEvent(const string& eventID) {
|
||||||
|
_mutex.lock();
|
||||||
for ( const auto event : _events ) {
|
for ( const auto event : _events ) {
|
||||||
if (event->getID() == eventID) {
|
if (event->getID() == eventID) {
|
||||||
_logger.debug << "Event '" << eventID << "' found" << Logger::commit;
|
_logger.debug << "Event '" << eventID << "' found" << Logger::commit;
|
||||||
|
_mutex.unlock();
|
||||||
return *event;
|
return *event;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -27,27 +34,28 @@ Event& EventBus::registerEvent(const string& eventID) {
|
|||||||
_logger.debug << "Registering new Event '" << eventID << "'" << Logger::commit;
|
_logger.debug << "Registering new Event '" << eventID << "'" << Logger::commit;
|
||||||
Event* event = new Event(eventID);
|
Event* event = new Event(eventID);
|
||||||
_events.push_back(event);
|
_events.push_back(event);
|
||||||
|
_mutex.unlock();
|
||||||
return *event;
|
return *event;
|
||||||
}
|
}
|
||||||
|
|
||||||
void EventBus::run() {
|
void EventBus::run() {
|
||||||
_logger.warn.ln("Hi from EventBus run method! From within Event Thread! Dont forget to make Logger class thread-safe!");
|
_logger.warn.ln("Hi from EventBus run method, from within Event Thread!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// =============================== Event Class ================================
|
// =============================== Event Class ================================
|
||||||
|
|
||||||
Event::Event(const string id) : _id(id) {}
|
Event::Event(const string id) : _id(id) {}
|
||||||
|
|
||||||
Event::~Event() {
|
Event::~Event() {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
const string& Event::getID() const {
|
const string& Event::getID() const {
|
||||||
return _id;
|
return _id;
|
||||||
};
|
};
|
||||||
|
|
||||||
void Event::subscribe(EventSubscriber* es) {
|
void Event::subscribe(EventSubscriber* es) {
|
||||||
|
_mutex.lock();
|
||||||
_subscribers.push_back(es);
|
_subscribers.push_back(es);
|
||||||
|
_mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Event::fire() {
|
void Event::fire() {
|
||||||
|
|||||||
+21
-12
@@ -63,17 +63,19 @@ Logger::Sink::Sink (const Level level, Logger& parent) :
|
|||||||
_lineIsPrefixed(false) {}
|
_lineIsPrefixed(false) {}
|
||||||
|
|
||||||
void Logger::Sink::ln ( const string& msg ) {
|
void Logger::Sink::ln ( const string& msg ) {
|
||||||
ln(msg.c_str());
|
ln (msg.c_str());
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::Sink::ln ( const char* msg ) {
|
void Logger::Sink::ln ( const char* msg ) {
|
||||||
|
_parent._mutex.lock();
|
||||||
if ( _level >= _parent._logLevel ) {
|
if ( _level >= _parent._logLevel ) {
|
||||||
// If line has already been started, abort it and start new one:
|
// If line has already been started, abort it and start new one:
|
||||||
if(_lineIsPrefixed) *_parent._output << endl;
|
if(_lineIsPrefixed) *_parent._output << endl;
|
||||||
prefixLine(true);
|
prefixLine(true);
|
||||||
*_parent._output << msg << endl;
|
*(_parent._output) << msg << endl;
|
||||||
cout << msg << CC_RESET "\n";
|
cout << msg << CC_RESET "\n";
|
||||||
}
|
}
|
||||||
|
_parent._mutex.unlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Logger::Sink::prefixLine(bool resetToFalse) {
|
void Logger::Sink::prefixLine(bool resetToFalse) {
|
||||||
@@ -82,19 +84,19 @@ void Logger::Sink::prefixLine(bool resetToFalse) {
|
|||||||
switch ( _level)
|
switch ( _level)
|
||||||
{
|
{
|
||||||
case DEBUG:
|
case DEBUG:
|
||||||
*_parent._output << timestamp << " " << "DEBUG ";
|
*(_parent._output) << timestamp << " " << "DEBUG ";
|
||||||
cout << timestamp << " " << CC_BLUE "DEBUG ";
|
cout << timestamp << " " << CC_BLUE "DEBUG ";
|
||||||
break;
|
break;
|
||||||
case INFO:
|
case INFO:
|
||||||
*_parent._output << timestamp << " " << "INFO ";
|
*(_parent._output) << timestamp << " " << "INFO ";
|
||||||
cout << timestamp << " " << CC_GREEN "INFO ";
|
cout << timestamp << " " << CC_GREEN "INFO ";
|
||||||
break;
|
break;
|
||||||
case WARN:
|
case WARN:
|
||||||
*_parent._output << timestamp << " " << "WARN ";
|
*(_parent._output) << timestamp << " " << "WARN ";
|
||||||
cout << timestamp << " " << CC_YELLOW "WARN ";
|
cout << timestamp << " " << CC_YELLOW "WARN ";
|
||||||
break;
|
break;
|
||||||
case FATAL:
|
case FATAL:
|
||||||
*_parent._output << timestamp << " " << "FATAL ";
|
*(_parent._output) << timestamp << " " << "FATAL ";
|
||||||
cout << timestamp << " " << CC_RED "FATAL ";
|
cout << timestamp << " " << CC_RED "FATAL ";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -103,61 +105,68 @@ void Logger::Sink::prefixLine(bool resetToFalse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Logger::Sink& Logger::Sink::operator<<(const string& msg) {
|
Logger::Sink& Logger::Sink::operator<<(const string& msg) {
|
||||||
|
_parent._mutex.try_lock();
|
||||||
if ( _level >= _parent._logLevel ) {
|
if ( _level >= _parent._logLevel ) {
|
||||||
prefixLine();
|
prefixLine();
|
||||||
*_parent._output << msg;
|
*(_parent._output) << msg;
|
||||||
cout << msg;
|
cout << msg;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Sink& Logger::Sink::operator<<(const char* msg) {
|
Logger::Sink& Logger::Sink::operator<<(const char* msg) {
|
||||||
|
_parent._mutex.try_lock();
|
||||||
if ( _level >= _parent._logLevel ) {
|
if ( _level >= _parent._logLevel ) {
|
||||||
prefixLine();
|
prefixLine();
|
||||||
*_parent._output << msg;
|
*(_parent._output) << msg;
|
||||||
cout << msg;
|
cout << msg;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Sink& Logger::Sink::operator<<(const int msg) {
|
Logger::Sink& Logger::Sink::operator<<(const int msg) {
|
||||||
|
_parent._mutex.try_lock();
|
||||||
if ( _level >= _parent._logLevel ) {
|
if ( _level >= _parent._logLevel ) {
|
||||||
prefixLine();
|
prefixLine();
|
||||||
*_parent._output << msg;
|
*(_parent._output) << msg;
|
||||||
cout << msg;
|
cout << msg;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Sink& Logger::Sink::operator<<(const long msg) {
|
Logger::Sink& Logger::Sink::operator<<(const long msg) {
|
||||||
|
_parent._mutex.try_lock();
|
||||||
if ( _level >= _parent._logLevel ) {
|
if ( _level >= _parent._logLevel ) {
|
||||||
prefixLine();
|
prefixLine();
|
||||||
*_parent._output << msg;
|
*(_parent._output) << msg;
|
||||||
cout << msg;
|
cout << msg;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Sink& Logger::Sink::operator<<(const unsigned long msg) {
|
Logger::Sink& Logger::Sink::operator<<(const unsigned long msg) {
|
||||||
|
_parent._mutex.try_lock();
|
||||||
if ( _level >= _parent._logLevel ) {
|
if ( _level >= _parent._logLevel ) {
|
||||||
prefixLine();
|
prefixLine();
|
||||||
*_parent._output << msg;
|
*(_parent._output) << msg;
|
||||||
cout << msg;
|
cout << msg;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger::Sink& Logger::Sink::operator<<(const char character) {
|
Logger::Sink& Logger::Sink::operator<<(const char character) {
|
||||||
|
_parent._mutex.try_lock();
|
||||||
if ( _level >= _parent._logLevel ) {
|
if ( _level >= _parent._logLevel ) {
|
||||||
switch(character) {
|
switch(character) {
|
||||||
// COMMIT - End message line
|
// COMMIT - End message line
|
||||||
case 0:
|
case 0:
|
||||||
*_parent._output << endl;
|
*(_parent._output) << endl;
|
||||||
cout << CC_RESET "\n";
|
cout << CC_RESET "\n";
|
||||||
_lineIsPrefixed = false;
|
_lineIsPrefixed = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
_parent._mutex.unlock();
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
namespace Plains {
|
namespace Plains {
|
||||||
namespace Core {
|
namespace Core {
|
||||||
@@ -12,6 +13,7 @@ namespace Core {
|
|||||||
using std::thread;
|
using std::thread;
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::vector;
|
using std::vector;
|
||||||
|
using std::mutex;
|
||||||
using std::unique_ptr;
|
using std::unique_ptr;
|
||||||
|
|
||||||
class EventSubscriber {
|
class EventSubscriber {
|
||||||
@@ -30,6 +32,7 @@ class Event {
|
|||||||
private:
|
private:
|
||||||
const string _id;
|
const string _id;
|
||||||
vector<EventSubscriber*> _subscribers;
|
vector<EventSubscriber*> _subscribers;
|
||||||
|
mutex _mutex;
|
||||||
};
|
};
|
||||||
|
|
||||||
class EventBus {
|
class EventBus {
|
||||||
@@ -38,12 +41,14 @@ class EventBus {
|
|||||||
~EventBus();
|
~EventBus();
|
||||||
Event& registerEvent(const string& eventID);
|
Event& registerEvent(const string& eventID);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void run();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Logger& _logger;
|
Logger& _logger;
|
||||||
thread _thread;
|
thread _thread;
|
||||||
vector<Event*> _events;
|
vector<Event*> _events;
|
||||||
|
mutex _mutex;
|
||||||
void run();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}}
|
}}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
#define LOGGER_HPP
|
#define LOGGER_HPP
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
|
#include <mutex>
|
||||||
|
|
||||||
#define CC(COLOR) CC_##COLOR
|
#define CC(COLOR) CC_##COLOR
|
||||||
#define CC_RESET "\033[0m"
|
#define CC_RESET "\033[0m"
|
||||||
@@ -20,6 +21,7 @@ namespace Core {
|
|||||||
|
|
||||||
using std::string;
|
using std::string;
|
||||||
using std::ofstream;
|
using std::ofstream;
|
||||||
|
using std::mutex;
|
||||||
//using std::ostream;
|
//using std::ostream;
|
||||||
//using std::streambuf;
|
//using std::streambuf;
|
||||||
|
|
||||||
@@ -39,6 +41,7 @@ class Logger {
|
|||||||
Logger& _parent;
|
Logger& _parent;
|
||||||
const Logger::Level _level;
|
const Logger::Level _level;
|
||||||
void prefixLine(bool resetToFalse = false);
|
void prefixLine(bool resetToFalse = false);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Sink(const Level level, Logger& parent);
|
Sink(const Level level, Logger& parent);
|
||||||
void ln (const string& msg);
|
void ln (const string& msg);
|
||||||
@@ -56,6 +59,7 @@ class Logger {
|
|||||||
private:
|
private:
|
||||||
enum Level _logLevel;
|
enum Level _logLevel;
|
||||||
ofstream* _output;
|
ofstream* _output;
|
||||||
|
mutex _mutex;
|
||||||
static string genTimeStamp();
|
static string genTimeStamp();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+9
-6
@@ -3,6 +3,7 @@
|
|||||||
#include "DNS.hpp"
|
#include "DNS.hpp"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <exception>
|
||||||
|
|
||||||
using namespace Plains;
|
using namespace Plains;
|
||||||
using namespace Core;
|
using namespace Core;
|
||||||
@@ -15,13 +16,13 @@ int main(int args, char **argv) {
|
|||||||
|
|
||||||
logger.info.ln ("Starting PlaiNS...");
|
logger.info.ln ("Starting PlaiNS...");
|
||||||
|
|
||||||
try
|
|
||||||
{
|
|
||||||
vector<string> arguments;
|
vector<string> arguments;
|
||||||
for ( unsigned index = 0; index < args; ++index ) {
|
for ( unsigned index = 0; index < args; ++index ) {
|
||||||
arguments.push_back (argv[index]);
|
arguments.push_back (argv[index]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try
|
||||||
|
{
|
||||||
ConfigManager cfg(logger, arguments);
|
ConfigManager cfg(logger, arguments);
|
||||||
EventBus eventBus(logger);
|
EventBus eventBus(logger);
|
||||||
Resolver::Server resolver(logger, eventBus);
|
Resolver::Server resolver(logger, eventBus);
|
||||||
@@ -56,13 +57,15 @@ int main(int args, char **argv) {
|
|||||||
// Run something on main thread...
|
// Run something on main thread...
|
||||||
logger.info.ln ("Shutting down PlaiNS. Good Bye!");
|
logger.info.ln ("Shutting down PlaiNS. Good Bye!");
|
||||||
}
|
}
|
||||||
catch (Exception& e)
|
catch (Exception& e) {
|
||||||
{
|
|
||||||
logger.fatal << "Uncaught Exception: " << e.what() << Logger::commit;
|
logger.fatal << "Uncaught Exception: " << e.what() << Logger::commit;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
catch (int e)
|
catch (std::system_error& e) {
|
||||||
{
|
logger.fatal << "Uncaught system_error exception: " << e.what() << Logger::commit;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
catch (int e) {
|
||||||
logger.fatal << "Uncaught Exception with error code " << e << Logger::commit;
|
logger.fatal << "Uncaught Exception with error code " << e << Logger::commit;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ namespace Plains {
|
|||||||
namespace Resolver {
|
namespace Resolver {
|
||||||
|
|
||||||
using asio::ip::udp;
|
using asio::ip::udp;
|
||||||
|
using asio::ip::tcp;
|
||||||
|
|
||||||
static char* byteToHex(char c) {
|
static char* byteToHex(char c) {
|
||||||
static char* out = new char[3];
|
static char* out = new char[3];
|
||||||
@@ -93,9 +94,12 @@ Server::Server(Logger& logger, EventBus& eventBus)
|
|||||||
_udpSocket = new udp::socket(_ioContext, udp::endpoint(udp::v4(), 8853));
|
_udpSocket = new udp::socket(_ioContext, udp::endpoint(udp::v4(), 8853));
|
||||||
_ioContext.run();
|
_ioContext.run();
|
||||||
doReceive();
|
doReceive();
|
||||||
|
_logger.debug.ln ("Resolver started");
|
||||||
}
|
}
|
||||||
|
|
||||||
Server::~Server() {}
|
Server::~Server() {
|
||||||
|
_udpSocket->close();
|
||||||
|
}
|
||||||
|
|
||||||
//void Server::run() {
|
//void Server::run() {
|
||||||
// _ioContext.run();
|
// _ioContext.run();
|
||||||
@@ -129,4 +133,6 @@ void Server::doSend(std::size_t length)
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}}
|
}}
|
||||||
Reference in new issue
Block a user