From c8d469cc3de8ef2fb95f7b47355ebf5318a4c22f Mon Sep 17 00:00:00 2001 From: Matthias Schiffer Date: Fri, 15 May 2009 17:30:40 +0200 Subject: Einfache (ziemlich kaputte) Multithreaded IO --- src/Server/ConnectionManager.cpp | 76 +++++++++++++++++----------------------- src/Server/ConnectionManager.h | 12 ++++--- 2 files changed, 40 insertions(+), 48 deletions(-) (limited to 'src/Server') diff --git a/src/Server/ConnectionManager.cpp b/src/Server/ConnectionManager.cpp index 9235700..99f5680 100644 --- a/src/Server/ConnectionManager.cpp +++ b/src/Server/ConnectionManager.cpp @@ -41,17 +41,19 @@ #include #include +#include + namespace Mad { namespace Server { ConnectionManager ConnectionManager::connectionManager; -void ConnectionManager::Connection::send(const Net::Packet &packet) { - connection->send(packet); +bool ConnectionManager::Connection::send(const Net::Packet &packet) { + return connection->send(packet); } -ConnectionManager::Connection::Connection(Net::ServerConnection *connection0, ConnectionType type0) -: connection(connection0), type(type0), hostInfo(0) { +ConnectionManager::Connection::Connection(Net::ServerConnection *connection0) +: connection(connection0), type(connection0->isDaemonConnection() ? DAEMON : CLIENT), hostInfo(0) { connection->signalReceive().connect(sigc::mem_fun(this, &Connection::receive)); } @@ -86,7 +88,7 @@ void* ConnectionManager::Connection::getPeerCertificate(size_t *size) const { void ConnectionManager::updateState(Common::HostInfo *hostInfo, Common::HostInfo::State state) { hostInfo->setState(state); - for(std::list::iterator con = connections.begin(); con != connections.end(); ++con) { + for(std::set::iterator con = connections.begin(); con != connections.end(); ++con) { if((*con)->getConnectionType() == Connection::CLIENT) Common::RequestManager::get()->sendRequest(*con, Common::Request::slot_type(), hostInfo->getName(), state); } @@ -147,7 +149,9 @@ bool ConnectionManager::handleConfigEntry(const Common::ConfigEntry &entry, bool void ConnectionManager::configFinished() { if(listenerAddresses.empty()) { try { - listeners.push_back(new Net::Listener(x509CertFile, x509KeyFile)); + Net::Listener *listener = new Net::Listener(x509CertFile, x509KeyFile); + listener->signalNewConnection().connect(sigc::mem_fun(this, &ConnectionManager::newConnectionHandler)); + listeners.push_back(listener); } catch(Net::Exception &e) { // TODO Log error @@ -156,7 +160,9 @@ void ConnectionManager::configFinished() { else { for(std::vector::const_iterator address = listenerAddresses.begin(); address != listenerAddresses.end(); ++address) { try { - listeners.push_back(new Net::Listener(x509CertFile, x509KeyFile, *address)); + Net::Listener *listener = new Net::Listener(x509CertFile, x509KeyFile, *address); + listener->signalNewConnection().connect(sigc::mem_fun(this, &ConnectionManager::newConnectionHandler)); + listeners.push_back(listener); } catch(Net::Exception &e) { // TODO Log error @@ -165,11 +171,27 @@ void ConnectionManager::configFinished() { } } +void ConnectionManager::newConnectionHandler(Net::ServerConnection *con) { + Connection *connection = new Connection(con); + con->signalDisconnected().connect(sigc::bind(sigc::mem_fun(this, &ConnectionManager::disconnectHandler), connection)); + connections.insert(connection); + + Common::RequestManager::get()->registerConnection(connection); +} + +void ConnectionManager::disconnectHandler(Connection *con) { + if(con->isIdentified()) + updateState(con->getHostInfo(), Common::HostInfo::INACTIVE); + + connections.erase(con); + + Common::RequestManager::get()->unregisterConnection(con); + delete con; +} + void ConnectionManager::doInit() { Common::RequestManager::get()->setServer(true); - Net::Connection::init(); - Common::RequestManager::get()->registerPacketType("AuthGSSAPI"); Common::RequestManager::get()->registerPacketType("DaemonCommand"); Common::RequestManager::get()->registerPacketType("DaemonFSInfo"); @@ -184,7 +206,7 @@ void ConnectionManager::doInit() { } void ConnectionManager::doDeinit() { - for(std::list::iterator con = connections.begin(); con != connections.end(); ++con) + for(std::set::iterator con = connections.begin(); con != connections.end(); ++con) delete *con; @@ -199,38 +221,6 @@ void ConnectionManager::doDeinit() { Common::RequestManager::get()->unregisterPacketType("GetUserInfo"); Common::RequestManager::get()->unregisterPacketType("ListUsers"); Common::RequestManager::get()->unregisterPacketType("Log"); - - Net::Connection::deinit(); -} - -void ConnectionManager::run() { - // TODO Logging - - Net::FdManager::get()->run(); - - for(std::list::iterator con = connections.begin(); con != connections.end();) { - if(!(*con)->isConnected()) { - if((*con)->isIdentified()) - updateState((*con)->getHostInfo(), Common::HostInfo::INACTIVE); - - Common::RequestManager::get()->unregisterConnection(*con); - delete *con; - connections.erase(con++); - } - else - ++con; - } - - for(std::list::iterator listener = listeners.begin(); listener != listeners.end(); ++listener) { - Net::ServerConnection *con; - - while((con = (*listener)->getConnection()) != 0) { - Connection *connection = new Connection(con, - con->isDaemonConnection() ? Connection::DAEMON : Connection::CLIENT); - connections.push_back(connection); - Common::RequestManager::get()->registerConnection(connection); - } - } } Common::Connection* ConnectionManager::getDaemonConnection(const std::string &name) const throw (Net::Exception&) { @@ -244,7 +234,7 @@ Common::Connection* ConnectionManager::getDaemonConnection(const std::string &na } if(hostInfo->getState() != Common::HostInfo::INACTIVE) { - for(std::list::const_iterator it = connections.begin(); it != connections.end(); ++it) { + for(std::set::const_iterator it = connections.begin(); it != connections.end(); ++it) { if((*it)->getHostInfo() == hostInfo) { return *it; } diff --git a/src/Server/ConnectionManager.h b/src/Server/ConnectionManager.h index 62ecc37..691d51f 100644 --- a/src/Server/ConnectionManager.h +++ b/src/Server/ConnectionManager.h @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -55,10 +56,10 @@ class ConnectionManager : public Common::Configurable, public Common::Initializa Common::HostInfo *hostInfo; protected: - virtual void send(const Net::Packet &packet); + virtual bool send(const Net::Packet &packet); public: - Connection(Net::ServerConnection *connection0, ConnectionType type0); + Connection(Net::ServerConnection *connection0); virtual ~Connection(); bool isConnected() const; @@ -91,7 +92,7 @@ class ConnectionManager : public Common::Configurable, public Common::Initializa std::vector listenerAddresses; std::list listeners; - std::list connections; + std::set connections; std::map daemonInfo; @@ -103,6 +104,9 @@ class ConnectionManager : public Common::Configurable, public Common::Initializa ConnectionManager() {} + void newConnectionHandler(Net::ServerConnection *con); + void disconnectHandler(Connection *con); + protected: virtual bool handleConfigEntry(const Common::ConfigEntry &entry, bool handled); virtual void configFinished(); @@ -115,8 +119,6 @@ class ConnectionManager : public Common::Configurable, public Common::Initializa return &connectionManager; } - void run(); - Common::Connection* getDaemonConnection(const std::string &name) const throw (Net::Exception&); std::string getDaemonName(const Common::Connection *con) const throw (Net::Exception&); -- cgit v1.2.3