diff --git a/include/Swiften/Server/Server.cpp b/include/Swiften/Server/Server.cpp index 65a1a193..61e0a494 100644 --- a/include/Swiften/Server/Server.cpp +++ b/include/Swiften/Server/Server.cpp @@ -141,6 +141,7 @@ void Server::handleSessionFinished(boost::shared_ptr se dynamic_cast(stanzaChannel_)->onPresenceReceived(presence); } serverFromClientSessions.erase(std::remove(serverFromClientSessions.begin(), serverFromClientSessions.end(), session), serverFromClientSessions.end()); + std::cout << "FINISH SESSION2 " << serverFromClientSessions.size() << "\n"; session->onSessionStarted.disconnect( boost::bind(&Server::handleSessionStarted, this, session)); session->onSessionFinished.disconnect( diff --git a/include/Swiften/Server/ServerFromClientSession.cpp b/include/Swiften/Server/ServerFromClientSession.cpp index f69b63cf..b1e7d7c9 100644 --- a/include/Swiften/Server/ServerFromClientSession.cpp +++ b/include/Swiften/Server/ServerFromClientSession.cpp @@ -48,6 +48,8 @@ ServerFromClientSession::ServerFromClientSession( ServerFromClientSession::~ServerFromClientSession() { std::cout << "DESTRUCTOR;\n"; + userRegistry_->onPasswordValid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordValid, this, _1)); + userRegistry_->onPasswordInvalid.disconnect(boost::bind(&ServerFromClientSession::handlePasswordInvalid, this, _1)); if (tlsLayer) { delete tlsLayer; } diff --git a/include/Swiften/Server/ServerStanzaChannel.cpp b/include/Swiften/Server/ServerStanzaChannel.cpp index 10a3eceb..bfa33db4 100644 --- a/include/Swiften/Server/ServerStanzaChannel.cpp +++ b/include/Swiften/Server/ServerStanzaChannel.cpp @@ -6,6 +6,7 @@ #include "Swiften/Server/ServerStanzaChannel.h" #include "Swiften/Base/Error.h" +#include #include @@ -55,13 +56,17 @@ void ServerStanzaChannel::sendPresence(boost::shared_ptr presence) { void ServerStanzaChannel::finishSession(const JID& to, boost::shared_ptr element) { std::vector > candidateSessions; for (std::list >::const_iterator i = sessions[to.toBare().toString()].begin(); i != sessions[to.toBare().toString()].end(); ++i) { - (*i)->sendElement(element); + if (element) { + (*i)->sendElement(element); + } candidateSessions.push_back(*i); } for (std::vector >::const_iterator i = candidateSessions.begin(); i != candidateSessions.end(); ++i) { + (*i)->finishSession(); sessions[to.toBare().toString()].remove(*i); + std::cout << "FINISH SESSION " << sessions[to.toBare().toString()].size() << "\n"; } } diff --git a/spectrum/src/main.cpp b/spectrum/src/main.cpp index eb786e10..52c082f5 100644 --- a/spectrum/src/main.cpp +++ b/spectrum/src/main.cpp @@ -7,13 +7,34 @@ #include "transport/networkpluginserver.h" #include "transport/admininterface.h" #include "Swiften/EventLoop/SimpleEventLoop.h" +#include "sys/signal.h" using namespace Transport; +Swift::SimpleEventLoop *eventLoop_ = NULL; + +static void spectrum_sigint_handler(int sig) { + eventLoop_->stop(); +} + +static void spectrum_sigterm_handler(int sig) { + eventLoop_->stop(); +} + int main(int argc, char **argv) { Config config; + if (signal(SIGINT, spectrum_sigint_handler) == SIG_ERR) { + std::cout << "SIGINT handler can't be set\n"; + return -1; + } + + if (signal(SIGTERM, spectrum_sigterm_handler) == SIG_ERR) { + std::cout << "SIGTERM handler can't be set\n"; + return -1; + } + boost::program_options::options_description desc("Usage: spectrum [OPTIONS] \nAllowed options"); desc.add_options() ("help,h", "help") @@ -69,8 +90,9 @@ int main(int argc, char **argv) } UserManager userManager(&transport, &userRegistry, storageBackend); + UserRegistration *userRegistration = NULL; if (storageBackend) { - UserRegistration *userRegistration = new UserRegistration(&transport, &userManager, storageBackend); + userRegistration = new UserRegistration(&transport, &userManager, storageBackend); userRegistration->start(); // logger.setUserRegistration(&userRegistration); } @@ -80,5 +102,12 @@ int main(int argc, char **argv) AdminInterface adminInterface(&transport, &userManager, &plugin, storageBackend); + eventLoop_ = &eventLoop; + eventLoop.run(); + if (userRegistration) { + userRegistration->stop(); + delete userRegistration; + } + delete storageBackend; } diff --git a/src/networkpluginserver.cpp b/src/networkpluginserver.cpp index 72a1e2bb..6d2a9da1 100644 --- a/src/networkpluginserver.cpp +++ b/src/networkpluginserver.cpp @@ -168,6 +168,9 @@ NetworkPluginServer::NetworkPluginServer(Component *component, Config *config, U NetworkPluginServer::~NetworkPluginServer() { m_pingTimer->stop(); + m_server->stop(); + m_server.reset(); + delete m_component->m_factory; delete m_vcardResponder; delete m_rosterResponder; } diff --git a/src/transport.cpp b/src/transport.cpp index 20f82807..2cb8042b 100644 --- a/src/transport.cpp +++ b/src/transport.cpp @@ -134,10 +134,13 @@ Component::~Component() { delete m_capsManager; delete m_capsMemoryStorage; delete m_discoInfoResponder; + delete m_discoItemsResponder; if (m_component) delete m_component; - if (m_server) + if (m_server) { + m_server->stop(); delete m_server; + } delete m_factories; } diff --git a/src/user.cpp b/src/user.cpp index 622a750e..e3157724 100644 --- a/src/user.cpp +++ b/src/user.cpp @@ -62,6 +62,10 @@ User::User(const Swift::JID &jid, UserInfo &userInfo, Component *component, User User::~User(){ LOG4CXX_INFO(logger, m_jid.toString() << ": Destroying"); + if (m_component->inServerMode()) { + dynamic_cast(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr()); + } + m_reconnectTimer->stop(); delete m_rosterManager; delete m_conversationManager; @@ -194,7 +198,7 @@ void User::handleDisconnected(const std::string &error) { // Remove user later just to be sure there won't be double-free. // We can't be sure finishSession sends unavailable presence everytime, so check if user gets removed // in finishSession(...) call and if not, remove it here. - std::string jid = m_jid.toBare().toString(); + std::string jid = m_jid.toBare().toString(); dynamic_cast(m_component->getStanzaChannel())->finishSession(m_jid, boost::shared_ptr(new Swift::StreamError())); if (m_userManager->getUser(jid) != NULL) { m_userManager->removeUser(this);