From 2b83ae7c71dc706fb4fd7b4efc4a8ffee8dfe522 Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Mon, 27 Oct 2008 22:41:06 +0100 Subject: Neues Initialisierung-Framework hinzugef?gt --- src/Common/ConfigManager.h | 4 +- src/Common/Configurable.cpp | 35 --------- src/Common/Configurable.h | 5 +- src/Common/Initializable.cpp | 74 +++++++++++++++++ src/Common/Initializable.h | 54 +++++++++++++ src/Common/LogManager.cpp | 105 +++++++++++++++++++++++++ src/Common/LogManager.h | 98 +++++++++++++++++++++++ src/Common/Logger.cpp | 62 +-------------- src/Common/Logger.h | 39 ++------- src/Common/LoggerBase.h | 2 +- src/Common/Makefile.am | 6 +- src/Common/Makefile.in | 16 ++-- src/Common/RemoteLogger.cpp | 52 ------------ src/Common/RemoteLogger.h | 35 +-------- src/Common/RequestManager.cpp | 4 +- src/Common/RequestManager.h | 20 ++--- src/Common/SharedPtr.h | 101 ++++++++++++++++++++++++ src/Core/ConnectionManager.cpp | 9 ++- src/Core/ConnectionManager.h | 21 +++-- src/Core/RequestHandlers/LogRequestHandler.cpp | 4 +- src/mad-core.cpp | 8 +- src/mad.cpp | 12 ++- src/madc.cpp | 8 +- 23 files changed, 510 insertions(+), 264 deletions(-) delete mode 100644 src/Common/Configurable.cpp create mode 100644 src/Common/Initializable.cpp create mode 100644 src/Common/Initializable.h create mode 100644 src/Common/LogManager.cpp create mode 100644 src/Common/LogManager.h delete mode 100644 src/Common/RemoteLogger.cpp create mode 100644 src/Common/SharedPtr.h diff --git a/src/Common/ConfigManager.h b/src/Common/ConfigManager.h index bf34f6f..b4264d5 100644 --- a/src/Common/ConfigManager.h +++ b/src/Common/ConfigManager.h @@ -20,6 +20,7 @@ #ifndef MAD_COMMON_CONFIGMANAGER_H_ #define MAD_COMMON_CONFIGMANAGER_H_ +#include #include #include @@ -38,7 +39,6 @@ class ConfigManager { static ConfigManager configManager; std::set configurables; - bool finished; ConfigManager() : finished(false) {} @@ -57,8 +57,6 @@ class ConfigManager { configurables.erase(c); } - virtual ~ConfigManager() {} - static ConfigManager *getConfigManager() { return &configManager; } diff --git a/src/Common/Configurable.cpp b/src/Common/Configurable.cpp deleted file mode 100644 index 4d689ed..0000000 --- a/src/Common/Configurable.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Configurable.cpp - * - * Copyright (C) 2008 Matthias Schiffer - * - * 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 3 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 . - */ - -#include "Configurable.h" -#include "ConfigManager.h" - -namespace Mad { -namespace Common { - -Configurable::Configurable() { - ConfigManager::getConfigManager()->registerConfigurable(this); -} - -Configurable::~Configurable() { - ConfigManager::getConfigManager()->unregisterConfigurable(this); -} - -} -} diff --git a/src/Common/Configurable.h b/src/Common/Configurable.h index 0f16058..47f919d 100644 --- a/src/Common/Configurable.h +++ b/src/Common/Configurable.h @@ -28,14 +28,15 @@ class ConfigManager; class Configurable { public: - Configurable(); - virtual ~Configurable(); + virtual ~Configurable() {} virtual int getPriority() const {return 0;} protected: friend class ConfigManager; + Configurable() {} + virtual bool handleConfigEntry(const ConfigEntry&, bool) {return false;} virtual void configFinished() {} }; diff --git a/src/Common/Initializable.cpp b/src/Common/Initializable.cpp new file mode 100644 index 0000000..adcb0fa --- /dev/null +++ b/src/Common/Initializable.cpp @@ -0,0 +1,74 @@ +/* + * Initializable.cpp + * + * Copyright (C) 2008 Matthias Schiffer + * + * 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 3 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 . + */ + +#include "Initializable.h" + +#include "ConfigManager.h" +#include "Configurable.h" +#include "LogManager.h" +#include "Logger.h" + +namespace Mad { +namespace Common { + +std::stack Initializable::initializedObjects; + + +void Initializable::init() { + if(initialized) + return; + + if(initializing) { + Logger::log(Logger::CRITICAL, "Fatal initialization error: cyclic dependencies."); + std::terminate(); + } + + initializing = true; + + if(!(LogManager::getLogManager()->isInitialized() || LogManager::getLogManager()->isInitializing())) + LogManager::getLogManager()->init(); + + doInit(); + + Configurable *c = dynamic_cast(this); + if(c) + ConfigManager::getConfigManager()->registerConfigurable(c); + + initializing = false; + initialized = true; + initializedObjects.push(this); +} + +void Initializable::deinit() { + while(!initializedObjects.empty()) { + Initializable *in = initializedObjects.top(); + + Configurable *c = dynamic_cast(in); + if(c) + ConfigManager::getConfigManager()->unregisterConfigurable(c); + + in->doDeinit(); + in->initialized = false; + + initializedObjects.pop(); + } +} + +} +} diff --git a/src/Common/Initializable.h b/src/Common/Initializable.h new file mode 100644 index 0000000..6f67678 --- /dev/null +++ b/src/Common/Initializable.h @@ -0,0 +1,54 @@ +/* + * Initializable.h + * + * Copyright (C) 2008 Matthias Schiffer + * + * 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 3 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 . + */ + +#ifndef MAD_COMMON_INITIALIZABLE_H_ +#define MAD_COMMON_INITIALIZABLE_H_ + +#include + +namespace Mad { +namespace Common { + +class Initializable { + private: + static std::stack initializedObjects; + + bool initializing; + bool initialized; + + protected: + Initializable() : initializing(false), initialized(false) {} + virtual void doInit() {} + virtual void doDeinit() {} + + public: + virtual ~Initializable() {} + + void init(); + + bool isInitialized() const {return initialized;} + bool isInitializing() const {return initializing;} + + static void deinit(); +}; + +} +} + +#endif /* MAD_COMMON_INITIALIZABLE_H_ */ diff --git a/src/Common/LogManager.cpp b/src/Common/LogManager.cpp new file mode 100644 index 0000000..7b4e898 --- /dev/null +++ b/src/Common/LogManager.cpp @@ -0,0 +1,105 @@ +/* + * LogManager.cpp + * + * Copyright (C) 2008 Matthias Schiffer + * + * 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 3 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 . + */ + +#include "LogManager.h" +#include "ConfigEntry.h" +#include "ConfigManager.h" +#include "Backends/ConsoleLogger.h" +#include "Backends/FileLogger.h" + +namespace Mad { +namespace Common { + +LogManager LogManager::logManager; + + +bool LogManager::handleConfigEntry(const ConfigEntry &entry, bool handled) { + if(handled) + return false; + + if(entry[0].getKey().matches("Logger")) { + if(entry[0][0].matches("Console")) { + if(entry[1].empty()) { + registerLogger(SharedPtr(new Backends::ConsoleLogger())); + return true; + } + } + else if(entry[1].empty()) { + Logger::logf(Logger::WARNING, "Unknown logger '%s'.", entry[0][0].c_str()); + return true; + } + } + + return false; +} + +void LogManager::configFinished() { + SharedPtr consoleLogger; + + if(loggers.empty() || remoteLoggers.empty()) { + consoleLogger = SharedPtr(new Backends::ConsoleLogger()); + + if(loggers.empty()) + registerLogger(consoleLogger.cast()); + + if(remoteLoggers.empty()) + registerLogger(consoleLogger.cast()); + } + + std::auto_ptr > queue = messageQueue; + + while(!queue->empty()) { + const Message &message = queue->front(); + log(message.category, message.level, message.timestamp, message.message); + queue->pop(); + } +} + +void LogManager::log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message) { + if(messageQueue.get()) { // Queue message if loggers aren't configured yet + Message m = {category, level, timestamp, message}; + messageQueue->push(m); + return; + } + + for(std::set >::iterator it = loggers.begin(); it != loggers.end(); ++it) { + SharedPtr logger = *it; + + if(logger->getLevel() >= level && logger->isCategorySet(category)) + logger->logMessage(category, level, timestamp, message); + } +} + +void LogManager::log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message, const std::string &source) { + if(remoteMessageQueue.get()) { // Queue message if loggers aren't configured yet + RemoteMessage m = {category, level, timestamp, message, source}; + remoteMessageQueue->push(m); + return; + } + + for(std::set >::iterator it = remoteLoggers.begin(); it != remoteLoggers.end(); ++it) { + SharedPtr logger = *it; + + if(logger->getLevel() >= level && logger->isCategorySet(category)) + logger->logMessage(category, level, timestamp, message, source); + } +} + +} +} diff --git a/src/Common/LogManager.h b/src/Common/LogManager.h new file mode 100644 index 0000000..c1bba9f --- /dev/null +++ b/src/Common/LogManager.h @@ -0,0 +1,98 @@ +/* + * LogManager.h + * + * Copyright (C) 2008 Matthias Schiffer + * + * 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 3 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 . + */ + +#ifndef MAD_COMMON_LOGMANAGER_H_ +#define MAD_COMMON_LOGMANAGER_H_ + +#include "Configurable.h" +#include "Initializable.h" +#include "Logger.h" +#include "RemoteLogger.h" +#include "SharedPtr.h" + +#include +#include +#include + +namespace Mad { +namespace Common { + +class LogManager : public Initializable, public Configurable { + private: + typedef LoggerBase::MessageCategory MessageCategory; + typedef LoggerBase::MessageLevel MessageLevel; + + struct Message { + MessageCategory category; + MessageLevel level; + time_t timestamp; + std::string message; + }; + + struct RemoteMessage { + MessageCategory category; + MessageLevel level; + time_t timestamp; + std::string message; + std::string source; + }; + + static LogManager logManager; + + std::set > loggers; + std::set > remoteLoggers; + + std::auto_ptr > messageQueue; + std::auto_ptr > remoteMessageQueue; + + LogManager() : messageQueue(new std::queue()), remoteMessageQueue(new std::queue()) {} + + protected: + virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled); + virtual void configFinished(); + + public: + void log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message); + void log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message, const std::string &source); + + void registerLogger(SharedPtr logger) { + loggers.insert(logger); + } + + void unregisterLogger(SharedPtr logger) { + loggers.erase(logger); + } + + void registerLogger(SharedPtr logger) { + remoteLoggers.insert(logger); + } + + void unregisterLogger(SharedPtr logger) { + remoteLoggers.erase(logger); + } + + static LogManager *getLogManager() { + return &logManager; + } +}; + +} +} + +#endif /* MAD_COMMON_LOGMANAGER_H_ */ diff --git a/src/Common/Logger.cpp b/src/Common/Logger.cpp index 51a320f..8586fa9 100644 --- a/src/Common/Logger.cpp +++ b/src/Common/Logger.cpp @@ -18,60 +18,13 @@ */ #include "Logger.h" -#include "ConfigEntry.h" -#include "ConfigManager.h" -#include "Backends/ConsoleLogger.h" -#include "Backends/FileLogger.h" +#include "LogManager.h" #include namespace Mad { namespace Common { -std::auto_ptr Logger::configHelper; -std::set Logger::loggers; -std::auto_ptr > Logger::messageQueue(new std::queue); - -bool Logger::ConfigHelper::handleConfigEntry(const ConfigEntry &entry, bool handled) { - if(handled) - return false; - - if(entry[0].getKey().matches("Logger")) { - if(entry[0][0].matches("Console")) { - if(entry[1].empty()) { - loggers.insert(new Backends::ConsoleLogger()); - return true; - } - } - else if(entry[1].empty()) { - logf(WARNING, "Unknown logger '%s'.", entry[0][0].c_str()); - return true; - } - } - - return false; -} - -void Logger::ConfigHelper::configFinished() { - std::auto_ptr > queue = messageQueue; - - if(loggers.empty()) - loggers.insert(new Backends::ConsoleLogger()); - - while(!queue->empty()) { - const Message &message = queue->front(); - log(message.category, message.level, message.timestamp, message.message); - queue->pop(); - } -} - -Logger::ConfigHelper::~ConfigHelper() { - // TODO delete all those loggers... - - //while(!loggers.empty()) - // delete (*loggers.begin()); -} - void Logger::logfv(MessageCategory category, MessageLevel level, const char *format, va_list ap) { int size = 100; char *buf = (char*)std::malloc(size); @@ -100,17 +53,8 @@ void Logger::logfv(MessageCategory category, MessageLevel level, const char *for } -void Logger::log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message) { - if(messageQueue.get()) { // Queue message if loggers aren't configured yet - Message m = {category, level, timestamp, message}; - messageQueue->push(m); - return; - } - - for(std::set::iterator logger = loggers.begin(); logger != loggers.end(); ++logger) { - if((*logger)->getLevel() >= level && (*logger)->isCategorySet(category)) - (*logger)->logMessage(category, level, timestamp, message); - } +void Logger::log(MessageCategory category, MessageLevel level, const std::string &message) { + LogManager::getLogManager()->log(category, level, std::time(0), message); } void Logger::logf(MessageCategory category, MessageLevel level, const char *format, ...) { diff --git a/src/Common/Logger.h b/src/Common/Logger.h index cf7e7d5..436c232 100644 --- a/src/Common/Logger.h +++ b/src/Common/Logger.h @@ -21,66 +21,41 @@ #define MAD_COMMON_LOGGER_H_ #include "LoggerBase.h" -#include "Configurable.h" -#include #include #include -#include -#include -#include #include namespace Mad { namespace Common { +class LogManager; + class Logger : public LoggerBase { private: - class ConfigHelper : private Configurable { - protected: - virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled); - virtual void configFinished(); - - public: - ~ConfigHelper(); - }; - - struct Message { - MessageCategory category; - MessageLevel level; - time_t timestamp; - std::string message; - }; - - static std::auto_ptr configHelper; - static std::set loggers; - static std::auto_ptr > messageQueue; + friend class LogManager; static void logfv(MessageCategory category, MessageLevel level, const char *format, va_list ap); - static void log(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message); - protected: virtual void logMessage(MessageCategory category, MessageLevel level, time_t timestamp, const std::string &message) = 0; public: - static void initConfigHelper() { - configHelper.reset(new ConfigHelper()); - } + static void log(MessageCategory category, MessageLevel level, const std::string &message); - static void log(MessageCategory category, MessageLevel level, const std::string &message) { - log(category, level, std::time(0), message); - } static void log(MessageCategory category, const std::string &message) { log(category, DEFAULT, message); } + static void log(MessageLevel level, const std::string &message) { log(GENERAL, level, message); } + static void log(const std::string &message) { log(GENERAL, DEFAULT, message); } + static void logf(MessageCategory category, MessageLevel level, const char *format, ...); static void logf(MessageCategory category, const char *format, ...); static void logf(MessageLevel level, const char *format, ...); diff --git a/src/Common/LoggerBase.h b/src/Common/LoggerBase.h index b06f03a..9843d4d 100644 --- a/src/Common/LoggerBase.h +++ b/src/Common/LoggerBase.h @@ -60,7 +60,7 @@ class LoggerBase { categories.reset(); } - bool isCategorySet(MessageCategory category) { + bool isCategorySet(MessageCategory category) const { return categories.test(category); } diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am index 7cfa0d4..bf4df4e 100644 --- a/src/Common/Makefile.am +++ b/src/Common/Makefile.am @@ -1,8 +1,8 @@ SUBDIRS = Backends Requests RequestHandlers noinst_LTLIBRARIES = libcommon.la -libcommon_la_SOURCES = ConfigEntry.cpp ConfigManager.cpp Configurable.cpp Exception.cpp Logger.cpp RemoteLogger.cpp RequestManager.cpp SystemBackend.cpp Tokenizer.cpp +libcommon_la_SOURCES = ConfigEntry.cpp ConfigManager.cpp Exception.cpp Initializable.cpp Logger.cpp LogManager.cpp RequestManager.cpp SystemBackend.cpp Tokenizer.cpp libcommon_la_LIBADD = Backends/libbackends.la Requests/librequests.la RequestHandlers/librequesthandlers.la -noinst_HEADERS = ConfigEntry.h ConfigManager.h Configurable.h Exception.h HostInfo.h Logger.h LoggerBase.h RemoteLogger.h Request.h RequestBase.h \ - RequestHandler.h RequestManager.h SystemBackend.h Tokenizer.h +noinst_HEADERS = ConfigEntry.h ConfigManager.h Configurable.h Exception.h HostInfo.h Initializable.h Logger.h LoggerBase.h LogManager.h RemoteLogger.h Request.h RequestBase.h \ + RequestHandler.h RequestManager.h SharedPtr.h SystemBackend.h Tokenizer.h diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in index 37a874d..15cf675 100644 --- a/src/Common/Makefile.in +++ b/src/Common/Makefile.in @@ -49,9 +49,9 @@ CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libcommon_la_DEPENDENCIES = Backends/libbackends.la \ Requests/librequests.la RequestHandlers/librequesthandlers.la -am_libcommon_la_OBJECTS = ConfigEntry.lo ConfigManager.lo \ - Configurable.lo Exception.lo Logger.lo RemoteLogger.lo \ - RequestManager.lo SystemBackend.lo Tokenizer.lo +am_libcommon_la_OBJECTS = ConfigEntry.lo ConfigManager.lo Exception.lo \ + Initializable.lo Logger.lo LogManager.lo RequestManager.lo \ + SystemBackend.lo Tokenizer.lo libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir)/src depcomp = $(SHELL) $(top_srcdir)/depcomp @@ -201,10 +201,10 @@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ SUBDIRS = Backends Requests RequestHandlers noinst_LTLIBRARIES = libcommon.la -libcommon_la_SOURCES = ConfigEntry.cpp ConfigManager.cpp Configurable.cpp Exception.cpp Logger.cpp RemoteLogger.cpp RequestManager.cpp SystemBackend.cpp Tokenizer.cpp +libcommon_la_SOURCES = ConfigEntry.cpp ConfigManager.cpp Exception.cpp Initializable.cpp Logger.cpp LogManager.cpp RequestManager.cpp SystemBackend.cpp Tokenizer.cpp libcommon_la_LIBADD = Backends/libbackends.la Requests/librequests.la RequestHandlers/librequesthandlers.la -noinst_HEADERS = ConfigEntry.h ConfigManager.h Configurable.h Exception.h HostInfo.h Logger.h LoggerBase.h RemoteLogger.h Request.h RequestBase.h \ - RequestHandler.h RequestManager.h SystemBackend.h Tokenizer.h +noinst_HEADERS = ConfigEntry.h ConfigManager.h Configurable.h Exception.h HostInfo.h Initializable.h Logger.h LoggerBase.h LogManager.h RemoteLogger.h Request.h RequestBase.h \ + RequestHandler.h RequestManager.h SharedPtr.h SystemBackend.h Tokenizer.h all: all-recursive @@ -259,10 +259,10 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigEntry.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConfigManager.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Configurable.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Exception.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Initializable.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/LogManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Logger.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RemoteLogger.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SystemBackend.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Tokenizer.Plo@am__quote@ diff --git a/src/Common/RemoteLogger.cpp b/src/Common/RemoteLogger.cpp deleted file mode 100644 index a678e92..0000000 --- a/src/Common/RemoteLogger.cpp +++ /dev/null @@ -1,52 +0,0 @@ -/* - * LogRequestLogger.cpp - * - * Copyright (C) 2008 Johannes Thorn - * - * 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 3 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 . - */ - -#include "RemoteLogger.h" -#include "ConfigEntry.h" -#include "Logger.h" - -namespace Mad { -namespace Common { - -std::auto_ptr RemoteLogger::configHelper; -std::list RemoteLogger::remoteLoggers; - - -bool RemoteLogger::ConfigHelper::handleConfigEntry(const ConfigEntry &entry, bool handled) { - if(handled) - return false; - - if(entry[0].getKey().matches("RemoteLogger") && entry[1].empty()) { - Logger::logf(WARNING, "Unknown remote logger '%s'.", entry[0][0].c_str()); - return true; - } - - return false; -} - -void RemoteLogger::log(MessageCategory category, MessageLevel level, - time_t messageTimestamp, const std::string &message, const std::string &messageSource) { - for(std::list::iterator remoteLogger = remoteLoggers.begin(); remoteLogger != remoteLoggers.end(); ++remoteLogger) { - if((*remoteLogger)->getLevel() >= level && (*remoteLogger)->isCategorySet(category)) - (*remoteLogger)->logMessage(category, level, messageTimestamp, message, messageSource); - } -} - -} -} diff --git a/src/Common/RemoteLogger.h b/src/Common/RemoteLogger.h index 8ed7836..579a54b 100644 --- a/src/Common/RemoteLogger.h +++ b/src/Common/RemoteLogger.h @@ -21,46 +21,19 @@ #define MAD_COMMON_REMOTELOGGER_H_ #include "LoggerBase.h" -#include "Configurable.h" -#include -#include -#include -#include -#include #include namespace Mad { namespace Common { -class RemoteLogger : public LoggerBase { - private: - class ConfigHelper : private Configurable { - protected: - virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled); - }; - - static std::auto_ptr configHelper; - static std::list remoteLoggers; +class LogManager; +class RemoteLogger : public LoggerBase { protected: - virtual void logMessage(MessageCategory category, MessageLevel level, time_t messageTimestamp, const std::string &message, const std::string &messageSource) = 0; + friend class LogManager; - public: - static void log(MessageCategory category, MessageLevel level, time_t messageTimestamp, const std::string &message, const std::string &messageSource); - - static void registerRemoteLogger(RemoteLogger *remoteLogger) { - remoteLoggers.push_back(remoteLogger); - } - - static void unregisterRemoteLogger(RemoteLogger *remoteLogger) { - std::list::iterator it = std::find(remoteLoggers.begin(), remoteLoggers.end(), remoteLogger); - if(it != remoteLoggers.end()) - remoteLoggers.erase(it); - } - - RemoteLogger() {} - virtual ~RemoteLogger() {} + virtual void logMessage(MessageCategory category, MessageLevel level, time_t messageTimestamp, const std::string &message, const std::string &messageSource) = 0; }; } diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index 8d0c73c..e15ff67 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -30,7 +30,7 @@ namespace Mad { namespace Common { -std::auto_ptr RequestManager::requestManager; +RequestManager RequestManager::requestManager; RequestManager::RequestMap::~RequestMap() { @@ -149,7 +149,7 @@ void RequestManager::unregisterPacketType(Net::Packet::Type type) { requestHandlerFactories.erase(it); } -RequestManager::RequestManager(bool core) : requestId(core ? -2 : -1) { +RequestManager::RequestManager() : core(false) { registerPacketType(Net::Packet::DISCONNECT); } diff --git a/src/Common/RequestManager.h b/src/Common/RequestManager.h index 2013860..b0002d0 100644 --- a/src/Common/RequestManager.h +++ b/src/Common/RequestManager.h @@ -20,19 +20,19 @@ #ifndef MAD_COMMON_REQUESTMANAGER_H_ #define MAD_COMMON_REQUESTMANAGER_H_ +#include "Initializable.h" #include #include #include - namespace Mad { namespace Common { class RequestBase; class RequestHandler; -class RequestManager { +class RequestManager : public Initializable { private: class RequestMap : private std::map { private: @@ -65,9 +65,10 @@ class RequestManager { } }; - static std::auto_ptr requestManager; + static RequestManager requestManager; std::map requestMaps; + bool core; uint16_t requestId; std::map requestHandlerFactories; @@ -80,19 +81,20 @@ class RequestManager { RequestManager(const RequestManager &o); RequestManager& operator=(const RequestManager &o); - RequestManager(bool core); + RequestManager(); void receiveHandler(Net::Connection *connection, const Net::Packet &packet); public: - static void init(bool core) { - requestManager = std::auto_ptr(new RequestManager(core)); - } - static RequestManager* getRequestManager() { - return requestManager.get(); + return &requestManager; } + bool isCore() const {return core;} + void setCore(bool newCore) {core = newCore;} + + virtual void doInit() {requestId = core ? -2 : -1;} + void registerConnection(Net::Connection *connection); void unregisterConnection(Net::Connection *connection); diff --git a/src/Common/SharedPtr.h b/src/Common/SharedPtr.h new file mode 100644 index 0000000..3696344 --- /dev/null +++ b/src/Common/SharedPtr.h @@ -0,0 +1,101 @@ +/* + * SharedPtr.h + * + * Copyright (C) 2008 Johannes Thorn + * + * 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 3 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 . + */ + +#ifndef MAD_COMMON_SHAREDPTR_H_ +#define MAD_COMMON_SHAREDPTR_H_ + +namespace Mad { +namespace Common { + +template +class SharedPtr { + protected: + class Counter { + public: + Counter(T *o) : object(o), refCount(1), cCount(new unsigned int(1)) {} + Counter(T *o, unsigned int *count) : object(o), refCount(1), cCount(count) {++*cCount;} + + virtual ~Counter() { + if(--cCount) + return; + + if(object) + delete object; + + delete cCount; + } + + T *object; + unsigned int refCount; + unsigned int *cCount; + }; + + Counter *counter; + + template + class CastPtr : public SharedPtr { + public: + CastPtr(T *o, unsigned int *cCount) : SharedPtr(o, cCount) {} + }; + + SharedPtr(T *o, unsigned int *cCount) : counter(new Counter(o, cCount)) {} + + public: + SharedPtr(T *o = 0) : counter(new Counter(o)) {} + + SharedPtr(const SharedPtr &c) : counter(c.counter) { + ++counter->refCount; + } + + virtual ~SharedPtr() { + if(--counter->refCount == 0) + delete counter; + } + + SharedPtr& operator=(const SharedPtr& c) { + ++c.counter->refCount; + if(--counter->refCount == 0) + delete counter; + + counter = c.counter; + return *this; + } + + bool empty() const { + return counter->object; + } + + T* operator->() {return counter->object;} + T& operator*() {return *counter->object;} + + const T* operator->() const {return counter->object;} + const T& operator*() const {return *counter->object;} + + bool operator<(const SharedPtr &o) const {return counter->object < o.counter->object;} + bool operator==(const SharedPtr &o) const {return counter->object == o.counter->object;} + + template SharedPtr cast() const { + return CastPtr(counter->object, counter->cCount); + } +}; + +} +} + +#endif /*MAD_COMMON_SHAREDPTR_H_*/ diff --git a/src/Core/ConnectionManager.cpp b/src/Core/ConnectionManager.cpp index ff44da3..3d69165 100644 --- a/src/Core/ConnectionManager.cpp +++ b/src/Core/ConnectionManager.cpp @@ -42,7 +42,7 @@ namespace Mad { namespace Core { -std::auto_ptr ConnectionManager::connectionManager; +ConnectionManager ConnectionManager::connectionManager; void ConnectionManager::updateState(const std::string &name, Common::HostInfo::State state) { @@ -129,8 +129,9 @@ void ConnectionManager::configFinished() { } } -ConnectionManager::ConnectionManager() { - Common::RequestManager::init(true); +void ConnectionManager::doInit() { + Common::RequestManager::getRequestManager()->setCore(true); + Common::RequestManager::getRequestManager()->init(); Common::RequestManager::getRequestManager()->registerPacketType(Net::Packet::FS_INFO); Common::RequestManager::getRequestManager()->registerPacketType(Net::Packet::STATUS); @@ -146,7 +147,7 @@ ConnectionManager::ConnectionManager() { Net::Connection::init(); } -ConnectionManager::~ConnectionManager() { +void ConnectionManager::doDeinit() { for(std::list::iterator con = daemonConnections.begin(); con != daemonConnections.end(); ++con) delete *con; diff --git a/src/Core/ConnectionManager.h b/src/Core/ConnectionManager.h index 29ed280..e9565f9 100644 --- a/src/Core/ConnectionManager.h +++ b/src/Core/ConnectionManager.h @@ -23,13 +23,15 @@ #include #include #include -#include #include #include #include +#include #include +#include + namespace Mad { namespace Net { @@ -41,9 +43,9 @@ class Packet; namespace Core { -class ConnectionManager : private Common::Configurable { +class ConnectionManager : public Common::Initializable, public Common::Configurable { private: - static std::auto_ptr connectionManager; + static ConnectionManager connectionManager; std::string x509TrustFile, x509CrlFile, x509CertFile, x509KeyFile; @@ -60,27 +62,24 @@ class ConnectionManager : private Common::Configurable { ConnectionManager(const ConnectionManager &o); ConnectionManager& operator=(const ConnectionManager &o); - ConnectionManager(); + ConnectionManager() {} void handleConnections(std::list &connections); void updateState(const std::string &name, Common::HostInfo::State state); protected: + virtual void doInit(); + virtual void doDeinit(); + virtual bool handleConfigEntry(const Common::ConfigEntry &entry, bool handled); virtual void configFinished(); public: static ConnectionManager* getConnectionManager() { - return connectionManager.get(); + return &connectionManager; } - static void init() { - connectionManager = std::auto_ptr(new ConnectionManager()); - } - - ~ConnectionManager(); - void run(); Net::Connection* getDaemonConnection(const std::string &name) const throw (Common::Exception&); diff --git a/src/Core/RequestHandlers/LogRequestHandler.cpp b/src/Core/RequestHandlers/LogRequestHandler.cpp index 6bda627..c2b2fde 100644 --- a/src/Core/RequestHandlers/LogRequestHandler.cpp +++ b/src/Core/RequestHandlers/LogRequestHandler.cpp @@ -19,7 +19,7 @@ #include "LogRequestHandler.h" #include -#include +#include #include "../ConnectionManager.h" #include #include @@ -43,7 +43,7 @@ void LogRequestHandler::handlePacket(Net::Connection *connection, const Net::Pac Net::Packets::LogPacket logPacket(packet); try { - Common::RemoteLogger::log(logPacket.getCategory(), logPacket.getLevel(), logPacket.getTimestamp(), logPacket.getMessage().c_str(), + Common::LogManager::getLogManager()->log(logPacket.getCategory(), logPacket.getLevel(), logPacket.getTimestamp(), logPacket.getMessage().c_str(), ConnectionManager::getConnectionManager()->getDaemonName(connection)); } catch(Common::Exception &e) { diff --git a/src/mad-core.cpp b/src/mad-core.cpp index 19c8b05..359abb3 100644 --- a/src/mad-core.cpp +++ b/src/mad-core.cpp @@ -18,10 +18,10 @@ */ #include "Common/ConfigManager.h" +#include "Common/LogManager.h" #include "Common/Logger.h" #include "Common/Backends/SystemBackendPosix.h" #include "Common/Backends/SystemBackendProc.h" -#include "Net/Connection.h" #include "Core/ConnectionManager.h" #include @@ -36,9 +36,7 @@ int main() { sigaddset(&signals, SIGPIPE); sigprocmask(SIG_BLOCK, &signals, 0); - Common::Logger::initConfigHelper(); - - Core::ConnectionManager::init(); + Core::ConnectionManager::getConnectionManager()->init(); Common::ConfigManager::getConfigManager()->loadFile("mad-core.conf"); Common::ConfigManager::getConfigManager()->finish(); @@ -49,5 +47,7 @@ int main() { while(true) Core::ConnectionManager::getConnectionManager()->run(); + Common::Initializable::deinit(); + return 0; } diff --git a/src/mad.cpp b/src/mad.cpp index 36432e1..d2315f1 100644 --- a/src/mad.cpp +++ b/src/mad.cpp @@ -23,6 +23,7 @@ #include "Common/Backends/SystemBackendPosix.h" #include "Common/Backends/SystemBackendProc.h" #include "Common/ConfigManager.h" +#include "Common/LogManager.h" #include "Common/Logger.h" #include "Common/Request.h" #include "Common/RequestManager.h" @@ -44,10 +45,9 @@ static void requestFinished(const Common::Request<>&) { int main() { Net::Connection::init(); - Common::Logger::initConfigHelper(); Common::ConfigManager::getConfigManager()->finish(); - Common::RequestManager::init(false); + Common::RequestManager::getRequestManager()->init(); Common::RequestManager::getRequestManager()->registerPacketType(Net::Packet::FS_INFO); Common::RequestManager::getRequestManager()->registerPacketType(Net::Packet::STATUS); Common::RequestManager::getRequestManager()->registerPacketType(Net::Packet::COMMAND_REBOOT); @@ -66,8 +66,8 @@ int main() { Common::RequestManager::getRequestManager()->registerConnection(connection); - Daemon::Backends::NetworkLogger networkLogger(connection); - //TODO Common::Logger::registerLogger(&networkLogger); + Common::SharedPtr networkLogger = new Daemon::Backends::NetworkLogger(connection); + Common::LogManager::getLogManager()->registerLogger(networkLogger); //char hostname[256]; @@ -78,6 +78,8 @@ int main() { while(connection->isConnected()) Net::FdManager::getFdManager()->run(); + Common::LogManager::getLogManager()->unregisterLogger(networkLogger); + Common::RequestManager::getRequestManager()->unregisterConnection(connection); } catch(Mad::Common::Exception &e) { @@ -86,6 +88,8 @@ int main() { delete connection; + Common::Initializable::deinit(); + Net::Connection::deinit(); return 0; diff --git a/src/madc.cpp b/src/madc.cpp index 0dc1e81..8e1c4cd 100644 --- a/src/madc.cpp +++ b/src/madc.cpp @@ -21,6 +21,7 @@ #include "Net/FdManager.h" #include "Net/IPAddress.h" #include "Common/ConfigManager.h" +#include "Common/LogManager.h" #include "Common/Logger.h" #include "Common/RequestManager.h" #include "Client/CommandParser.h" @@ -81,10 +82,11 @@ int main(int argc, char *argv[]) { Net::Connection::init(); - Common::Logger::initConfigHelper(); + Common::LogManager::getLogManager()->init(); + Common::ConfigManager::getConfigManager()->finish(); - Common::RequestManager::init(false); + Common::RequestManager::getRequestManager()->init(); Net::ClientConnection *connection = new Net::ClientConnection; try { @@ -130,6 +132,8 @@ int main(int argc, char *argv[]) { delete connection; + Common::Initializable::deinit(); + Net::Connection::deinit(); return 0; -- cgit v1.2.3