summaryrefslogtreecommitdiffstats
path: root/src/Common
diff options
context:
space:
mode:
authorMatthias Schiffer <matthias@gamezock.de>2009-04-28 22:36:59 +0200
committerMatthias Schiffer <matthias@gamezock.de>2009-04-28 22:36:59 +0200
commit539d7e2cfbc8fef2837c47312107a8314108158b (patch)
tree0675c479bfd39c836e1784961ad9d1943abaf464 /src/Common
parent71dc41a9b7b0e939314a886383daa6fb2e297a55 (diff)
downloadmad-539d7e2cfbc8fef2837c47312107a8314108158b.tar
mad-539d7e2cfbc8fef2837c47312107a8314108158b.zip
ThreadManager angefangen; Logger laeuft jetzt in eigenem Thread
Diffstat (limited to 'src/Common')
-rw-r--r--src/Common/LogManager.cpp115
-rw-r--r--src/Common/LogManager.h65
-rw-r--r--src/Common/Makefile.am7
-rw-r--r--src/Common/Makefile.in61
-rw-r--r--src/Common/RequestHandlers/Makefile.in44
-rw-r--r--src/Common/RequestManager.cpp1
-rw-r--r--src/Common/Requests/Makefile.in44
-rw-r--r--src/Common/ThreadManager.cpp109
-rw-r--r--src/Common/ThreadManager.h90
9 files changed, 474 insertions, 62 deletions
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 <iostream>
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<Logger*>(&consoleLogger));
- std::auto_ptr<std::queue<Message> > queue = messageQueue;
-
- while(!queue->empty()) {
- const Message &message = queue->front();
- log(message.category, message.level, message.timestamp, message.message);
- queue->pop();
- }
-
- std::auto_ptr<std::queue<RemoteMessage> > 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<Logger*>::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<Logger*>::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<RemoteLogger*>::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<RemoteLogger*>::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 <config.h>
+
#include "Configurable.h"
#include "Logger.h"
#include "RemoteLogger.h"
-#include <iostream>
-#include <memory>
#include <queue>
#include <set>
+#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<Logger*> loggers;
std::set<RemoteLogger*> remoteLoggers;
+ bool configured, running;
+
+ gl_lock_t lock;
+ gl_cond_t queueCond;
- std::auto_ptr<std::queue<Message> > messageQueue;
- std::auto_ptr<std::queue<RemoteMessage> > remoteMessageQueue;
+ gl_lock_t loggerLock;
+ gl_lock_t remoteLoggerLock;
- LogManager() : messageQueue(new std::queue<Message>()), remoteMessageQueue(new std::queue<RemoteMessage>()) {}
+ std::queue<Message> messageQueue;
+ std::queue<RemoteMessage> 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 <matthias@gamezock.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#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<void> nextWork = work.front();
+ work.pop();
+
+ gl_lock_unlock(workLock);
+
+ nextWork();
+ }
+}
+
+void ThreadManager::pushWork(const sigc::slot<void> &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 <matthias@gamezock.de>
+ *
+ * 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 <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef MAD_COMMON_THREADMANAGER_H_
+#define MAD_COMMON_THREADMANAGER_H_
+
+#include <config.h>
+
+#include "Initializable.h"
+#include "LogManager.h"
+
+#include <queue>
+#include <set>
+#include <sigc++/slot.h>
+
+#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<gl_thread_t> threads;
+
+ gl_lock_t runLock;
+ bool running;
+
+ gl_lock_t workLock;
+ gl_cond_t workCond;
+ std::queue<sigc::slot<void> > 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<void> &newWork);
+
+ static ThreadManager* get() {
+ return &threadManager;
+ }
+};
+
+}
+}
+
+#endif /* MAD_COMMON_THREADMANAGER_H_ */