From 539d7e2cfbc8fef2837c47312107a8314108158b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Tue, 28 Apr 2009 22:36:59 +0200 Subject: ThreadManager angefangen; Logger laeuft jetzt in eigenem Thread --- src/Common/LogManager.cpp | 115 +++++++++++++++++++++++---------- src/Common/LogManager.h | 65 +++++++++++++++---- src/Common/Makefile.am | 7 +- src/Common/Makefile.in | 61 ++++++++++++++--- src/Common/RequestHandlers/Makefile.in | 44 ++++++++++++- src/Common/RequestManager.cpp | 1 + src/Common/Requests/Makefile.in | 44 ++++++++++++- src/Common/ThreadManager.cpp | 109 +++++++++++++++++++++++++++++++ src/Common/ThreadManager.h | 90 ++++++++++++++++++++++++++ 9 files changed, 474 insertions(+), 62 deletions(-) create mode 100644 src/Common/ThreadManager.cpp create mode 100644 src/Common/ThreadManager.h (limited to 'src/Common') diff --git a/src/Common/LogManager.cpp b/src/Common/LogManager.cpp index 61c4bb6..22c688f 100644 --- a/src/Common/LogManager.cpp +++ b/src/Common/LogManager.cpp @@ -19,6 +19,9 @@ #include "LogManager.h" #include "ConfigEntry.h" +#include "ThreadManager.h" + +#include namespace Mad { namespace Common { @@ -26,6 +29,27 @@ namespace Common { LogManager LogManager::logManager; +void LogManager::ConsoleLogger::logMessage(MessageCategory category _UNUSED_PARAMETER_, MessageLevel level, time_t timestamp _UNUSED_PARAMETER_, const std::string &message) { + if(level != CRITICAL) {// Critical messages are printed to cerr directly, so don't print them a second time + gl_lock_lock(cerrLock); + std::cerr << message << std::endl; + gl_lock_unlock(cerrLock); + } +} + +void LogManager::ConsoleLogger::logMessage(MessageCategory category _UNUSED_PARAMETER_, MessageLevel, time_t timestamp _UNUSED_PARAMETER_, const std::string &message, const std::string &messageSource) { + gl_lock_lock(cerrLock); + std::cerr << message << " from " << messageSource << std::endl; + gl_lock_unlock(cerrLock); +} + +void LogManager::ConsoleLogger::logMessageDirect(MessageCategory category _UNUSED_PARAMETER_, MessageLevel level _UNUSED_PARAMETER_, time_t timestamp _UNUSED_PARAMETER_, const std::string &message) { + gl_lock_lock(cerrLock); + std::cerr << message << std::endl; + gl_lock_unlock(cerrLock); +} + + bool LogManager::handleConfigEntry(const ConfigEntry &entry, bool handled) { if(handled) return false; @@ -50,47 +74,72 @@ void LogManager::configFinished() { if(loggers.empty()) registerLogger(static_cast(&consoleLogger)); - std::auto_ptr > queue = messageQueue; - - while(!queue->empty()) { - const Message &message = queue->front(); - log(message.category, message.level, message.timestamp, message.message); - queue->pop(); - } - - std::auto_ptr > queue2 = remoteMessageQueue; - - while(!queue2->empty()) { - const RemoteMessage &message = queue2->front(); - log(message.category, message.level, message.timestamp, message.message, message.source); - queue2->pop(); - } + gl_lock_lock(lock); + configured = true; + gl_cond_signal(queueCond); + gl_lock_unlock(lock); } 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 logger = loggers.begin(); logger != loggers.end(); ++logger) { - if((*logger)->getLevel() >= level && (*logger)->isCategorySet(category)) - (*logger)->logMessage(category, level, timestamp, message); - } + if(level == LoggerBase::CRITICAL) + consoleLogger.logMessageDirect(category, level, timestamp, message); + + gl_lock_lock(lock); + Message m = {category, level, timestamp, message}; + messageQueue.push(m); + gl_cond_signal(queueCond); + gl_lock_unlock(lock); } 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; - } + gl_lock_lock(lock); + RemoteMessage m = {category, level, timestamp, message, source}; + remoteMessageQueue.push(m); + gl_cond_signal(queueCond); + gl_lock_unlock(lock); +} + +void LogManager::loggerThread() { + gl_lock_lock(lock); + + running = true; + + while(running) { + while(running && ((messageQueue.empty() && messageQueue.empty()) || !configured)) + gl_cond_wait(queueCond, lock); + + while(!messageQueue.empty()) { + Message message = messageQueue.front(); + messageQueue.pop(); + gl_lock_unlock(lock); + + gl_lock_lock(loggerLock); + for(std::set::iterator logger = loggers.begin(); logger != loggers.end(); ++logger) { + if((*logger)->getLevel() >= message.level && (*logger)->isCategorySet(message.category)) + (*logger)->logMessage(message.category, message.level, message.timestamp, message.message); + } + gl_lock_unlock(loggerLock); + + gl_lock_lock(lock); + } + + while(!remoteMessageQueue.empty()) { + RemoteMessage message = remoteMessageQueue.front(); + remoteMessageQueue.pop(); + gl_lock_unlock(lock); - for(std::set::iterator logger = remoteLoggers.begin(); logger != remoteLoggers.end(); ++logger) { - if((*logger)->getLevel() >= level && (*logger)->isCategorySet(category)) - (*logger)->logMessage(category, level, timestamp, message, source); + gl_lock_lock(remoteLoggerLock); + for(std::set::iterator logger = remoteLoggers.begin(); logger != remoteLoggers.end(); ++logger) { + if((*logger)->getLevel() >= message.level && (*logger)->isCategorySet(message.category)) + (*logger)->logMessage(message.category, message.level, message.timestamp, message.message, message.source); + } + gl_lock_unlock(remoteLoggerLock); + + gl_lock_lock(lock); + } } + + gl_lock_unlock(lock); } } diff --git a/src/Common/LogManager.h b/src/Common/LogManager.h index 5f2fb17..34a4689 100644 --- a/src/Common/LogManager.h +++ b/src/Common/LogManager.h @@ -20,20 +20,27 @@ #ifndef MAD_COMMON_LOGMANAGER_H_ #define MAD_COMMON_LOGMANAGER_H_ +#include + #include "Configurable.h" #include "Logger.h" #include "RemoteLogger.h" -#include -#include #include #include +#include "glthread/lock.h" +#include "glthread/cond.h" + namespace Mad { namespace Common { +class ThreadManager; + class LogManager : public Configurable { private: + friend class ThreadManager; + typedef LoggerBase::MessageCategory MessageCategory; typedef LoggerBase::MessageLevel MessageLevel; @@ -53,16 +60,19 @@ class LogManager : public Configurable { }; class ConsoleLogger : public Logger, public RemoteLogger { + private: + // For long messages, writing to cerr is not atomic + // -> lock cerr to prevent mixing messages up + gl_lock_t cerrLock; + protected: - virtual void logMessage(MessageCategory, MessageLevel, time_t, const std::string &message) { - std::cerr << message << std::endl; - } - virtual void logMessage(MessageCategory, MessageLevel, time_t, const std::string &message, const std::string &messageSource) { - std::cerr << message << " from "<< messageSource << std::endl; - } + virtual void logMessage(MessageCategory category _UNUSED_PARAMETER_, MessageLevel level, time_t timestamp _UNUSED_PARAMETER_, const std::string &message); + virtual void logMessage(MessageCategory category _UNUSED_PARAMETER_, MessageLevel, time_t timestamp _UNUSED_PARAMETER_, const std::string &message, const std::string &messageSource); public: ConsoleLogger() {} + + void logMessageDirect(MessageCategory category _UNUSED_PARAMETER_, MessageLevel level _UNUSED_PARAMETER_, time_t timestamp _UNUSED_PARAMETER_, const std::string &message); }; @@ -72,34 +82,67 @@ class LogManager : public Configurable { std::set loggers; std::set remoteLoggers; + bool configured, running; + + gl_lock_t lock; + gl_cond_t queueCond; - std::auto_ptr > messageQueue; - std::auto_ptr > remoteMessageQueue; + gl_lock_t loggerLock; + gl_lock_t remoteLoggerLock; - LogManager() : messageQueue(new std::queue()), remoteMessageQueue(new std::queue()) {} + std::queue messageQueue; + std::queue remoteMessageQueue; + + void loggerThread(); + void stopLoggerThread() { + gl_lock_lock(lock); + running = false; + gl_cond_signal(queueCond); + gl_lock_unlock(lock); + } + + LogManager() : configured(false), running(false) { + gl_lock_init(lock); + gl_lock_init(loggerLock); + gl_lock_init(remoteLoggerLock); + } protected: virtual bool handleConfigEntry(const ConfigEntry &entry, bool handled); virtual void configFinished(); public: + ~LogManager() { + gl_lock_destroy(remoteLoggerLock); + gl_lock_destroy(loggerLock); + gl_lock_destroy(lock); + } + 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(Logger *logger) { + gl_lock_lock(loggerLock); loggers.insert(logger); + gl_lock_unlock(loggerLock); } void unregisterLogger(Logger *logger) { + gl_lock_lock(loggerLock); loggers.erase(logger); + gl_lock_unlock(loggerLock); } void registerLogger(RemoteLogger *logger) { + gl_lock_lock(remoteLoggerLock); remoteLoggers.insert(logger); + gl_lock_unlock(remoteLoggerLock); } void unregisterLogger(RemoteLogger *logger) { + gl_lock_lock(remoteLoggerLock); remoteLoggers.erase(logger); + gl_lock_unlock(remoteLoggerLock); } static LogManager *get() { diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am index dd27afe..60184d4 100644 --- a/src/Common/Makefile.am +++ b/src/Common/Makefile.am @@ -4,11 +4,12 @@ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ActionManager.cpp ClientConnection.cpp ConfigEntry.cpp ConfigManager.cpp \ Connection.cpp Exception.cpp Initializable.cpp Logger.cpp LogManager.cpp \ ModuleManager.cpp Request.cpp RequestManager.cpp SystemManager.cpp \ - Tokenizer.cpp XmlPacket.cpp + ThreadManager.cpp Tokenizer.cpp XmlPacket.cpp libcommon_la_LIBADD = Requests/librequests.la RequestHandlers/librequesthandlers.la ../../lib/libgnu.la +libcommon_la_LDFLAGS = $(LTLIBMULTITHREAD) $(LTLIBTHREAD) noinst_HEADERS = ActionManager.h ClientConnection.h ConfigEntry.h ConfigManager.h \ Configurable.h Connection.h Exception.h HostInfo.h Initializable.h Logger.h \ LoggerBase.h LogManager.h ModuleManager.h RemoteLogger.h Request.h \ - RequestHandler.h RequestManager.h SystemBackend.h SystemManager.h Tokenizer.h \ - UserInfo.h XmlPacket.h + RequestHandler.h RequestManager.h SystemBackend.h SystemManager.h \ + ThreadManager.h Tokenizer.h UserInfo.h XmlPacket.h diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in index a17d8a1..541090d 100644 --- a/src/Common/Makefile.in +++ b/src/Common/Makefile.in @@ -39,12 +39,20 @@ DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ $(top_srcdir)/m4/argz.m4 $(top_srcdir)/m4/ax_lib_mysql.m4 \ - $(top_srcdir)/m4/base64.m4 $(top_srcdir)/m4/gnulib-common.m4 \ - $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/base64.m4 $(top_srcdir)/m4/cond.m4 \ + $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/extensions.m4 \ + $(top_srcdir)/m4/gettimeofday.m4 \ + $(top_srcdir)/m4/gnulib-common.m4 \ + $(top_srcdir)/m4/gnulib-comp.m4 \ + $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \ $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ - $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/sys_time_h.m4 \ + $(top_srcdir)/m4/thread.m4 $(top_srcdir)/m4/threadlib.m4 \ + $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -56,9 +64,12 @@ libcommon_la_DEPENDENCIES = Requests/librequests.la \ am_libcommon_la_OBJECTS = ActionManager.lo ClientConnection.lo \ ConfigEntry.lo ConfigManager.lo Connection.lo Exception.lo \ Initializable.lo Logger.lo LogManager.lo ModuleManager.lo \ - Request.lo RequestManager.lo SystemManager.lo Tokenizer.lo \ - XmlPacket.lo + Request.lo RequestManager.lo SystemManager.lo ThreadManager.lo \ + Tokenizer.lo XmlPacket.lo libcommon_la_OBJECTS = $(am_libcommon_la_OBJECTS) +libcommon_la_LINK = $(LIBTOOL) --tag=CXX $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ + $(CXXFLAGS) $(libcommon_la_LDFLAGS) $(LDFLAGS) -o $@ DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp am__depfiles_maybe = depfiles @@ -113,14 +124,25 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ +EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ +ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ +ENOLINK_VALUE = @ENOLINK_VALUE@ +EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ +EOVERFLOW_VALUE = @EOVERFLOW_VALUE@ +ERRNO_H = @ERRNO_H@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ GSSAPI_LIBS = @GSSAPI_LIBS@ GnuTLS_CFLAGS = @GnuTLS_CFLAGS@ GnuTLS_LIBS = @GnuTLS_LIBS@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ HAVE__BOOL = @HAVE__BOOL@ INCLTDL = @INCLTDL@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -133,15 +155,22 @@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBLTDL = @LIBLTDL@ +LIBMULTITHREAD = @LIBMULTITHREAD@ LIBOBJS = @LIBOBJS@ +LIBPTH = @LIBPTH@ +LIBPTH_PREFIX = @LIBPTH_PREFIX@ LIBS = @LIBS@ +LIBTHREAD = @LIBTHREAD@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTDLDEPS = @LTDLDEPS@ LTDLINCL = @LTDLINCL@ LTDLOPEN = @LTDLOPEN@ +LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ LTLIBOBJS = @LTLIBOBJS@ +LTLIBPTH = @LTLIBPTH@ +LTLIBTHREAD = @LTLIBTHREAD@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ @@ -152,6 +181,9 @@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_VERSION = @MYSQL_VERSION@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ +NEXT_TIME_H = @NEXT_TIME_H@ NM = @NM@ NMEDIT = @NMEDIT@ OBJEXT = @OBJEXT@ @@ -165,13 +197,22 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +REPLACE_STRPTIME = @REPLACE_STRPTIME@ +REPLACE_TIMEGM = @REPLACE_TIMEGM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STDBOOL_H = @STDBOOL_H@ STRIP = @STRIP@ +SYS_TIME_H = @SYS_TIME_H@ +SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ @@ -245,14 +286,15 @@ noinst_LTLIBRARIES = libcommon.la libcommon_la_SOURCES = ActionManager.cpp ClientConnection.cpp ConfigEntry.cpp ConfigManager.cpp \ Connection.cpp Exception.cpp Initializable.cpp Logger.cpp LogManager.cpp \ ModuleManager.cpp Request.cpp RequestManager.cpp SystemManager.cpp \ - Tokenizer.cpp XmlPacket.cpp + ThreadManager.cpp Tokenizer.cpp XmlPacket.cpp libcommon_la_LIBADD = Requests/librequests.la RequestHandlers/librequesthandlers.la ../../lib/libgnu.la +libcommon_la_LDFLAGS = $(LTLIBMULTITHREAD) $(LTLIBTHREAD) noinst_HEADERS = ActionManager.h ClientConnection.h ConfigEntry.h ConfigManager.h \ Configurable.h Connection.h Exception.h HostInfo.h Initializable.h Logger.h \ LoggerBase.h LogManager.h ModuleManager.h RemoteLogger.h Request.h \ - RequestHandler.h RequestManager.h SystemBackend.h SystemManager.h Tokenizer.h \ - UserInfo.h XmlPacket.h + RequestHandler.h RequestManager.h SystemBackend.h SystemManager.h \ + ThreadManager.h Tokenizer.h UserInfo.h XmlPacket.h all: all-recursive @@ -297,7 +339,7 @@ clean-noinstLTLIBRARIES: rm -f "$${dir}/so_locations"; \ done libcommon.la: $(libcommon_la_OBJECTS) $(libcommon_la_DEPENDENCIES) - $(CXXLINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS) + $(libcommon_la_LINK) $(libcommon_la_OBJECTS) $(libcommon_la_LIBADD) $(LIBS) mostlyclean-compile: -rm -f *.$(OBJEXT) @@ -318,6 +360,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Request.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/RequestManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/SystemManager.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ThreadManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Tokenizer.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/XmlPacket.Plo@am__quote@ diff --git a/src/Common/RequestHandlers/Makefile.in b/src/Common/RequestHandlers/Makefile.in index b7c01a3..8595870 100644 --- a/src/Common/RequestHandlers/Makefile.in +++ b/src/Common/RequestHandlers/Makefile.in @@ -39,12 +39,20 @@ DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ $(top_srcdir)/m4/argz.m4 $(top_srcdir)/m4/ax_lib_mysql.m4 \ - $(top_srcdir)/m4/base64.m4 $(top_srcdir)/m4/gnulib-common.m4 \ - $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/base64.m4 $(top_srcdir)/m4/cond.m4 \ + $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/extensions.m4 \ + $(top_srcdir)/m4/gettimeofday.m4 \ + $(top_srcdir)/m4/gnulib-common.m4 \ + $(top_srcdir)/m4/gnulib-comp.m4 \ + $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \ $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ - $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/sys_time_h.m4 \ + $(top_srcdir)/m4/thread.m4 $(top_srcdir)/m4/threadlib.m4 \ + $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -99,14 +107,25 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ +EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ +ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ +ENOLINK_VALUE = @ENOLINK_VALUE@ +EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ +EOVERFLOW_VALUE = @EOVERFLOW_VALUE@ +ERRNO_H = @ERRNO_H@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ GSSAPI_LIBS = @GSSAPI_LIBS@ GnuTLS_CFLAGS = @GnuTLS_CFLAGS@ GnuTLS_LIBS = @GnuTLS_LIBS@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ HAVE__BOOL = @HAVE__BOOL@ INCLTDL = @INCLTDL@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -119,15 +138,22 @@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBLTDL = @LIBLTDL@ +LIBMULTITHREAD = @LIBMULTITHREAD@ LIBOBJS = @LIBOBJS@ +LIBPTH = @LIBPTH@ +LIBPTH_PREFIX = @LIBPTH_PREFIX@ LIBS = @LIBS@ +LIBTHREAD = @LIBTHREAD@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTDLDEPS = @LTDLDEPS@ LTDLINCL = @LTDLINCL@ LTDLOPEN = @LTDLOPEN@ +LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ LTLIBOBJS = @LTLIBOBJS@ +LTLIBPTH = @LTLIBPTH@ +LTLIBTHREAD = @LTLIBTHREAD@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ @@ -138,6 +164,9 @@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_VERSION = @MYSQL_VERSION@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ +NEXT_TIME_H = @NEXT_TIME_H@ NM = @NM@ NMEDIT = @NMEDIT@ OBJEXT = @OBJEXT@ @@ -151,13 +180,22 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +REPLACE_STRPTIME = @REPLACE_STRPTIME@ +REPLACE_TIMEGM = @REPLACE_TIMEGM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STDBOOL_H = @STDBOOL_H@ STRIP = @STRIP@ +SYS_TIME_H = @SYS_TIME_H@ +SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index 23f620f..75f07cf 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -78,6 +78,7 @@ void RequestManager::receiveHandler(Connection *connection, const XmlPacket &pac if(request) { request->handlePacket(packet); + return; } diff --git a/src/Common/Requests/Makefile.in b/src/Common/Requests/Makefile.in index 0472724..a150e6a 100644 --- a/src/Common/Requests/Makefile.in +++ b/src/Common/Requests/Makefile.in @@ -39,12 +39,20 @@ DIST_COMMON = $(noinst_HEADERS) $(srcdir)/Makefile.am \ ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 am__aclocal_m4_deps = $(top_srcdir)/m4/00gnulib.m4 \ $(top_srcdir)/m4/argz.m4 $(top_srcdir)/m4/ax_lib_mysql.m4 \ - $(top_srcdir)/m4/base64.m4 $(top_srcdir)/m4/gnulib-common.m4 \ - $(top_srcdir)/m4/gnulib-comp.m4 $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/base64.m4 $(top_srcdir)/m4/cond.m4 \ + $(top_srcdir)/m4/errno_h.m4 $(top_srcdir)/m4/extensions.m4 \ + $(top_srcdir)/m4/gettimeofday.m4 \ + $(top_srcdir)/m4/gnulib-common.m4 \ + $(top_srcdir)/m4/gnulib-comp.m4 \ + $(top_srcdir)/m4/include_next.m4 $(top_srcdir)/m4/lib-ld.m4 \ + $(top_srcdir)/m4/lib-link.m4 $(top_srcdir)/m4/lib-prefix.m4 \ + $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/lock.m4 \ $(top_srcdir)/m4/ltdl.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/pkg.m4 \ - $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/configure.ac + $(top_srcdir)/m4/stdbool.m4 $(top_srcdir)/m4/sys_time_h.m4 \ + $(top_srcdir)/m4/thread.m4 $(top_srcdir)/m4/threadlib.m4 \ + $(top_srcdir)/m4/time_h.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d @@ -99,14 +107,25 @@ ECHO_C = @ECHO_C@ ECHO_N = @ECHO_N@ ECHO_T = @ECHO_T@ EGREP = @EGREP@ +EMULTIHOP_HIDDEN = @EMULTIHOP_HIDDEN@ +EMULTIHOP_VALUE = @EMULTIHOP_VALUE@ +ENOLINK_HIDDEN = @ENOLINK_HIDDEN@ +ENOLINK_VALUE = @ENOLINK_VALUE@ +EOVERFLOW_HIDDEN = @EOVERFLOW_HIDDEN@ +EOVERFLOW_VALUE = @EOVERFLOW_VALUE@ +ERRNO_H = @ERRNO_H@ EXEEXT = @EXEEXT@ FGREP = @FGREP@ GREP = @GREP@ GSSAPI_LIBS = @GSSAPI_LIBS@ GnuTLS_CFLAGS = @GnuTLS_CFLAGS@ GnuTLS_LIBS = @GnuTLS_LIBS@ +HAVE_STRUCT_TIMEVAL = @HAVE_STRUCT_TIMEVAL@ +HAVE_SYS_TIME_H = @HAVE_SYS_TIME_H@ HAVE__BOOL = @HAVE__BOOL@ INCLTDL = @INCLTDL@ +INCLUDE_NEXT = @INCLUDE_NEXT@ +INCLUDE_NEXT_AS_FIRST_DIRECTIVE = @INCLUDE_NEXT_AS_FIRST_DIRECTIVE@ INSTALL = @INSTALL@ INSTALL_DATA = @INSTALL_DATA@ INSTALL_PROGRAM = @INSTALL_PROGRAM@ @@ -119,15 +138,22 @@ LIBADD_DLD_LINK = @LIBADD_DLD_LINK@ LIBADD_DLOPEN = @LIBADD_DLOPEN@ LIBADD_SHL_LOAD = @LIBADD_SHL_LOAD@ LIBLTDL = @LIBLTDL@ +LIBMULTITHREAD = @LIBMULTITHREAD@ LIBOBJS = @LIBOBJS@ +LIBPTH = @LIBPTH@ +LIBPTH_PREFIX = @LIBPTH_PREFIX@ LIBS = @LIBS@ +LIBTHREAD = @LIBTHREAD@ LIBTOOL = @LIBTOOL@ LIPO = @LIPO@ LN_S = @LN_S@ LTDLDEPS = @LTDLDEPS@ LTDLINCL = @LTDLINCL@ LTDLOPEN = @LTDLOPEN@ +LTLIBMULTITHREAD = @LTLIBMULTITHREAD@ LTLIBOBJS = @LTLIBOBJS@ +LTLIBPTH = @LTLIBPTH@ +LTLIBTHREAD = @LTLIBTHREAD@ LT_CONFIG_H = @LT_CONFIG_H@ LT_DLLOADERS = @LT_DLLOADERS@ LT_DLPREOPEN = @LT_DLPREOPEN@ @@ -138,6 +164,9 @@ MYSQL_CFLAGS = @MYSQL_CFLAGS@ MYSQL_CONFIG = @MYSQL_CONFIG@ MYSQL_LDFLAGS = @MYSQL_LDFLAGS@ MYSQL_VERSION = @MYSQL_VERSION@ +NEXT_ERRNO_H = @NEXT_ERRNO_H@ +NEXT_SYS_TIME_H = @NEXT_SYS_TIME_H@ +NEXT_TIME_H = @NEXT_TIME_H@ NM = @NM@ NMEDIT = @NMEDIT@ OBJEXT = @OBJEXT@ @@ -151,13 +180,22 @@ PACKAGE_TARNAME = @PACKAGE_TARNAME@ PACKAGE_VERSION = @PACKAGE_VERSION@ PATH_SEPARATOR = @PATH_SEPARATOR@ PKG_CONFIG = @PKG_CONFIG@ +PRAGMA_SYSTEM_HEADER = @PRAGMA_SYSTEM_HEADER@ RANLIB = @RANLIB@ READLINE_LIBS = @READLINE_LIBS@ +REPLACE_GETTIMEOFDAY = @REPLACE_GETTIMEOFDAY@ +REPLACE_LOCALTIME_R = @REPLACE_LOCALTIME_R@ +REPLACE_NANOSLEEP = @REPLACE_NANOSLEEP@ +REPLACE_STRPTIME = @REPLACE_STRPTIME@ +REPLACE_TIMEGM = @REPLACE_TIMEGM@ SED = @SED@ SET_MAKE = @SET_MAKE@ SHELL = @SHELL@ STDBOOL_H = @STDBOOL_H@ STRIP = @STRIP@ +SYS_TIME_H = @SYS_TIME_H@ +SYS_TIME_H_DEFINES_STRUCT_TIMESPEC = @SYS_TIME_H_DEFINES_STRUCT_TIMESPEC@ +TIME_H_DEFINES_STRUCT_TIMESPEC = @TIME_H_DEFINES_STRUCT_TIMESPEC@ VERSION = @VERSION@ abs_builddir = @abs_builddir@ abs_srcdir = @abs_srcdir@ diff --git a/src/Common/ThreadManager.cpp b/src/Common/ThreadManager.cpp new file mode 100644 index 0000000..6b2606c --- /dev/null +++ b/src/Common/ThreadManager.cpp @@ -0,0 +1,109 @@ +/* + * ThreadManager.cpp + * + * Copyright (C) 2009 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 "ThreadManager.h" + +namespace Mad { +namespace Common { + +ThreadManager ThreadManager::threadManager; + + +void ThreadManager::workerFunc() { + while(true) { + gl_lock_lock(runLock); + + if(!running || !isThisWorkerThread()) { + gl_lock_unlock(runLock); + return; + } + + gl_lock_unlock(runLock); + + gl_lock_lock(workLock); + while(work.empty()) { + gl_cond_wait(workCond, workLock); + + if(!running) { + gl_lock_unlock(workLock); + return; + } + } + + sigc::slot nextWork = work.front(); + work.pop(); + + gl_lock_unlock(workLock); + + nextWork(); + } +} + +void ThreadManager::pushWork(const sigc::slot &newWork) { + gl_lock_lock(workLock); + + work.push(newWork); + + gl_cond_signal(workCond); + gl_lock_unlock(workLock); +} + + +void ThreadManager::doInit() { + gl_lock_init(runLock); + gl_lock_init(workLock); + gl_cond_init(workCond); + + gl_lock_lock(runLock); + running = true; + + mainThread = (gl_thread_t)gl_thread_self(); + workerThread = gl_thread_create(&ThreadManager::workerStart, 0); + loggerThread = gl_thread_create(&ThreadManager::loggerStart, 0); + + gl_lock_unlock(runLock); +} + +void ThreadManager::doDeinit() { + if(!isThisMainThread()) { + // TODO Critical error!!! + return; + } + + gl_lock_lock(runLock); + gl_lock_lock(workLock); + + running = false; + gl_cond_signal(workCond); + + gl_lock_unlock(workLock); + gl_lock_unlock(runLock); + + LogManager::get()->stopLoggerThread(); + + gl_thread_join(workerThread, 0); + gl_thread_join(loggerThread, 0); + + gl_cond_destroy(workCond); + gl_lock_destroy(workLock); + gl_lock_destroy(runLock); +} + +} +} diff --git a/src/Common/ThreadManager.h b/src/Common/ThreadManager.h new file mode 100644 index 0000000..07ab196 --- /dev/null +++ b/src/Common/ThreadManager.h @@ -0,0 +1,90 @@ +/* + * ThreadManager.h + * + * Copyright (C) 2009 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_THREADMANAGER_H_ +#define MAD_COMMON_THREADMANAGER_H_ + +#include + +#include "Initializable.h" +#include "LogManager.h" + +#include +#include +#include + +#include "glthread/thread.h" +#include "glthread/lock.h" +#include "glthread/cond.h" + +namespace Mad { +namespace Common { + +class ThreadManager : public Initializable { + private: + gl_thread_t mainThread, workerThread, loggerThread; + std::set threads; + + gl_lock_t runLock; + bool running; + + gl_lock_t workLock; + gl_cond_t workCond; + std::queue > work; + + static ThreadManager threadManager; + + ThreadManager() {} + + static void* workerStart(void*) { + threadManager.workerFunc(); + return 0; + } + + static void* loggerStart(void*) { + LogManager::get()->loggerThread(); + return 0; + } + + void workerFunc(); + + protected: + virtual void doInit(); + virtual void doDeinit(); + + public: + bool isThisMainThread() const { + return (mainThread == (gl_thread_t)gl_thread_self()); + } + + bool isThisWorkerThread() const { + return (workerThread == (gl_thread_t)gl_thread_self()); + } + + void pushWork(const sigc::slot &newWork); + + static ThreadManager* get() { + return &threadManager; + } +}; + +} +} + +#endif /* MAD_COMMON_THREADMANAGER_H_ */ -- cgit v1.2.3