From e8e592d1ace5413a1e7d8b59b9467c78d8d68ea9 Mon Sep 17 00:00:00 2001 From: Florent Le Coz Date: Fri, 27 Dec 2013 12:01:26 +0100 Subject: Remove disconnected IrcClients --- src/bridge/bridge.cpp | 13 +++++++++++++ src/bridge/bridge.hpp | 5 ++++- src/irc/irc_client.cpp | 10 ++++++++-- src/main.cpp | 3 +++ src/xmpp/xmpp_component.cpp | 8 ++++++++ src/xmpp/xmpp_component.hpp | 5 +++++ 6 files changed, 41 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/bridge/bridge.cpp b/src/bridge/bridge.cpp index 3a755a3..c93d710 100644 --- a/src/bridge/bridge.cpp +++ b/src/bridge/bridge.cpp @@ -29,6 +29,19 @@ void Bridge::shutdown() } } +void Bridge::clean() +{ + auto it = this->irc_clients.begin(); + while (it != this->irc_clients.end()) + { + IrcClient* client = it->second.get(); + if (!client->is_connected()) + it = this->irc_clients.erase(it); + else + ++it; + } +} + Xmpp::body Bridge::make_xmpp_body(const std::string& str) { std::string res; diff --git a/src/bridge/bridge.hpp b/src/bridge/bridge.hpp index 7a36b59..1e1149b 100644 --- a/src/bridge/bridge.hpp +++ b/src/bridge/bridge.hpp @@ -28,7 +28,10 @@ public: * QUIT all connected IRC servers. */ void shutdown(); - + /** + * Remove all inactive IrcClients + */ + void clean(); static Xmpp::body make_xmpp_body(const std::string& str); /*** ** diff --git a/src/irc/irc_client.cpp b/src/irc/irc_client.cpp index 4e37a63..afdc629 100644 --- a/src/irc/irc_client.cpp +++ b/src/irc/irc_client.cpp @@ -58,8 +58,8 @@ IrcChannel* IrcClient::get_channel(const std::string& name) bool IrcClient::is_channel_joined(const std::string& name) { - IrcChannel* client = this->get_channel(name); - return client->joined; + IrcChannel* channel = this->get_channel(name); + return channel->joined; } std::string IrcClient::get_own_nick() const @@ -339,7 +339,12 @@ void IrcClient::on_part(const IrcMessage& message) bool self = channel->get_self()->nick == nick; this->bridge->send_muc_leave(std::move(iid), std::move(nick), std::move(txt), self); if (self) + { channel->joined = false; + this->channels.erase(chan_name); + // channel pointer is now invalid + channel = nullptr; + } } } @@ -358,6 +363,7 @@ void IrcClient::on_error(const IrcMessage& message) std::string own_nick = channel->get_self()->nick; this->bridge->send_muc_leave(std::move(iid), std::move(own_nick), leave_message, true); } + this->channels.clear(); this->send_gateway_message(std::string("ERROR: ") + leave_message); } diff --git a/src/main.cpp b/src/main.cpp index 6c9560c..28f5a76 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -81,6 +81,9 @@ int main(int ac, char** av) const std::chrono::milliseconds timeout(-1); while (p.poll(timeout) != -1 || !exiting) { + // Check for empty irc_clients (not connected, or with no joined + // channel) and remove them + xmpp_component->clean(); if (stop) { log_info("Signal received, exiting..."); diff --git a/src/xmpp/xmpp_component.cpp b/src/xmpp/xmpp_component.cpp index dc77934..3c37eb1 100644 --- a/src/xmpp/xmpp_component.cpp +++ b/src/xmpp/xmpp_component.cpp @@ -94,6 +94,14 @@ void XmppComponent::shutdown() } } +void XmppComponent::clean() +{ + for (auto it = this->bridges.begin(); it != this->bridges.end(); ++it) + { + it->second->clean(); + } +} + void XmppComponent::on_remote_stream_open(const XmlNode& node) { log_debug("XMPP DOCUMENT OPEN: " << node.to_string()); diff --git a/src/xmpp/xmpp_component.hpp b/src/xmpp/xmpp_component.hpp index 1952e19..d76a2c3 100644 --- a/src/xmpp/xmpp_component.hpp +++ b/src/xmpp/xmpp_component.hpp @@ -31,6 +31,11 @@ public: */ void shutdown(); bool is_document_open() const; + /** + * Run a check on all bridges, to remove all disconnected (socket is + * closed, or no channel is joined) IrcClients. Some kind of garbage collector. + */ + void clean(); /** * Connect to the XMPP server. * Returns false if we failed to connect -- cgit v1.2.3