diff options
Diffstat (limited to 'src/server/clients.cpp')
| -rw-r--r-- | src/server/clients.cpp | 37 |
1 files changed, 19 insertions, 18 deletions
diff --git a/src/server/clients.cpp b/src/server/clients.cpp index e1dd161..a274224 100644 --- a/src/server/clients.cpp +++ b/src/server/clients.cpp @@ -2,7 +2,6 @@ #include "libsock/server/client.hpp" #include <algorithm> #include <ranges> -#include <stdexcept> #include <unistd.h> #include <utility> @@ -29,24 +28,25 @@ void Clients::shutdownClients(std::optional<std::function<bool(const std::vector Clients::Clients() { if (std::atexit([]() { - if (pClients) - pClients->shutdownClients(); + for (auto c : vpClients) + if (const auto p = c.lock()) + p->shutdownClients(); })) void(); // failed to register exit handler... } -SP<Clients> Clients::create() { - if (pClients) - throw std::runtime_error("server:clients ClientManager already exist"); - - pClients = SP<Clients>(new Clients()); - return pClients; +SP<Clients> Clients::create(WP<Server> server) { + auto c = SP<Clients>(new Clients()); + vpClients.emplace_back(c); + c->m_self = c; + c->m_wpServer = server; + return c; } -SP<Clients> Clients::get() { - if (!pClients) - pClients = shared_from_this(); - return pClients; +WP<Clients> Clients::get() { + if (m_self.expired()) + m_self = shared_from_this(); + return m_self; } Clients::~Clients() { @@ -55,13 +55,14 @@ Clients::~Clients() { thread.detach(); kick(WP<Client>(client)); } + vpClients.erase(std::remove_if(vpClients.begin(), vpClients.end(), [this](const WP<Clients> &wptr) { return !wptr.owner_before(m_self) && !m_self.owner_before(wptr); }), vpClients.end()); } -WP<Client> Clients::newClient(std::function<void(const WP<Client> &)> loopFunc, SP<Server> server) { - SP client = SP<Client>(new Client(server, shared_from_this())); - auto &instance = m_vClients.emplace_back(std::jthread([&client, &loopFunc]() { loopFunc(client); }), client); - instance.second->self = std::weak_ptr<Client>(instance.second); - return instance.second; +SP<Client> Clients::newClient(std::function<void(const WP<Client> &)> loopFunc) { + SP client = SP<Client>(new Client(m_wpServer.lock(), shared_from_this())); + auto &instance = m_vClients.emplace_back(std::jthread([&client, &loopFunc]() { loopFunc(client); }), client); + instance.second->m_self = std::weak_ptr<Client>(instance.second); + return client; } void Clients::broadcast(const std::string &msg, std::optional<std::weak_ptr<Client>> self) { |
