From 8324b947487f72fd8cfc439ea5ae5bd1187fff1b Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Wed, 6 May 2009 17:39:30 +0200 Subject: Exception und ThreadHandler nach Net verschoben --- Konzept/Klassen.txt | 75 +++++++ configure | 8 +- configure.ac | 7 +- lib/Makefile.am | 8 +- lib/Makefile.in | 6 +- lib/ignore-value.h | 45 +++++ m4/gnulib-cache.m4 | 3 +- m4/gnulib-comp.m4 | 2 + src/Client/CommandManager.cpp | 16 +- src/Client/CommandParser.cpp | 1 - src/Client/InformationManager.cpp | 4 +- src/Common/ClientConnection.cpp | 6 +- src/Common/ClientConnection.h | 6 +- src/Common/Connection.cpp | 7 +- src/Common/Connection.h | 4 +- src/Common/Exception.cpp | 63 ------ src/Common/Exception.h | 61 ------ src/Common/LogManager.cpp | 1 - src/Common/LogManager.h | 7 +- src/Common/Makefile.am | 8 +- src/Common/Makefile.in | 17 +- src/Common/Request.cpp | 4 +- src/Common/Request.h | 10 +- src/Common/RequestHandler.h | 4 +- .../RequestHandlers/DisconnectRequestHandler.cpp | 4 +- .../RequestHandlers/FSInfoRequestHandler.cpp | 6 +- .../RequestHandlers/StatusRequestHandler.cpp | 4 +- src/Common/RequestManager.cpp | 2 +- src/Common/Requests/DisconnectRequest.cpp | 4 +- src/Common/Requests/GSSAPIAuthRequest.cpp | 17 +- src/Common/ThreadManager.cpp | 153 --------------- src/Common/ThreadManager.h | 105 ---------- .../RequestHandlers/CommandRequestHandler.cpp | 6 +- src/Net/ClientConnection.cpp | 8 +- src/Net/ClientConnection.h | 4 +- src/Net/Exception.cpp | 63 ++++++ src/Net/Exception.h | 61 ++++++ src/Net/IPAddress.cpp | 10 +- src/Net/IPAddress.h | 6 +- src/Net/Listener.cpp | 10 +- src/Net/Listener.h | 3 +- src/Net/Makefile.am | 6 +- src/Net/Makefile.in | 15 +- src/Net/ServerConnection.h | 1 - src/Net/ThreadManager.cpp | 215 +++++++++++++++++++++ src/Net/ThreadManager.h | 113 +++++++++++ src/Server/ConnectionManager.cpp | 30 +-- src/Server/ConnectionManager.h | 9 +- .../DaemonCommandRequestHandler.cpp | 6 +- .../RequestHandlers/DaemonFSInfoRequestHandler.cpp | 6 +- .../RequestHandlers/DaemonListRequestHandler.cpp | 2 +- .../RequestHandlers/DaemonStatusRequestHandler.cpp | 6 +- .../RequestHandlers/GSSAPIAuthRequestHandler.cpp | 15 +- .../RequestHandlers/IdentifyRequestHandler.cpp | 4 +- src/Server/RequestHandlers/LogRequestHandler.cpp | 4 +- .../RequestHandlers/UserInfoRequestHandler.cpp | 6 +- .../RequestHandlers/UserListRequestHandler.cpp | 6 +- src/mad-server.cpp | 4 +- src/mad.cpp | 6 +- src/madc.cpp | 6 +- 60 files changed, 746 insertions(+), 553 deletions(-) create mode 100644 Konzept/Klassen.txt create mode 100644 lib/ignore-value.h delete mode 100644 src/Common/Exception.cpp delete mode 100644 src/Common/Exception.h delete mode 100644 src/Common/ThreadManager.cpp delete mode 100644 src/Common/ThreadManager.h create mode 100644 src/Net/Exception.cpp create mode 100644 src/Net/Exception.h create mode 100644 src/Net/ThreadManager.cpp create mode 100644 src/Net/ThreadManager.h diff --git a/Konzept/Klassen.txt b/Konzept/Klassen.txt new file mode 100644 index 0000000..799ffc9 --- /dev/null +++ b/Konzept/Klassen.txt @@ -0,0 +1,75 @@ +M läuft im Main-Thread +W läuft im Worker-Thread +T ist Thread-safe +D sind Datenstrukturen +? TODO + + +? Client::CommandManager +? Client::CommandParser +? Client::InformationManager +W Client::Requests::DaemonCommandRequest +W Client::Requests::DaemonFSInfoRequest +W Client::Requests::DaemonListRequest +W Client::Requests::DaemonStatusRequest +T Common::ClientConnection +D Common::ConfigEntry +? Common::ConfigManager +? Common::Configurable +T Common::Connection +D Common::Exception +D Common::HostInfo +? Common::Initializable +T Common::LoggerBase +T Common::Logger +T Common::LogManager +? Common::ModuleManager +T Common::RemoteLogger +W Common::Request +W Common::RequestHandler +W Common::RequestHandlers::DisconnectRequestHandler +W Common::RequestHandlers::FSInfoRequestHandler +W Common::RequestHandlers::StatusRequestHandler +? Common::RequestManager +W Common::Requests::DisconnectRequest +W Common::Requests::FSInfoRequest +W Common::Requests::GSSAPIAuthRequest +W Common::Requests::SimpleRequest +W Common::Requests::StatusRequest +W Common::Requests::UserInfoRequest +W Common::Requests::UserListRequest +W Common::SystemBackend +W Common::SystemManager +T Common::ThreadManager +D Common::Tokenizer +D Common::UserInfo +D Common::XmlPacket +? Daemon::Backends::NetworkLogger +W Daemon::RequestHandlers::CommandRequestHandler +W Daemon::Requests::IdentifyRequest +W Daemon::Requests::LogRequest +? modules::FileLogger +? modules::SystemBackendPosix +? modules::SystemBackendProc +? modules::UserBackendMysql +? Net::ClientConnection +? Net::Connection +? Net::FdManager +D Net::IPAddress +? Net::Listener +D Net::Packet +? Net::ServerConnection +? Server::ConnectionManager +W Server::RequestHandlers::DaemonCommandRequestHandler +W Server::RequestHandlers::DaemonFSInfoRequestHandler +W Server::RequestHandlers::DaemonListRequestHandler +W Server::RequestHandlers::DaemonStatusRequestHandler +W Server::RequestHandlers::GSSAPIAuthRequestHandler +W Server::RequestHandlers::IdentifyRequestHandler +W Server::RequestHandlers::LogRequestHandler +W Server::RequestHandlers::UserInfoRequestHandler +W Server::RequestHandlers::UserListRequestHandler +W Server::Requests::CommandRequest +W Server::Requests::DaemonStateUpdateRequest +W Server::UserBackend +W Server::UserManager diff --git a/configure b/configure index 1b4a11c..2f91f8b 100755 --- a/configure +++ b/configure @@ -24402,6 +24402,7 @@ done + if test "$gl_threads_api" = posix; then # OSF/1 4.0 and MacOS X 10.1 lack the pthread_rwlock_t type and the # pthread_rwlock_* functions. @@ -26565,9 +26566,9 @@ fi done -with_systembackend_proc=no - -{ $as_echo "$as_me:$LINENO: checking for /proc/uptime" >&5 +if test x"$with_systembackend_proc" = x; then + with_systembackend_proc=no + { $as_echo "$as_me:$LINENO: checking for /proc/uptime" >&5 $as_echo_n "checking for /proc/uptime... " >&6; } if test "${ac_cv_file__proc_uptime+set}" = set; then $as_echo_n "(cached) " >&6 @@ -26643,6 +26644,7 @@ _ACEOF with_systembackend_proc=yes fi +fi # Check whether --with-systembackend_posix was given. diff --git a/configure.ac b/configure.ac index fe6363d..d49a98e 100644 --- a/configure.ac +++ b/configure.ac @@ -69,9 +69,10 @@ AC_FUNC_REALLOC AC_TYPE_SIGNAL AC_CHECK_FUNCS([dup2 gethostname memmove memset socket strcasecmp strchr strdup strerror strrchr strtol]) -with_systembackend_proc=no - -AC_CHECK_FILES([/proc/uptime /proc/meminfo /proc/loadavg], with_systembackend_proc=yes) +if test x"$with_systembackend_proc" = x; then + with_systembackend_proc=no + AC_CHECK_FILES([/proc/uptime /proc/meminfo /proc/loadavg], with_systembackend_proc=yes) +fi AC_ARG_WITH([systembackend_posix], [AS_HELP_STRING([--with-systembackend-posix], [enable POSIX system backend @<:@default=yes@:>@])]) diff --git a/lib/Makefile.am b/lib/Makefile.am index 906cdb0..e0f95a2 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -9,7 +9,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=config --libtool --macro-prefix=gl --no-vc-files base64 cond thread +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=config --libtool --macro-prefix=gl --no-vc-files base64 cond ignore-value thread AUTOMAKE_OPTIONS = 1.5 gnits subdir-objects @@ -91,6 +91,12 @@ EXTRA_DIST += $(top_srcdir)/config/config.rpath ## end gnulib module havelib +## begin gnulib module ignore-value + +libgnu_la_SOURCES += ignore-value.h + +## end gnulib module ignore-value + ## begin gnulib module lock libgnu_la_SOURCES += glthread/lock.h glthread/lock.c diff --git a/lib/Makefile.in b/lib/Makefile.in index d5b3b48..3ebf543 100644 --- a/lib/Makefile.in +++ b/lib/Makefile.in @@ -23,7 +23,7 @@ # the same distribution terms as the rest of that program. # # Generated by gnulib-tool. -# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=config --libtool --macro-prefix=gl --no-vc-files base64 cond thread +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=config --libtool --macro-prefix=gl --no-vc-files base64 cond ignore-value thread @@ -309,8 +309,8 @@ DISTCLEANFILES = MAINTAINERCLEANFILES = AM_CPPFLAGS = libgnu_la_SOURCES = base64.h base64.c glthread/cond.h glthread/cond.c \ - glthread/lock.h glthread/lock.c glthread/thread.h \ - glthread/thread.c glthread/threadlib.c + ignore-value.h glthread/lock.h glthread/lock.c \ + glthread/thread.h glthread/thread.c glthread/threadlib.c libgnu_la_LIBADD = $(gl_LTLIBOBJS) libgnu_la_DEPENDENCIES = $(gl_LTLIBOBJS) EXTRA_libgnu_la_SOURCES = gettimeofday.c diff --git a/lib/ignore-value.h b/lib/ignore-value.h new file mode 100644 index 0000000..5f97c91 --- /dev/null +++ b/lib/ignore-value.h @@ -0,0 +1,45 @@ +/* ignore a value to quiet a compiler warning + + Copyright (C) 2008 Free Software Foundation, Inc. + + 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 . */ + +/* Written by Jim Meyering. */ + +#ifndef __attribute__ +# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 8) +# define __attribute__(x) +# endif +#endif + +/* Use this function to avoid a warning when using a function declared with + gcc's warn_unused_result attribute, but for which you really do want to + ignore the result. Traditionally, people have used a "(void)" cast to + indicate that a function's return value is deliberately unused. However, + if the function is declared with __attribute__((warn_unused_result)), + gcc issues a warning even with the cast. + + Caution: most of the time, you really should heed gcc's warning, and + check the return value. However, in those exceptional cases in which + you're sure you know what you're doing, use this function. + + For the record, here's one of the ignorable warnings: + "copy.c:233: warning: ignoring return value of 'fchown', + declared with attribute warn_unused_result". */ + +static inline void +ignore_value (int i __attribute__ ((__unused__))) +{ + /* empty */ +} diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 index 005c6ab..c49637b 100644 --- a/m4/gnulib-cache.m4 +++ b/m4/gnulib-cache.m4 @@ -15,13 +15,14 @@ # Specification in the form of a command-line invocation: -# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=config --libtool --macro-prefix=gl --no-vc-files base64 cond thread +# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=config --libtool --macro-prefix=gl --no-vc-files base64 cond ignore-value thread # Specification in the form of a few gnulib-tool.m4 macro invocations: gl_LOCAL_DIR([]) gl_MODULES([ base64 cond + ignore-value thread ]) gl_AVOID([]) diff --git a/m4/gnulib-comp.m4 b/m4/gnulib-comp.m4 index 3fc3f08..9cfa479 100644 --- a/m4/gnulib-comp.m4 +++ b/m4/gnulib-comp.m4 @@ -47,6 +47,7 @@ AC_DEFUN([gl_INIT], gl_COND AC_REQUIRE([gl_HEADER_ERRNO_H]) gl_FUNC_GETTIMEOFDAY + AC_REQUIRE([AC_C_INLINE]) gl_LOCK AM_STDBOOL_H gl_HEADER_SYS_TIME_H @@ -194,6 +195,7 @@ AC_DEFUN([gl_FILE_LIST], [ lib/glthread/thread.c lib/glthread/thread.h lib/glthread/threadlib.c + lib/ignore-value.h lib/stdbool.in.h lib/sys_time.in.h lib/time.in.h diff --git a/src/Client/CommandManager.cpp b/src/Client/CommandManager.cpp index ad88152..f46bdcd 100644 --- a/src/Client/CommandManager.cpp +++ b/src/Client/CommandManager.cpp @@ -140,7 +140,7 @@ void CommandManager::daemonCommandRequestFinished(const Common::Request &request try { request.getResult(); } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } @@ -153,7 +153,7 @@ void CommandManager::daemonFSInfoRequestFinished(const Common::Request &request) std::cout << "Host file system usage:" << std::endl; printFSInfo(packet); } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } @@ -166,7 +166,7 @@ void CommandManager::daemonStatusRequestFinished(const Common::Request &request) std::cout << "Host status:" << std::endl; printHostStatus(packet); } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } @@ -178,7 +178,7 @@ void CommandManager::disconnectRequestFinished(const Common::Request &request) { request.getResult(); disconnect = true; } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } @@ -191,7 +191,7 @@ void CommandManager::fsInfoRequestFinished(const Common::Request &request) { std::cout << "Server file system usage:" << std::endl; printFSInfo(packet); } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } @@ -204,7 +204,7 @@ void CommandManager::statusRequestFinished(const Common::Request &request) { std::cout << "Server status:" << std::endl; printHostStatus(packet); } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } @@ -218,7 +218,7 @@ void CommandManager::userInfoRequestFinished(const Common::Request &request) { std::cout << " " << (unsigned long)packet["uid"] << ", " << (unsigned long)packet["gid"] << ", " << (const std::string&)packet["username"] << ", " << (const std::string&)packet["fullName"] << std::endl << std::endl; } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } @@ -244,7 +244,7 @@ void CommandManager::userListRequestFinished(const Common::Request &request) { std::cout << std::endl; } - catch(Common::Exception &exception) { + catch(Net::Exception &exception) { Common::Logger::logf(Common::Logger::ERROR, "An error occurred during your request: %s.", exception.strerror().c_str()); } diff --git a/src/Client/CommandParser.cpp b/src/Client/CommandParser.cpp index 8e55c01..1b40046 100644 --- a/src/Client/CommandParser.cpp +++ b/src/Client/CommandParser.cpp @@ -22,7 +22,6 @@ #include "Requests/DaemonFSInfoRequest.h" #include "Requests/DaemonCommandRequest.h" #include "Requests/DaemonStatusRequest.h" -#include #include #include #include diff --git a/src/Client/InformationManager.cpp b/src/Client/InformationManager.cpp index d99791c..6c36495 100644 --- a/src/Client/InformationManager.cpp +++ b/src/Client/InformationManager.cpp @@ -35,7 +35,7 @@ void InformationManager::DaemonStateUpdateRequestHandler::handlePacket(const Com Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -94,7 +94,7 @@ void InformationManager::daemonListRequestFinished(const Common::Request &reques daemons.insert(std::make_pair(info.getName(), info)); } } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::Logger::logf(Common::Logger::CRITICAL, "Host list request failed: %s", e.strerror().c_str()); } diff --git a/src/Common/ClientConnection.cpp b/src/Common/ClientConnection.cpp index e030bfc..0e080fd 100644 --- a/src/Common/ClientConnection.cpp +++ b/src/Common/ClientConnection.cpp @@ -27,11 +27,11 @@ ClientConnection::ClientConnection() : connection(new Net::ClientConnection) { connection->signalReceive().connect(sigc::mem_fun(this, &ClientConnection::receive)); } -bool ClientConnection::send(const Net::Packet &packet) { - return connection->send(packet); +void ClientConnection::send(const Net::Packet &packet) { + connection->send(packet); } -void ClientConnection::connect(const Net::IPAddress &address, bool daemon) throw(Common::Exception) { +void ClientConnection::connect(const Net::IPAddress &address, bool daemon) throw(Net::Exception) { connection->connect(address, daemon); } diff --git a/src/Common/ClientConnection.h b/src/Common/ClientConnection.h index 7e422b0..28a7016 100644 --- a/src/Common/ClientConnection.h +++ b/src/Common/ClientConnection.h @@ -21,7 +21,7 @@ #define MAD_COMMON_CLIENTCONNECTION_H_ #include "Connection.h" -#include "Exception.h" +#include namespace Mad { @@ -37,13 +37,13 @@ class ClientConnection : public Connection { Net::ClientConnection *connection; protected: - virtual bool send(const Net::Packet &packet); + virtual void send(const Net::Packet &packet); public: ClientConnection(); virtual ~ClientConnection() {} - void connect(const Net::IPAddress &address, bool daemon = false) throw(Common::Exception); + void connect(const Net::IPAddress &address, bool daemon = false) throw(Net::Exception); bool isConnecting() const; bool isConnected() const; diff --git a/src/Common/Connection.cpp b/src/Common/Connection.cpp index b4e5db4..cde3fc2 100644 --- a/src/Common/Connection.cpp +++ b/src/Common/Connection.cpp @@ -20,16 +20,19 @@ #include "Connection.h" #include "XmlPacket.h" +#include namespace Mad { namespace Common { void Connection::receive(const Net::Packet &packet) { + // receive() will be called by FdManager (main thread) + // -> let the ThreadManager call the handler in the worker thread signal(XmlPacket(packet), packet.getRequestId()); } -bool Connection::sendPacket(const XmlPacket &packet, uint16_t requestId) { - return send(packet.encode(requestId)); +void Connection::sendPacket(const XmlPacket &packet, uint16_t requestId) { + send(packet.encode(requestId)); } } diff --git a/src/Common/Connection.h b/src/Common/Connection.h index 860c044..7bcb92b 100644 --- a/src/Common/Connection.h +++ b/src/Common/Connection.h @@ -50,12 +50,12 @@ class Connection { void receive(const Net::Packet &packet); - virtual bool send(const Net::Packet &packet) = 0; + virtual void send(const Net::Packet &packet) = 0; public: virtual ~Connection() {} - bool sendPacket(const XmlPacket &packet, uint16_t requestId); + void sendPacket(const XmlPacket &packet, uint16_t requestId); sigc::signal signalReceive() const { return signal; diff --git a/src/Common/Exception.cpp b/src/Common/Exception.cpp deleted file mode 100644 index 67eb1d9..0000000 --- a/src/Common/Exception.cpp +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Exception.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 "Exception.h" - -#include -#include - -namespace Mad { -namespace Common { - -std::string Exception::strerror() const { - std::string ret; - - if(!where.empty()) - ret = where + ": "; - - switch(errorCode) { - case SUCCESS: - return ret + "Success"; - case UNEXPECTED_PACKET: - return ret + "An unexpected packet was received"; - case INVALID_ACTION: - return ret + "The action is invalid"; - case NOT_AVAILABLE: - return ret + "Not available"; - case NOT_FINISHED: - return ret + "Not finished"; - case NOT_IMPLEMENTED: - return ret + "Not implemented"; - case INTERNAL_ERRNO: - return ret + std::strerror(subCode); - case INTERNAL_GNUTLS: - return ret + "GnuTLS error: " + gnutls_strerror(subCode); - case INVALID_ADDRESS: - return ret + "Invalid address"; - case ALREADY_IDENTIFIED: - return ret + "The host is already identified"; - case UNKNOWN_DAEMON: - return ret + "The daemon is unknown"; - default: - return ret + "Unknown error"; - } -} - -} -} diff --git a/src/Common/Exception.h b/src/Common/Exception.h deleted file mode 100644 index 7b86fbd..0000000 --- a/src/Common/Exception.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Exception.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_EXCEPTION_H_ -#define MAD_COMMON_EXCEPTION_H_ - -#include - -namespace Mad { -namespace Common { - -class Exception { - public: - enum ErrorCode { - SUCCESS = 0x0000, UNEXPECTED_PACKET = 0x0001, INVALID_ACTION = 0x0002, NOT_AVAILABLE = 0x0003, NOT_FINISHED = 0x0004, NOT_IMPLEMENTED = 0x0005, - INTERNAL_ERRNO = 0x0010, INTERNAL_GNUTLS = 0x0011, - INVALID_ADDRESS = 0x0020, - ALREADY_IDENTIFIED = 0x0030, UNKNOWN_DAEMON = 0x0031 - }; - - private: - std::string where; - - ErrorCode errorCode; - long subCode; - long subSubCode; - - public: - Exception(const std::string &where0, ErrorCode errorCode0, long subCode0 = 0, long subSubCode0 = 0) - : where(where0), errorCode(errorCode0), subCode(subCode0), subSubCode(subSubCode0) {} - Exception(ErrorCode errorCode0, long subCode0 = 0, long subSubCode0 = 0) : errorCode(errorCode0), subCode(subCode0), subSubCode(subSubCode0) {} - virtual ~Exception() {} - - const std::string& getWhere() const {return where;} - ErrorCode getErrorCode() const {return errorCode;} - long getSubCode() const {return subCode;} - long getSubSubCode() const {return subSubCode;} - - std::string strerror() const; -}; - -} -} - -#endif /* MAD_COMMON_EXCEPTION_H_ */ diff --git a/src/Common/LogManager.cpp b/src/Common/LogManager.cpp index 22c688f..5741d38 100644 --- a/src/Common/LogManager.cpp +++ b/src/Common/LogManager.cpp @@ -19,7 +19,6 @@ #include "LogManager.h" #include "ConfigEntry.h" -#include "ThreadManager.h" #include diff --git a/src/Common/LogManager.h b/src/Common/LogManager.h index 34a4689..1e10e0b 100644 --- a/src/Common/LogManager.h +++ b/src/Common/LogManager.h @@ -33,13 +33,16 @@ #include "glthread/cond.h" namespace Mad { -namespace Common { +namespace Net { class ThreadManager; +} + +namespace Common { class LogManager : public Configurable { private: - friend class ThreadManager; + friend class Net::ThreadManager; typedef LoggerBase::MessageCategory MessageCategory; typedef LoggerBase::MessageLevel MessageLevel; diff --git a/src/Common/Makefile.am b/src/Common/Makefile.am index 60184d4..e50461a 100644 --- a/src/Common/Makefile.am +++ b/src/Common/Makefile.am @@ -2,14 +2,14 @@ SUBDIRS = Requests RequestHandlers 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 \ + Connection.cpp Initializable.cpp Logger.cpp LogManager.cpp \ ModuleManager.cpp Request.cpp RequestManager.cpp SystemManager.cpp \ - ThreadManager.cpp Tokenizer.cpp XmlPacket.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 \ + Configurable.h Connection.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 \ - ThreadManager.h Tokenizer.h UserInfo.h XmlPacket.h + Tokenizer.h UserInfo.h XmlPacket.h diff --git a/src/Common/Makefile.in b/src/Common/Makefile.in index 541090d..915c3bb 100644 --- a/src/Common/Makefile.in +++ b/src/Common/Makefile.in @@ -62,10 +62,9 @@ LTLIBRARIES = $(noinst_LTLIBRARIES) libcommon_la_DEPENDENCIES = Requests/librequests.la \ RequestHandlers/librequesthandlers.la ../../lib/libgnu.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 ThreadManager.lo \ - Tokenizer.lo XmlPacket.lo + ConfigEntry.lo ConfigManager.lo Connection.lo Initializable.lo \ + Logger.lo LogManager.lo ModuleManager.lo Request.lo \ + RequestManager.lo SystemManager.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) \ @@ -284,17 +283,17 @@ top_srcdir = @top_srcdir@ SUBDIRS = Requests RequestHandlers 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 \ + Connection.cpp Initializable.cpp Logger.cpp LogManager.cpp \ ModuleManager.cpp Request.cpp RequestManager.cpp SystemManager.cpp \ - ThreadManager.cpp Tokenizer.cpp XmlPacket.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 \ + Configurable.h Connection.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 \ - ThreadManager.h Tokenizer.h UserInfo.h XmlPacket.h + Tokenizer.h UserInfo.h XmlPacket.h all: all-recursive @@ -352,7 +351,6 @@ 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)/Connection.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@ @@ -360,7 +358,6 @@ 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/Request.cpp b/src/Common/Request.cpp index bc37708..5f4c201 100644 --- a/src/Common/Request.cpp +++ b/src/Common/Request.cpp @@ -24,11 +24,11 @@ namespace Common { void Request::handlePacket(const XmlPacket &packet) { if(packet.getType() == "Error") { - finishWithError(Common::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"])); + finishWithError(Net::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"])); return; } else if(packet.getType() != "OK") { - finishWithError(Exception(Exception::UNEXPECTED_PACKET)); + finishWithError(Net::Exception(Net::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } diff --git a/src/Common/Request.h b/src/Common/Request.h index 7048a4e..7ab2816 100644 --- a/src/Common/Request.h +++ b/src/Common/Request.h @@ -21,7 +21,7 @@ #define MAD_COMMON_XMLREQUEST_H_ #include "RequestHandler.h" -#include "Exception.h" +#include #include #include @@ -36,27 +36,27 @@ class Request : public RequestHandler { sigc::signal finished; std::auto_ptr res; - Exception exp; + Net::Exception exp; public: typedef sigc::slot slot_type; protected: Request(Connection *connection, uint16_t requestId, slot_type slot) - : RequestHandler(connection, requestId), exp(Exception::NOT_FINISHED) { + : RequestHandler(connection, requestId), exp(Net::Exception::NOT_FINISHED) { finished.connect(slot); finished.connect(sigc::hide(signalFinished().make_slot())); } void finish(std::auto_ptr result) {res = result; finished(*this);} void finish(const XmlPacket& result) {res.reset(new XmlPacket(result)); finished(*this);} - void finishWithError(const Exception &e) {exp = e; finished(*this);} + void finishWithError(const Net::Exception &e) {exp = e; finished(*this);} virtual void sendRequest() = 0; virtual void handlePacket(const XmlPacket &packet); public: - const XmlPacket& getResult() const throw(Exception) { + const XmlPacket& getResult() const throw(Net::Exception) { if(res.get()) return *res; diff --git a/src/Common/RequestHandler.h b/src/Common/RequestHandler.h index a0922a7..e3ac19f 100644 --- a/src/Common/RequestHandler.h +++ b/src/Common/RequestHandler.h @@ -56,8 +56,8 @@ class RequestHandler { return requestId; } - bool sendPacket(const XmlPacket &packet) { - return connection->sendPacket(packet, requestId); + void sendPacket(const XmlPacket &packet) { + connection->sendPacket(packet, requestId); } virtual void handlePacket(const XmlPacket &packet) = 0; diff --git a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp index 9204f43..fa2ad88 100644 --- a/src/Common/RequestHandlers/DisconnectRequestHandler.cpp +++ b/src/Common/RequestHandlers/DisconnectRequestHandler.cpp @@ -18,7 +18,7 @@ */ #include "DisconnectRequestHandler.h" -#include "../Exception.h" +#include #include "../Logger.h" namespace Mad { @@ -31,7 +31,7 @@ void DisconnectRequestHandler::handlePacket(const XmlPacket &packet) { XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); diff --git a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp index 7421ad2..fc98730 100644 --- a/src/Common/RequestHandlers/FSInfoRequestHandler.cpp +++ b/src/Common/RequestHandlers/FSInfoRequestHandler.cpp @@ -18,7 +18,7 @@ */ #include "FSInfoRequestHandler.h" -#include "../Exception.h" +#include #include "../Logger.h" namespace Mad { @@ -31,7 +31,7 @@ void FSInfoRequestHandler::handlePacket(const XmlPacket &packet) { XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -44,7 +44,7 @@ void FSInfoRequestHandler::handlePacket(const XmlPacket &packet) { if(!SystemManager::get()->getFSInfo(sigc::mem_fun(this, &FSInfoRequestHandler::fsInfoHandler))) { XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Exception::NOT_IMPLEMENTED); + ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); sendPacket(ret); diff --git a/src/Common/RequestHandlers/StatusRequestHandler.cpp b/src/Common/RequestHandlers/StatusRequestHandler.cpp index 1464f71..0cfe025 100644 --- a/src/Common/RequestHandlers/StatusRequestHandler.cpp +++ b/src/Common/RequestHandlers/StatusRequestHandler.cpp @@ -18,7 +18,7 @@ */ #include "StatusRequestHandler.h" -#include "../Exception.h" +#include #include "../SystemBackend.h" #include "../Logger.h" @@ -32,7 +32,7 @@ void StatusRequestHandler::handlePacket(const XmlPacket &packet) { XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); diff --git a/src/Common/RequestManager.cpp b/src/Common/RequestManager.cpp index 1edf778..08be0a9 100644 --- a/src/Common/RequestManager.cpp +++ b/src/Common/RequestManager.cpp @@ -96,7 +96,7 @@ void RequestManager::receiveHandler(Connection *connection, const XmlPacket &pac XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); connection->sendPacket(ret, requestId); } diff --git a/src/Common/Requests/DisconnectRequest.cpp b/src/Common/Requests/DisconnectRequest.cpp index 248f8b1..3fac25b 100644 --- a/src/Common/Requests/DisconnectRequest.cpp +++ b/src/Common/Requests/DisconnectRequest.cpp @@ -32,11 +32,11 @@ void DisconnectRequest::sendRequest() { void DisconnectRequest::handlePacket(const XmlPacket &packet) { if(packet.getType() == "Error") { - finishWithError(Common::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"])); + finishWithError(Net::Exception(packet["Where"], packet["ErrorCode"], packet["SubCode"], packet["SubSubCode"])); return; } else if(packet.getType() != "OK") { - finishWithError(Exception(Exception::UNEXPECTED_PACKET)); + finishWithError(Net::Exception(Net::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } diff --git a/src/Common/Requests/GSSAPIAuthRequest.cpp b/src/Common/Requests/GSSAPIAuthRequest.cpp index f10bf9b..ffc7939 100644 --- a/src/Common/Requests/GSSAPIAuthRequest.cpp +++ b/src/Common/Requests/GSSAPIAuthRequest.cpp @@ -68,17 +68,14 @@ void GSSAPIAuthRequest::sendRequest() { ret.setType("AuthGSSAPI"); ret.addBinary("authToken", buffer.value, buffer.length); - if(!sendPacket(ret)) { - gss_release_buffer(&minStat, &buffer); - return; - } + sendPacket(ret); gss_release_buffer(&minStat, &buffer); } void GSSAPIAuthRequest::handlePacket(const XmlPacket &packet) { if(packet.getType() != "AuthGSSAPI") { - finishWithError(Exception(Exception::UNEXPECTED_PACKET)); + finishWithError(Net::Exception(Net::Exception::UNEXPECTED_PACKET)); return; // TODO Logging } @@ -112,10 +109,7 @@ void GSSAPIAuthRequest::handlePacket(const XmlPacket &packet) { ret.setType("AuthGSSAPI"); ret.addBinary("authToken", sendBuffer.value, sendBuffer.length); - if(!sendPacket(ret)) { - gss_release_buffer(&minStat, &sendBuffer); - return; - } + sendPacket(ret); gss_release_buffer(&minStat, &sendBuffer); } @@ -153,10 +147,7 @@ void GSSAPIAuthRequest::handlePacket(const XmlPacket &packet) { ret.setType("AuthGSSAPI"); ret.addBinary("authToken", sendBuffer.value, sendBuffer.length); - if(!sendPacket(ret)) { - gss_release_buffer(&minStat, &sendBuffer); - return; - } + sendPacket(ret); gss_release_buffer(&minStat, &sendBuffer); diff --git a/src/Common/ThreadManager.cpp b/src/Common/ThreadManager.cpp deleted file mode 100644 index c0f4d74..0000000 --- a/src/Common/ThreadManager.cpp +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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" - -#include - -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(); - } - - // And let the new worker thread join us... - pushWork(sigc::bind(sigc::mem_fun(this, &ThreadManager::threadFinished), (gl_thread_t)gl_thread_self())); -} - -void ThreadManager::detach() { - if(!isThisMainThread()) { - Logger::log(Logger::CRITICAL, "Tried to detach main thread! This is just WRONG!"); - return; - } - - gl_lock_lock(runLock); - bool isRunning = running; - gl_lock_unlock(runLock); - if(!isRunning) // There's no point in creating a new worker thread when we aren't running anymore - return; - - gl_lock_lock(threadLock); - - if(workerThread == (gl_thread_t)gl_thread_self()) {// Already detached? - threads.insert(workerThread); - workerThread = gl_thread_create(&ThreadManager::workerStart, 0); - } - - gl_lock_unlock(threadLock); -} - -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(threadLock); - gl_lock_init(runLock); - gl_lock_init(workLock); - gl_cond_init(workCond); - - running = true; - - gl_lock_lock(threadLock); - - mainThread = (gl_thread_t)gl_thread_self(); - workerThread = gl_thread_create(&ThreadManager::workerStart, 0); - loggerThread = gl_thread_create(&ThreadManager::loggerStart, 0); - - gl_lock_unlock(threadLock); -} - -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); - - // We don't have to lock threadLock as detach() won't change workerThread when running is false - gl_thread_join(workerThread, 0); - - // Now wait for all detached threads - gl_lock_lock(threadLock); - while(!threads.empty()) { - gl_thread_t thread = *threads.begin(); - gl_lock_unlock(threadLock); - - gl_thread_join(thread, 0); - - gl_lock_lock(threadLock); - threads.erase(thread); - } - gl_lock_unlock(threadLock); - - LogManager::get()->stopLoggerThread(); - gl_thread_join(loggerThread, 0); - - gl_cond_destroy(workCond); - gl_lock_destroy(workLock); - gl_lock_destroy(runLock); - gl_lock_destroy(threadLock); -} - -} -} diff --git a/src/Common/ThreadManager.h b/src/Common/ThreadManager.h deleted file mode 100644 index 6e8616f..0000000 --- a/src/Common/ThreadManager.h +++ /dev/null @@ -1,105 +0,0 @@ -/* - * 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 threadLock; - - 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(); - - void threadFinished(gl_thread_t thread) { - gl_lock_lock(threadLock); - threads.erase(thread); - gl_lock_unlock(threadLock); - - gl_thread_join(thread, 0); - } - - protected: - virtual void doInit(); - virtual void doDeinit(); - - public: - bool isThisMainThread() { - return (mainThread == (gl_thread_t)gl_thread_self()); - } - - bool isThisWorkerThread() { - gl_lock_lock(threadLock); - bool ret = (workerThread == (gl_thread_t)gl_thread_self()); - gl_lock_unlock(threadLock); - return ret; - } - - void detach(); - - void pushWork(const sigc::slot &newWork); - - static ThreadManager* get() { - return &threadManager; - } -}; - -} -} - -#endif /* MAD_COMMON_THREADMANAGER_H_ */ diff --git a/src/Daemon/RequestHandlers/CommandRequestHandler.cpp b/src/Daemon/RequestHandlers/CommandRequestHandler.cpp index ad5908a..939f1f0 100644 --- a/src/Daemon/RequestHandlers/CommandRequestHandler.cpp +++ b/src/Daemon/RequestHandlers/CommandRequestHandler.cpp @@ -18,7 +18,7 @@ */ #include "CommandRequestHandler.h" -#include +#include #include #include @@ -32,7 +32,7 @@ void CommandRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -56,7 +56,7 @@ void CommandRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::NOT_IMPLEMENTED); + ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); sendPacket(ret); diff --git a/src/Net/ClientConnection.cpp b/src/Net/ClientConnection.cpp index 31c1a08..0162a86 100644 --- a/src/Net/ClientConnection.cpp +++ b/src/Net/ClientConnection.cpp @@ -54,7 +54,7 @@ void ClientConnection::connectionHeader() { rawReceive(sizeof(ConnectionHeader), sigc::mem_fun(this, &ClientConnection::connectionHeaderReceiveHandler)); } -void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(Common::Exception) { +void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(Exception) { daemon = daemon0; if(isConnected()) @@ -63,7 +63,7 @@ void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(Com sock = socket(PF_INET, SOCK_STREAM, 0); if(sock < 0) - throw Common::Exception("socket()", Common::Exception::INTERNAL_ERRNO, errno); + throw Exception("socket()", Exception::INTERNAL_ERRNO, errno); if(peer) delete peer; @@ -73,7 +73,7 @@ void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(Com close(sock); delete peer; peer = 0; - throw Common::Exception("connect()", Common::Exception::INTERNAL_ERRNO, errno); + throw Exception("connect()", Exception::INTERNAL_ERRNO, errno); } // Set non-blocking flag @@ -82,7 +82,7 @@ void ClientConnection::connect(const IPAddress &address, bool daemon0) throw(Com if(flags < 0) { close(sock); - throw Common::Exception("fcntl()", Common::Exception::INTERNAL_ERRNO, errno); + throw Exception("fcntl()", Exception::INTERNAL_ERRNO, errno); } fcntl(sock, F_SETFL, flags | O_NONBLOCK); diff --git a/src/Net/ClientConnection.h b/src/Net/ClientConnection.h index 88bdf09..bdd7872 100644 --- a/src/Net/ClientConnection.h +++ b/src/Net/ClientConnection.h @@ -21,7 +21,7 @@ #define MAD_NET_CLIENTCONNECTION_H_ #include "Connection.h" -#include +#include "Exception.h" namespace Mad { namespace Net { @@ -40,7 +40,7 @@ class ClientConnection : public Connection { public: ClientConnection() : daemon(0) {} - void connect(const IPAddress &address, bool daemon0 = false) throw(Common::Exception); + void connect(const IPAddress &address, bool daemon0 = false) throw(Exception); }; } diff --git a/src/Net/Exception.cpp b/src/Net/Exception.cpp new file mode 100644 index 0000000..34b8033 --- /dev/null +++ b/src/Net/Exception.cpp @@ -0,0 +1,63 @@ +/* + * Exception.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 "Exception.h" + +#include +#include + +namespace Mad { +namespace Net { + +std::string Exception::strerror() const { + std::string ret; + + if(!where.empty()) + ret = where + ": "; + + switch(errorCode) { + case SUCCESS: + return ret + "Success"; + case UNEXPECTED_PACKET: + return ret + "An unexpected packet was received"; + case INVALID_ACTION: + return ret + "The action is invalid"; + case NOT_AVAILABLE: + return ret + "Not available"; + case NOT_FINISHED: + return ret + "Not finished"; + case NOT_IMPLEMENTED: + return ret + "Not implemented"; + case INTERNAL_ERRNO: + return ret + std::strerror(subCode); + case INTERNAL_GNUTLS: + return ret + "GnuTLS error: " + gnutls_strerror(subCode); + case INVALID_ADDRESS: + return ret + "Invalid address"; + case ALREADY_IDENTIFIED: + return ret + "The host is already identified"; + case UNKNOWN_DAEMON: + return ret + "The daemon is unknown"; + default: + return ret + "Unknown error"; + } +} + +} +} diff --git a/src/Net/Exception.h b/src/Net/Exception.h new file mode 100644 index 0000000..48e86d1 --- /dev/null +++ b/src/Net/Exception.h @@ -0,0 +1,61 @@ +/* + * Exception.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_NET_EXCEPTION_H_ +#define MAD_NET_EXCEPTION_H_ + +#include + +namespace Mad { +namespace Net { + +class Exception { + public: + enum ErrorCode { + SUCCESS = 0x0000, UNEXPECTED_PACKET = 0x0001, INVALID_ACTION = 0x0002, NOT_AVAILABLE = 0x0003, NOT_FINISHED = 0x0004, NOT_IMPLEMENTED = 0x0005, + INTERNAL_ERRNO = 0x0010, INTERNAL_GNUTLS = 0x0011, + INVALID_ADDRESS = 0x0020, + ALREADY_IDENTIFIED = 0x0030, UNKNOWN_DAEMON = 0x0031 + }; + + private: + std::string where; + + ErrorCode errorCode; + long subCode; + long subSubCode; + + public: + Exception(const std::string &where0, ErrorCode errorCode0, long subCode0 = 0, long subSubCode0 = 0) + : where(where0), errorCode(errorCode0), subCode(subCode0), subSubCode(subSubCode0) {} + Exception(ErrorCode errorCode0, long subCode0 = 0, long subSubCode0 = 0) : errorCode(errorCode0), subCode(subCode0), subSubCode(subSubCode0) {} + virtual ~Exception() {} + + const std::string& getWhere() const {return where;} + ErrorCode getErrorCode() const {return errorCode;} + long getSubCode() const {return subCode;} + long getSubSubCode() const {return subSubCode;} + + std::string strerror() const; +}; + +} +} + +#endif /* MAD_NET_EXCEPTION_H_ */ diff --git a/src/Net/IPAddress.cpp b/src/Net/IPAddress.cpp index 6bf79a3..eb9d3be 100644 --- a/src/Net/IPAddress.cpp +++ b/src/Net/IPAddress.cpp @@ -36,7 +36,7 @@ IPAddress::IPAddress(uint32_t address, uint16_t port0) : addr(address), port(por sa.sin_addr.s_addr = htonl(addr); } -IPAddress::IPAddress(const std::string &address) throw(Common::Exception) { +IPAddress::IPAddress(const std::string &address) throw(Exception) { std::string ip; size_t pos = address.find_first_of(':'); @@ -51,7 +51,7 @@ IPAddress::IPAddress(const std::string &address) throw(Common::Exception) { char *endptr; port = std::strtol(address.substr(pos+1).c_str(), &endptr, 10); if(*endptr != 0 || port == 0) - throw Common::Exception(Common::Exception::INVALID_ADDRESS); + throw Exception(Exception::INVALID_ADDRESS); } sa.sin_family = AF_INET; @@ -60,17 +60,17 @@ IPAddress::IPAddress(const std::string &address) throw(Common::Exception) { if(ip == "*") sa.sin_addr.s_addr = INADDR_ANY; else if(!inet_pton(AF_INET, ip.c_str(), &sa.sin_addr)) - throw Common::Exception(Common::Exception::INVALID_ADDRESS); + throw Exception(Exception::INVALID_ADDRESS); addr = ntohl(sa.sin_addr.s_addr); } -IPAddress::IPAddress(const std::string &address, uint16_t port0) throw(Common::Exception) : port(port0) { +IPAddress::IPAddress(const std::string &address, uint16_t port0) throw(Exception) : port(port0) { sa.sin_family = AF_INET; sa.sin_port = htons(port); if(!inet_pton(AF_INET, address.c_str(), &sa.sin_addr)) - throw Common::Exception(Common::Exception::INVALID_ADDRESS); + throw Exception(Exception::INVALID_ADDRESS); addr = ntohl(sa.sin_addr.s_addr); } diff --git a/src/Net/IPAddress.h b/src/Net/IPAddress.h index d67ec3e..3541891 100644 --- a/src/Net/IPAddress.h +++ b/src/Net/IPAddress.h @@ -20,7 +20,7 @@ #ifndef MAD_NET_IPADDRESS_H_ #define MAD_NET_IPADDRESS_H_ -#include +#include "Exception.h" #include #include @@ -39,8 +39,8 @@ class IPAddress { // TODO Default port IPAddress(uint16_t port0 = 6666); IPAddress(uint32_t address, uint16_t port0); - IPAddress(const std::string &address) throw(Common::Exception); - IPAddress(const std::string &address, uint16_t port0) throw(Common::Exception); + IPAddress(const std::string &address) throw(Exception); + IPAddress(const std::string &address, uint16_t port0) throw(Exception); IPAddress(const struct sockaddr_in &address); uint32_t getAddress() const {return addr;} diff --git a/src/Net/Listener.cpp b/src/Net/Listener.cpp index c4c5194..95147fa 100644 --- a/src/Net/Listener.cpp +++ b/src/Net/Listener.cpp @@ -41,7 +41,7 @@ void Listener::acceptHandler(int) { } } -Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0) throw(Common::Exception) +Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0) throw(Exception) : x905CertFile(x905CertFile0), x905KeyFile(x905KeyFile0), address(address0) { gnutls_dh_params_init(&dh_params); gnutls_dh_params_generate2(dh_params, 768); @@ -49,7 +49,7 @@ Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyF sock = socket(PF_INET, SOCK_STREAM, 0); if(sock < 0) - throw Common::Exception("socket()", Common::Exception::INTERNAL_ERRNO, errno); + throw Exception("socket()", Exception::INTERNAL_ERRNO, errno); // Set non-blocking flag int flags = fcntl(sock, F_GETFL, 0); @@ -57,7 +57,7 @@ Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyF if(flags < 0) { close(sock); - throw Common::Exception("fcntl()", Common::Exception::INTERNAL_ERRNO, errno); + throw Exception("fcntl()", Exception::INTERNAL_ERRNO, errno); } fcntl(sock, F_SETFL, flags | O_NONBLOCK); @@ -69,13 +69,13 @@ Listener::Listener(const std::string &x905CertFile0, const std::string &x905KeyF if(bind(sock, address.getSockAddr(), address.getSockAddrLength()) < 0) { close(sock); - throw Common::Exception("bind()", Common::Exception::INTERNAL_ERRNO, errno); + throw Exception("bind()", Exception::INTERNAL_ERRNO, errno); } if(listen(sock, 64) < 0) { close(sock); - throw Common::Exception("listen()", Common::Exception::INTERNAL_ERRNO, errno); + throw Exception("listen()", Exception::INTERNAL_ERRNO, errno); } FdManager::get()->registerFd(sock, sigc::mem_fun(this, &Listener::acceptHandler), POLLIN); diff --git a/src/Net/Listener.h b/src/Net/Listener.h index a095439..ca19947 100644 --- a/src/Net/Listener.h +++ b/src/Net/Listener.h @@ -21,7 +21,6 @@ #define MAD_NET_LISTENER_H_ #include "IPAddress.h" -#include #include #include @@ -51,7 +50,7 @@ class Listener { Listener& operator=(const Listener &o); public: - Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0 = IPAddress()) throw(Common::Exception); + Listener(const std::string &x905CertFile0, const std::string &x905KeyFile0, const IPAddress &address0 = IPAddress()) throw(Exception); virtual ~Listener(); ServerConnection* getConnection(); diff --git a/src/Net/Makefile.am b/src/Net/Makefile.am index e8265fa..65fc504 100644 --- a/src/Net/Makefile.am +++ b/src/Net/Makefile.am @@ -1,4 +1,6 @@ noinst_LTLIBRARIES = libnet.la -libnet_la_SOURCES = ClientConnection.cpp ServerConnection.cpp Connection.cpp FdManager.cpp IPAddress.cpp Listener.cpp Packet.cpp +libnet_la_SOURCES = ClientConnection.cpp Exception.cpp ServerConnection.cpp Connection.cpp FdManager.cpp IPAddress.cpp \ + Listener.cpp Packet.cpp ThreadManager.cpp -noinst_HEADERS = ClientConnection.h ServerConnection.h Connection.h FdManager.h IPAddress.h Listener.h Packet.h +noinst_HEADERS = ClientConnection.h Exception.h ServerConnection.h Connection.h FdManager.h IPAddress.h Listener.h \ + Packet.h ThreadManager.h diff --git a/src/Net/Makefile.in b/src/Net/Makefile.in index 0d65c6d..5d421fb 100644 --- a/src/Net/Makefile.in +++ b/src/Net/Makefile.in @@ -60,8 +60,9 @@ CONFIG_HEADER = $(top_builddir)/config.h CONFIG_CLEAN_FILES = LTLIBRARIES = $(noinst_LTLIBRARIES) libnet_la_LIBADD = -am_libnet_la_OBJECTS = ClientConnection.lo ServerConnection.lo \ - Connection.lo FdManager.lo IPAddress.lo Listener.lo Packet.lo +am_libnet_la_OBJECTS = ClientConnection.lo Exception.lo \ + ServerConnection.lo Connection.lo FdManager.lo IPAddress.lo \ + Listener.lo Packet.lo ThreadManager.lo libnet_la_OBJECTS = $(am_libnet_la_OBJECTS) DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/config/depcomp @@ -265,8 +266,12 @@ top_build_prefix = @top_build_prefix@ top_builddir = @top_builddir@ top_srcdir = @top_srcdir@ noinst_LTLIBRARIES = libnet.la -libnet_la_SOURCES = ClientConnection.cpp ServerConnection.cpp Connection.cpp FdManager.cpp IPAddress.cpp Listener.cpp Packet.cpp -noinst_HEADERS = ClientConnection.h ServerConnection.h Connection.h FdManager.h IPAddress.h Listener.h Packet.h +libnet_la_SOURCES = ClientConnection.cpp Exception.cpp ServerConnection.cpp Connection.cpp FdManager.cpp IPAddress.cpp \ + Listener.cpp Packet.cpp ThreadManager.cpp + +noinst_HEADERS = ClientConnection.h Exception.h ServerConnection.h Connection.h FdManager.h IPAddress.h Listener.h \ + Packet.h ThreadManager.h + all: all-am .SUFFIXES: @@ -320,11 +325,13 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ClientConnection.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Connection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Exception.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/FdManager.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/IPAddress.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Listener.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Packet.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ServerConnection.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ThreadManager.Plo@am__quote@ .cpp.o: @am__fastdepCXX_TRUE@ $(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< diff --git a/src/Net/ServerConnection.h b/src/Net/ServerConnection.h index 9a67c13..0870143 100644 --- a/src/Net/ServerConnection.h +++ b/src/Net/ServerConnection.h @@ -21,7 +21,6 @@ #define MAD_NET_SERVERCONNECTION_H_ #include "Connection.h" -#include #include namespace Mad { diff --git a/src/Net/ThreadManager.cpp b/src/Net/ThreadManager.cpp new file mode 100644 index 0000000..9eb965d --- /dev/null +++ b/src/Net/ThreadManager.cpp @@ -0,0 +1,215 @@ +/* + * 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" +#include "FdManager.h" + +#include +#include +#include + +#include + +namespace Mad { +namespace Net { + +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(); + } + + // And let the new worker thread join us... + pushWork(sigc::bind(sigc::mem_fun(this, &ThreadManager::threadFinished), (gl_thread_t)gl_thread_self())); +} + +void ThreadManager::detach() { + if(!isThisMainThread()) { + Common::Logger::log(Common::Logger::CRITICAL, "Tried to detach main thread! This is just WRONG!"); + return; + } + + gl_lock_lock(runLock); + bool isRunning = running; + gl_lock_unlock(runLock); + if(!isRunning) // There's no point in creating a new worker thread when we aren't running anymore + return; + + gl_lock_lock(threadLock); + + if(workerThread == (gl_thread_t)gl_thread_self()) {// Already detached? + threads.insert(workerThread); + workerThread = gl_thread_create(&ThreadManager::workerStart, 0); + } + + gl_lock_unlock(threadLock); +} + +void ThreadManager::pushWork(const sigc::slot &newWork) { + gl_lock_lock(workLock); + + work.push(newWork); + + gl_cond_signal(workCond); + gl_lock_unlock(workLock); +} + +void ThreadManager::pushIO(const sigc::slot &newIO) { + gl_lock_lock(ioLock); + + ioQueue.push(newIO); + + if(!hasIO) { + hasIO = true; + ignore_value(write(ioNotifyPipe[1], "", 1)); + } + + gl_lock_unlock(ioLock); +} + +void ThreadManager::runIO() { + gl_lock_lock(ioLock); + + // Empty the pipe + char buf; + ignore_value(read(ioNotifyPipe[0], &buf, 1)); + hasIO = false; + + while(!ioQueue.empty()) { + sigc::slot handler = ioQueue.front(); + ioQueue.pop(); + gl_lock_unlock(ioLock); + + handler(); + + gl_lock_lock(ioLock); + } + + gl_lock_unlock(ioLock); +} + + +void ThreadManager::doInit() { + gl_lock_init(threadLock); + gl_lock_init(runLock); + + gl_lock_init(workLock); + gl_cond_init(workCond); + + gl_lock_init(ioLock); + hasIO = false; + + // TODO Error handling + pipe(ioNotifyPipe); + + fcntl(ioNotifyPipe[0], F_SETFL, fcntl(ioNotifyPipe[0], F_GETFL) | O_NONBLOCK); + fcntl(ioNotifyPipe[1], F_SETFL, fcntl(ioNotifyPipe[1], F_GETFL) | O_NONBLOCK); + + Net::FdManager::get()->registerFd(ioNotifyPipe[0], sigc::hide(sigc::mem_fun(this, &ThreadManager::runIO)), POLLIN); + + running = true; + + gl_lock_lock(threadLock); + + mainThread = (gl_thread_t)gl_thread_self(); + workerThread = gl_thread_create(&ThreadManager::workerStart, 0); + loggerThread = gl_thread_create(&ThreadManager::loggerStart, 0); + + gl_lock_unlock(threadLock); +} + +void ThreadManager::doDeinit() { + if(!isThisMainThread()) { + // TODO Critical error!!! + return; + } + + // First set running = false so the worker threads quit + gl_lock_lock(runLock); + gl_lock_lock(workLock); + + running = false; + gl_cond_signal(workCond); + + gl_lock_unlock(workLock); + gl_lock_unlock(runLock); + + // We don't have to lock threadLock as detach() won't change workerThread when running is false + gl_thread_join(workerThread, 0); + + // Now wait for all detached threads + gl_lock_lock(threadLock); + while(!threads.empty()) { + gl_thread_t thread = *threads.begin(); + gl_lock_unlock(threadLock); + + gl_thread_join(thread, 0); + + gl_lock_lock(threadLock); + threads.erase(thread); + } + gl_lock_unlock(threadLock); + + // Finally, the logger thread has to die + Common::LogManager::get()->stopLoggerThread(); + gl_thread_join(loggerThread, 0); + + // And then we clean everything up + Net::FdManager::get()->unregisterFd(ioNotifyPipe[0]); + + close(ioNotifyPipe[0]); + close(ioNotifyPipe[1]); + + gl_lock_destroy(ioLock); + + gl_cond_destroy(workCond); + gl_lock_destroy(workLock); + + gl_lock_destroy(runLock); + gl_lock_destroy(threadLock); +} + +} +} diff --git a/src/Net/ThreadManager.h b/src/Net/ThreadManager.h new file mode 100644 index 0000000..9e2b3d3 --- /dev/null +++ b/src/Net/ThreadManager.h @@ -0,0 +1,113 @@ +/* + * 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 +#include + +#include +#include +#include + +#include "glthread/thread.h" +#include "glthread/lock.h" +#include "glthread/cond.h" + +namespace Mad { +namespace Net { + +class ThreadManager : public Common::Initializable { + private: + gl_thread_t mainThread, workerThread, loggerThread; + std::set threads; + + gl_lock_t threadLock; + + gl_lock_t runLock; + bool running; + + gl_lock_t workLock; + gl_cond_t workCond; + std::queue > work; + + gl_lock_t ioLock; + bool hasIO; + int ioNotifyPipe[2]; + std::queue > ioQueue; + + static ThreadManager threadManager; + + ThreadManager() {} + + static void* workerStart(void*) { + threadManager.workerFunc(); + return 0; + } + + static void* loggerStart(void*) { + Common::LogManager::get()->loggerThread(); + return 0; + } + + void workerFunc(); + + void threadFinished(gl_thread_t thread) { + gl_lock_lock(threadLock); + threads.erase(thread); + gl_lock_unlock(threadLock); + + gl_thread_join(thread, 0); + } + + protected: + virtual void doInit(); + virtual void doDeinit(); + + public: + bool isThisMainThread() { + return (mainThread == (gl_thread_t)gl_thread_self()); + } + + bool isThisWorkerThread() { + gl_lock_lock(threadLock); + bool ret = (workerThread == (gl_thread_t)gl_thread_self()); + gl_lock_unlock(threadLock); + return ret; + } + + void detach(); + + void pushWork(const sigc::slot &newWork); + void pushIO(const sigc::slot &newIO); + + void runIO(); + + static ThreadManager* get() { + return &threadManager; + } +}; + +} +} + +#endif /* MAD_COMMON_THREADMANAGER_H_ */ diff --git a/src/Server/ConnectionManager.cpp b/src/Server/ConnectionManager.cpp index 279304c..9235700 100644 --- a/src/Server/ConnectionManager.cpp +++ b/src/Server/ConnectionManager.cpp @@ -46,8 +46,8 @@ namespace Server { ConnectionManager ConnectionManager::connectionManager; -bool ConnectionManager::Connection::send(const Net::Packet &packet) { - return connection->send(packet); +void ConnectionManager::Connection::send(const Net::Packet &packet) { + connection->send(packet); } ConnectionManager::Connection::Connection(Net::ServerConnection *connection0, ConnectionType type0) @@ -100,7 +100,7 @@ bool ConnectionManager::handleConfigEntry(const Common::ConfigEntry &entry, bool try { listenerAddresses.push_back(Net::IPAddress(entry[0][0])); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { // TODO Log error } @@ -149,7 +149,7 @@ void ConnectionManager::configFinished() { try { listeners.push_back(new Net::Listener(x509CertFile, x509KeyFile)); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { // TODO Log error } } @@ -158,7 +158,7 @@ void ConnectionManager::configFinished() { try { listeners.push_back(new Net::Listener(x509CertFile, x509KeyFile, *address)); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { // TODO Log error } } @@ -233,14 +233,14 @@ void ConnectionManager::run() { } } -Common::Connection* ConnectionManager::getDaemonConnection(const std::string &name) const throw (Common::Exception&) { +Common::Connection* ConnectionManager::getDaemonConnection(const std::string &name) const throw (Net::Exception&) { const Common::HostInfo *hostInfo; try { hostInfo = &daemonInfo.at(name); } catch(std::out_of_range&) { - throw Common::Exception(Common::Exception::UNKNOWN_DAEMON); + throw Net::Exception(Net::Exception::UNKNOWN_DAEMON); } if(hostInfo->getState() != Common::HostInfo::INACTIVE) { @@ -251,10 +251,10 @@ Common::Connection* ConnectionManager::getDaemonConnection(const std::string &na } } - throw(Common::Exception::NOT_AVAILABLE); + throw(Net::Exception::NOT_AVAILABLE); } -std::string ConnectionManager::getDaemonName(const Common::Connection *con) const throw (Common::Exception&) { +std::string ConnectionManager::getDaemonName(const Common::Connection *con) const throw (Net::Exception&) { const Connection *connection = dynamic_cast(con); if(connection) { @@ -263,22 +263,22 @@ std::string ConnectionManager::getDaemonName(const Common::Connection *con) cons } } - throw Common::Exception(Common::Exception::UNKNOWN_DAEMON); + throw Net::Exception(Net::Exception::UNKNOWN_DAEMON); } -void ConnectionManager::identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Common::Exception&) { +void ConnectionManager::identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Net::Exception&) { // TODO Logging Connection *connection = dynamic_cast(con); if(!connection || (connection->getConnectionType() != Connection::DAEMON)) - throw Common::Exception(Common::Exception::INVALID_ACTION); + throw Net::Exception(Net::Exception::INVALID_ACTION); if(connection->isIdentified()) - throw Common::Exception(Common::Exception::ALREADY_IDENTIFIED); + throw Net::Exception(Net::Exception::ALREADY_IDENTIFIED); if(daemonInfo.count(name) == 0) - throw Common::Exception(Common::Exception::UNKNOWN_DAEMON); + throw Net::Exception(Net::Exception::UNKNOWN_DAEMON); Common::HostInfo *hostInfo = &daemonInfo[name]; @@ -287,7 +287,7 @@ void ConnectionManager::identifyDaemonConnection(Common::Connection *con, const getDaemonConnection(name)->disconnect(); Common::Logger::log(Common::Logger::WARNING, "Disconnecting old connection."); } - catch(Common::Exception&) {} + catch(Net::Exception&) {} } connection->identify(hostInfo); diff --git a/src/Server/ConnectionManager.h b/src/Server/ConnectionManager.h index 5072897..62ecc37 100644 --- a/src/Server/ConnectionManager.h +++ b/src/Server/ConnectionManager.h @@ -25,7 +25,6 @@ #include #include -#include #include #include #include @@ -56,7 +55,7 @@ class ConnectionManager : public Common::Configurable, public Common::Initializa Common::HostInfo *hostInfo; protected: - virtual bool send(const Net::Packet &packet); + virtual void send(const Net::Packet &packet); public: Connection(Net::ServerConnection *connection0, ConnectionType type0); @@ -118,10 +117,10 @@ class ConnectionManager : public Common::Configurable, public Common::Initializa void run(); - Common::Connection* getDaemonConnection(const std::string &name) const throw (Common::Exception&); - std::string getDaemonName(const Common::Connection *con) const throw (Common::Exception&); + Common::Connection* getDaemonConnection(const std::string &name) const throw (Net::Exception&); + std::string getDaemonName(const Common::Connection *con) const throw (Net::Exception&); - void identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Common::Exception&); + void identifyDaemonConnection(Common::Connection *con, const std::string &name) throw (Net::Exception&); std::vector getDaemonList() const; }; diff --git a/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp b/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp index 7c1efb9..314aa97 100644 --- a/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonCommandRequestHandler.cpp @@ -33,7 +33,7 @@ void DaemonCommandRequestHandler::handlePacket(const Common::XmlPacket &packet) Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -50,7 +50,7 @@ void DaemonCommandRequestHandler::handlePacket(const Common::XmlPacket &packet) Common::RequestManager::get()->sendRequest(daemonCon, sigc::mem_fun(this, &DaemonCommandRequestHandler::requestFinished), command == "reboot"); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::XmlPacket ret; ret.setType("Error"); ret.add("ErrorCode", e.getErrorCode()); @@ -66,7 +66,7 @@ void DaemonCommandRequestHandler::requestFinished(const Common::Request &request try { sendPacket(request.getResult()); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::XmlPacket ret; ret.setType("Error"); ret.add("ErrorCode", e.getErrorCode()); diff --git a/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp b/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp index 9ccca40..eadc0d5 100644 --- a/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonFSInfoRequestHandler.cpp @@ -33,7 +33,7 @@ void DaemonFSInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -48,7 +48,7 @@ void DaemonFSInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::RequestManager::get()->sendRequest(daemonCon, sigc::mem_fun(this, &DaemonFSInfoRequestHandler::requestFinished)); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::XmlPacket ret; ret.setType("Error"); ret.add("ErrorCode", e.getErrorCode()); @@ -64,7 +64,7 @@ void DaemonFSInfoRequestHandler::requestFinished(const Common::Request &request) try { sendPacket(request.getResult()); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::XmlPacket ret; ret.setType("Error"); ret.add("ErrorCode", e.getErrorCode()); diff --git a/src/Server/RequestHandlers/DaemonListRequestHandler.cpp b/src/Server/RequestHandlers/DaemonListRequestHandler.cpp index c4b4143..2b21a29 100644 --- a/src/Server/RequestHandlers/DaemonListRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonListRequestHandler.cpp @@ -31,7 +31,7 @@ void DaemonListRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); diff --git a/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp b/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp index 07e0c4c..9e21127 100644 --- a/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp +++ b/src/Server/RequestHandlers/DaemonStatusRequestHandler.cpp @@ -33,7 +33,7 @@ void DaemonStatusRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -50,7 +50,7 @@ void DaemonStatusRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::RequestManager::get()->sendRequest(daemonCon, sigc::mem_fun(this, &DaemonStatusRequestHandler::requestFinished)); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::XmlPacket ret; ret.setType("Error"); ret.add("ErrorCode", e.getErrorCode()); @@ -66,7 +66,7 @@ void DaemonStatusRequestHandler::requestFinished(const Common::Request &request) try { sendPacket(request.getResult()); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::XmlPacket ret; ret.setType("Error"); ret.add("ErrorCode", e.getErrorCode()); diff --git a/src/Server/RequestHandlers/GSSAPIAuthRequestHandler.cpp b/src/Server/RequestHandlers/GSSAPIAuthRequestHandler.cpp index c665843..5272d7a 100644 --- a/src/Server/RequestHandlers/GSSAPIAuthRequestHandler.cpp +++ b/src/Server/RequestHandlers/GSSAPIAuthRequestHandler.cpp @@ -18,9 +18,8 @@ */ #include "GSSAPIAuthRequestHandler.h" -#include #include -#include +#include #include @@ -36,7 +35,7 @@ void GSSAPIAuthRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -73,10 +72,7 @@ void GSSAPIAuthRequestHandler::handlePacket(const Common::XmlPacket &packet) { ret.setType("AuthGSSAPI"); ret.addBinary("authToken", sendBuffer.value, sendBuffer.length); - if(!sendPacket(ret)) { - gss_release_buffer(&minStat, &sendBuffer); - return; - } + sendPacket(ret); gss_release_buffer(&minStat, &sendBuffer); } @@ -102,10 +98,7 @@ void GSSAPIAuthRequestHandler::handlePacket(const Common::XmlPacket &packet) { ret.setType("AuthGSSAPI"); ret.addBinary("certMic", sendBuffer.value, sendBuffer.length); - if(!sendPacket(ret)) { - gss_release_buffer(&minStat, &sendBuffer); - return; - } + sendPacket(ret); gss_release_buffer(&minStat, &sendBuffer); diff --git a/src/Server/RequestHandlers/IdentifyRequestHandler.cpp b/src/Server/RequestHandlers/IdentifyRequestHandler.cpp index 9db9411..ac8bb42 100644 --- a/src/Server/RequestHandlers/IdentifyRequestHandler.cpp +++ b/src/Server/RequestHandlers/IdentifyRequestHandler.cpp @@ -32,7 +32,7 @@ void IdentifyRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -48,7 +48,7 @@ void IdentifyRequestHandler::handlePacket(const Common::XmlPacket &packet) { ret.setType("OK"); sendPacket(ret); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::XmlPacket ret; ret.setType("Error"); ret.add("ErrorCode", e.getErrorCode()); diff --git a/src/Server/RequestHandlers/LogRequestHandler.cpp b/src/Server/RequestHandlers/LogRequestHandler.cpp index ae64921..557a97c 100644 --- a/src/Server/RequestHandlers/LogRequestHandler.cpp +++ b/src/Server/RequestHandlers/LogRequestHandler.cpp @@ -32,7 +32,7 @@ void LogRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -46,7 +46,7 @@ void LogRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::LogManager::get()->log(packet["category"], packet["level"], packet["timestamp"], packet["message"], ConnectionManager::get()->getDaemonName(getConnection())); } - catch(Common::Exception &e) { + catch(Net::Exception &e) { Common::Logger::logf(Common::Logger::ERROR, "Can't determine daemon name: %s", e.strerror().c_str()); } diff --git a/src/Server/RequestHandlers/UserInfoRequestHandler.cpp b/src/Server/RequestHandlers/UserInfoRequestHandler.cpp index 16003a2..39fa63e 100644 --- a/src/Server/RequestHandlers/UserInfoRequestHandler.cpp +++ b/src/Server/RequestHandlers/UserInfoRequestHandler.cpp @@ -19,7 +19,7 @@ #include "UserInfoRequestHandler.h" #include "../UserManager.h" -#include +#include #include namespace Mad { @@ -32,7 +32,7 @@ void UserInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -45,7 +45,7 @@ void UserInfoRequestHandler::handlePacket(const Common::XmlPacket &packet) { if(!UserManager::get()->getUserInfo(packet["uid"], sigc::mem_fun(this, &UserInfoRequestHandler::userInfoHandler))) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::NOT_IMPLEMENTED); + ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); sendPacket(ret); signalFinished().emit(); diff --git a/src/Server/RequestHandlers/UserListRequestHandler.cpp b/src/Server/RequestHandlers/UserListRequestHandler.cpp index 696b1d4..66f67bd 100644 --- a/src/Server/RequestHandlers/UserListRequestHandler.cpp +++ b/src/Server/RequestHandlers/UserListRequestHandler.cpp @@ -19,7 +19,7 @@ #include "UserListRequestHandler.h" #include "../UserManager.h" -#include +#include #include namespace Mad { @@ -32,7 +32,7 @@ void UserListRequestHandler::handlePacket(const Common::XmlPacket &packet) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::UNEXPECTED_PACKET); + ret.add("ErrorCode", Net::Exception::UNEXPECTED_PACKET); sendPacket(ret); @@ -45,7 +45,7 @@ void UserListRequestHandler::handlePacket(const Common::XmlPacket &packet) { if(!UserManager::get()->getUserList(sigc::mem_fun(this, &UserListRequestHandler::userListHandler))) { Common::XmlPacket ret; ret.setType("Error"); - ret.add("ErrorCode", Common::Exception::NOT_IMPLEMENTED); + ret.add("ErrorCode", Net::Exception::NOT_IMPLEMENTED); sendPacket(ret); signalFinished().emit(); diff --git a/src/mad-server.cpp b/src/mad-server.cpp index 863d1ee..59d8949 100644 --- a/src/mad-server.cpp +++ b/src/mad-server.cpp @@ -21,7 +21,7 @@ #include "Common/LogManager.h" #include "Common/Logger.h" #include "Common/ModuleManager.h" -#include "Common/ThreadManager.h" +#include "Net/ThreadManager.h" #include "Server/ConnectionManager.h" #include @@ -36,7 +36,7 @@ int main() { sigaddset(&signals, SIGPIPE); sigprocmask(SIG_BLOCK, &signals, 0); - Common::ThreadManager::get()->init(); + Net::ThreadManager::get()->init(); Server::ConnectionManager::get()->init(); Common::ModuleManager::get()->loadModule("FileLogger"); diff --git a/src/mad.cpp b/src/mad.cpp index c3d3a82..bc150e2 100644 --- a/src/mad.cpp +++ b/src/mad.cpp @@ -20,12 +20,12 @@ #include "Net/Connection.h" #include "Net/FdManager.h" #include "Net/IPAddress.h" +#include "Net/ThreadManager.h" #include "Common/ConfigManager.h" #include "Common/LogManager.h" #include "Common/Logger.h" #include "Common/ModuleManager.h" #include "Common/RequestManager.h" -#include "Common/ThreadManager.h" #include "Common/ClientConnection.h" #include "Common/RequestHandlers/FSInfoRequestHandler.h" #include "Common/RequestHandlers/StatusRequestHandler.h" @@ -45,7 +45,7 @@ static void requestFinished(const Common::Request&) { int main() { Net::Connection::init(); - Common::ThreadManager::get()->init(); + Net::ThreadManager::get()->init(); Common::ModuleManager::get()->loadModule("FileLogger"); Common::ModuleManager::get()->loadModule("SystemBackendPosix"); @@ -83,7 +83,7 @@ int main() { Common::RequestManager::get()->unregisterConnection(connection); } - catch(Mad::Common::Exception &e) { + catch(Net::Exception &e) { Common::Logger::logf(Common::Logger::CRITICAL, "Connection error: %s", e.strerror().c_str()); } diff --git a/src/madc.cpp b/src/madc.cpp index b0922a0..46455b0 100644 --- a/src/madc.cpp +++ b/src/madc.cpp @@ -20,12 +20,12 @@ #include "Net/Connection.h" #include "Net/FdManager.h" #include "Net/IPAddress.h" +#include "Net/ThreadManager.h" #include "Common/ClientConnection.h" #include "Common/ConfigManager.h" #include "Common/LogManager.h" #include "Common/Logger.h" #include "Common/RequestManager.h" -#include "Common/ThreadManager.h" #include "Client/CommandParser.h" #include "Client/InformationManager.h" @@ -81,7 +81,7 @@ int main(int argc, char *argv[]) { Net::Connection::init(); - Common::ThreadManager::get()->init(); + Net::ThreadManager::get()->init(); Client::InformationManager::get()->init(); Common::ConfigManager::get()->finish(); @@ -123,7 +123,7 @@ int main(int argc, char *argv[]) { Common::RequestManager::get()->unregisterConnection(connection); } - catch(Mad::Common::Exception &e) { + catch(Net::Exception &e) { Common::Logger::logf(Common::Logger::CRITICAL, "Connection error: %s", e.strerror().c_str()); } -- cgit v1.2.3