M src/bridge/bridge.cpp => src/bridge/bridge.cpp +2 -3
@@ 14,7 14,7 @@ using namespace std::string_literals;
static const char* action_prefix = "\01ACTION ";
-Bridge::Bridge(const std::string& user_jid, XmppComponent* xmpp, Poller* poller):
+Bridge::Bridge(const std::string& user_jid, XmppComponent* xmpp, std::shared_ptr<Poller> poller):
user_jid(user_jid),
xmpp(xmpp),
poller(poller)
@@ 81,9 81,8 @@ IrcClient* Bridge::get_irc_client(const std::string& hostname, const std::string
}
catch (const std::out_of_range& exception)
{
- this->irc_clients.emplace(hostname, std::make_shared<IrcClient>(hostname, username, this));
+ this->irc_clients.emplace(hostname, std::make_shared<IrcClient>(this->poller, hostname, username, this));
std::shared_ptr<IrcClient> irc = this->irc_clients.at(hostname);
- this->poller->add_socket_handler(irc);
return irc.get();
}
}
M src/bridge/bridge.hpp => src/bridge/bridge.hpp +2 -3
@@ 22,7 22,7 @@ class Poller;
class Bridge
{
public:
- explicit Bridge(const std::string& user_jid, XmppComponent* xmpp, Poller* poller);
+ explicit Bridge(const std::string& user_jid, XmppComponent* xmpp, std::shared_ptr<Poller> poller);
~Bridge();
/**
* QUIT all connected IRC servers.
@@ 146,9 146,8 @@ private:
/**
* Poller, to give it the IrcClients that we spawn, to make it manage
* their sockets.
- * We don't own it.
*/
- Poller* poller;
+ std::shared_ptr<Poller> poller;
Bridge(const Bridge&) = delete;
Bridge(Bridge&& other) = delete;
M src/irc/irc_client.cpp => src/irc/irc_client.cpp +2 -1
@@ 13,7 13,8 @@
#include <string>
using namespace std::string_literals;
-IrcClient::IrcClient(const std::string& hostname, const std::string& username, Bridge* bridge):
+IrcClient::IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname, const std::string& username, Bridge* bridge):
+ SocketHandler(poller),
hostname(hostname),
username(username),
current_nick(username),
M src/irc/irc_client.hpp => src/irc/irc_client.hpp +2 -1
@@ 8,6 8,7 @@
#include <network/socket_handler.hpp>
#include <unordered_map>
+#include <memory>
#include <vector>
#include <string>
#include <map>
@@ 23,7 24,7 @@ class Bridge;
class IrcClient: public SocketHandler
{
public:
- explicit IrcClient(const std::string& hostname, const std::string& username, Bridge* bridge);
+ explicit IrcClient(std::shared_ptr<Poller> poller, const std::string& hostname, const std::string& username, Bridge* bridge);
~IrcClient();
/**
* Connect to the IRC server
M src/main.cpp => src/main.cpp +6 -7
@@ 61,11 61,11 @@ int main(int ac, char** av)
return config_help("password");
if (hostname.empty())
return config_help("hostname");
- std::shared_ptr<XmppComponent> xmpp_component =
- std::make_shared<XmppComponent>(hostname, password);
- Poller p;
- p.add_socket_handler(xmpp_component);
+ auto p = std::make_shared<Poller>();
+ auto xmpp_component = std::make_shared<XmppComponent>(p,
+ hostname,
+ password);
// Install the signals used to exit the process cleanly, or reload the
// config
@@ 91,7 91,7 @@ int main(int ac, char** av)
xmpp_component->start();
const std::chrono::milliseconds timeout(-1);
- while (p.poll(timeout) != -1)
+ while (p->poll(timeout) != -1)
{
// Check for empty irc_clients (not connected, or with no joined
// channel) and remove them
@@ 123,14 123,13 @@ int main(int ac, char** av)
!xmpp_component->is_connecting())
{
xmpp_component->reset();
- p.add_socket_handler(xmpp_component);
xmpp_component->start();
}
// If the only existing connection is the one to the XMPP component:
// close the XMPP stream.
if (exiting && xmpp_component->is_connecting())
xmpp_component->close();
- if (exiting && p.size() == 1 && xmpp_component->is_document_open())
+ if (exiting && p->size() == 1 && xmpp_component->is_document_open())
xmpp_component->close_document();
}
log_info("All connection cleanely closed, have a nice day.");
M src/network/poller.cpp => src/network/poller.cpp +4 -5
@@ 27,15 27,14 @@ Poller::~Poller()
{
}
-void Poller::add_socket_handler(std::shared_ptr<SocketHandler> socket_handler)
+void Poller::add_socket_handler(SocketHandler* socket_handler)
{
- // Raise an error if that socket is already in the list
+ // Don't do anything if the socket is already managed
const auto it = this->socket_handlers.find(socket_handler->get_socket());
if (it != this->socket_handlers.end())
- throw std::runtime_error("Trying to insert SocketHandler already managed");
+ return ;
this->socket_handlers.emplace(socket_handler->get_socket(), socket_handler);
- socket_handler->set_poller(this);
// We always watch all sockets for receive events
#if POLLER == POLL
@@ 44,7 43,7 @@ void Poller::add_socket_handler(std::shared_ptr<SocketHandler> socket_handler)
this->nfds++;
#endif
#if POLLER == EPOLL
- struct epoll_event event = {EPOLLIN, {socket_handler.get()}};
+ struct epoll_event event = {EPOLLIN, {socket_handler}};
const int res = ::epoll_ctl(this->epfd, EPOLL_CTL_ADD, socket_handler->get_socket(), &event);
if (res == -1)
{
M src/network/poller.hpp => src/network/poller.hpp +2 -2
@@ 42,7 42,7 @@ public:
* Add a SocketHandler to be monitored by this Poller. All receive events
* are always automatically watched.
*/
- void add_socket_handler(std::shared_ptr<SocketHandler> socket_handler);
+ void add_socket_handler(SocketHandler* socket_handler);
/**
* Remove (and stop managing) a SocketHandler, designed by the given socket_t.
*/
@@ 77,7 77,7 @@ private:
* because that's what is returned by select/poll/etc when an event
* occures.
*/
- std::unordered_map<socket_t, std::shared_ptr<SocketHandler>> socket_handlers;
+ std::unordered_map<socket_t, SocketHandler*> socket_handlers;
#if POLLER == POLL
struct pollfd fds[MAX_POLL_FD_NUMBER];
M src/network/socket_handler.cpp => src/network/socket_handler.cpp +3 -9
@@ 23,8 23,8 @@ using namespace std::string_literals;
# define UIO_FASTIOV 8
#endif
-SocketHandler::SocketHandler():
- poller(nullptr),
+SocketHandler::SocketHandler(std::shared_ptr<Poller> poller):
+ poller(poller),
connected(false),
connecting(false)
{
@@ 107,6 107,7 @@ void SocketHandler::connect(const std::string& address, const std::string& port)
|| errno == EISCONN)
{
log_info("Connection success.");
+ this->poller->add_socket_handler(this);
this->connected = true;
this->connecting = false;
this->on_connected();
@@ 134,11 135,6 @@ void SocketHandler::connect()
this->connect(this->address, this->port);
}
-void SocketHandler::set_poller(Poller* poller)
-{
- this->poller = poller;
-}
-
void SocketHandler::on_recv()
{
static constexpr size_t buf_size = 4096;
@@ 231,8 227,6 @@ void SocketHandler::close()
this->port.clear();
this->poller->remove_socket_handler(this->get_socket());
::close(this->socket);
- // recreate the socket for a potential future usage
- this->init_socket();
}
socket_t SocketHandler::get_socket() const
M src/network/socket_handler.hpp => src/network/socket_handler.hpp +3 -6
@@ 6,6 6,7 @@
#include <netdb.h>
#include <utility>
+#include <memory>
#include <string>
#include <list>
@@ 22,7 23,7 @@ class Poller;
class SocketHandler
{
public:
- explicit SocketHandler();
+ explicit SocketHandler(std::shared_ptr<Poller> poller);
virtual ~SocketHandler() {}
/**
* (re-)Initialize the socket
@@ 34,10 35,6 @@ public:
void connect(const std::string& address, const std::string& port);
void connect();
/**
- * Set the pointer to the given Poller, to communicate with it.
- */
- void set_poller(Poller* poller);
- /**
* Reads data in our in_buf and the call parse_in_buf, for the implementor
* to handle the data received so far.
*/
@@ 119,7 116,7 @@ protected:
* And a raw pointer because we are not owning it, it is owning us
* (actually it is sharing our ownership with a Bridge).
*/
- Poller* poller;
+ std::shared_ptr<Poller> poller;
/**
* Hostname we are connected/connecting to
*/
M src/xmpp/xmpp_component.cpp => src/xmpp/xmpp_component.cpp +2 -1
@@ 47,7 47,8 @@ static std::set<std::string> kickable_errors{
"malformed-error"
};
-XmppComponent::XmppComponent(const std::string& hostname, const std::string& secret):
+XmppComponent::XmppComponent(std::shared_ptr<Poller> poller, const std::string& hostname, const std::string& secret):
+ SocketHandler(poller),
ever_auth(false),
last_auth(false),
served_hostname(hostname),
M src/xmpp/xmpp_component.hpp => src/xmpp/xmpp_component.hpp +1 -1
@@ 18,7 18,7 @@
class XmppComponent: public SocketHandler
{
public:
- explicit XmppComponent(const std::string& hostname, const std::string& secret);
+ explicit XmppComponent(std::shared_ptr<Poller> poller, const std::string& hostname, const std::string& secret);
~XmppComponent();
void on_connection_failed(const std::string& reason) override final;