summaryrefslogtreecommitdiff
path: root/src/sessionManager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/sessionManager.cpp')
-rw-r--r--src/sessionManager.cpp58
1 files changed, 48 insertions, 10 deletions
diff --git a/src/sessionManager.cpp b/src/sessionManager.cpp
index aae56f1..03ad9b0 100644
--- a/src/sessionManager.cpp
+++ b/src/sessionManager.cpp
@@ -5,16 +5,21 @@
#include "log.hpp"
#include "session.hpp"
#include <algorithm>
+#include <mutex>
#include <ranges>
#include <unistd.h>
#include <utility>
void CSessionManager::shutdownSessions() {
+ std::unique_lock<std::mutex> lock(m_mutex);
if (m_vSessions.empty())
return;
- for (auto &session : m_vSessions)
+ for (auto &session : m_vSessions) {
+ lock.unlock();
kick(&session, false, "Server shutting down");
+ lock.lock();
+ }
}
CSessionManager::CSessionManager() {
@@ -28,6 +33,8 @@ CSessionManager::CSessionManager() {
};
CSessionManager::~CSessionManager() {
+ std::lock_guard<std::mutex> lock(m_mutex);
+
for (auto &[thread, session] : m_vSessions) {
if (thread.joinable())
thread.detach();
@@ -38,8 +45,10 @@ CSessionManager::~CSessionManager() {
}
std::pair<std::jthread, std::shared_ptr<CSession>> *CSessionManager::newSession() {
- std::shared_ptr session = std::make_shared<CSession>();
- const auto instance = &m_vSessions.emplace_back(std::jthread(&CSession::run, session.get()), session);
+ std::shared_ptr<CSession> session = std::make_shared<CSession>();
+ std::unique_lock<std::mutex> lock(m_mutex);
+ const auto instance = &m_vSessions.emplace_back(std::jthread(&CSession::run, session.get()), session);
+ lock.unlock();
instance->second->setSelf(instance);
return instance;
}
@@ -50,26 +59,35 @@ void CSessionManager::run() {
}
void CSessionManager::broadcast(const std::string &msg, std::optional<const CSession *const> self) const {
- for (const auto &[thread, session] : m_vSessions)
+ std::unique_lock<std::mutex> lock(m_mutex);
+ for (const auto &[thread, session] : m_vSessions) {
+ lock.unlock();
if (!self || (self && session.get() != *self))
session->write(msg);
+ lock.lock();
+ }
g_pIOManager->addCustom({"", msg});
}
void CSessionManager::broadcast(const CChatManager::SMessage &msg) const {
+ std::unique_lock<std::mutex> lock(m_mutex);
for (const auto &[thread, session] : m_vSessions) {
+ lock.unlock();
if (!session)
continue;
session->writeChat(msg);
+ lock.lock();
}
g_pIOManager->addMessage(msg);
}
bool CSessionManager::nameExists(const std::string &name) {
- auto it = std::ranges::find_if(m_vSessions, [&name](const auto &s) { return s.second->getName() == name; });
+ std::unique_lock<std::mutex> lock(m_mutex);
+ auto it = std::ranges::find_if(m_vSessions, [&name](const auto &s) { return s.second->getName() == name; });
+ lock.unlock();
if (it != m_vSessions.end()) {
if (!it->second->isValid()) {
@@ -82,32 +100,47 @@ bool CSessionManager::nameExists(const std::string &name) {
}
CSession *CSessionManager::getByName(const std::string &name) const {
- auto it = std::ranges::find_if(m_vSessions, [&name](const auto &s) { return s.second->getName() == name; });
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ const auto it = std::ranges::find_if(m_vSessions, [&name](const auto &s) { return s.second->getName() == name; });
return it != m_vSessions.end() ? it->second.get() : nullptr;
}
CSession *CSessionManager::getByIp(const std::string &ip) const {
- auto it = std::ranges::find_if(m_vSessions, [&ip](const auto &s) { log(LOG, s.second->m_ip); return s.second->m_ip == ip; });
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ const auto it = std::ranges::find_if(m_vSessions, [&ip](const auto &s) { log(LOG, s.second->m_ip); return s.second->m_ip == ip; });
return it != m_vSessions.end() ? it->second.get() : nullptr;
}
CSession *CSessionManager::getByPtr(const uintptr_t &p) const {
- auto it = std::ranges::find_if(m_vSessions, [&p](const auto &s) { return (uintptr_t)s.second.get() == p; });
+ std::lock_guard<std::mutex> lock(m_mutex);
+
+ const auto it = std::ranges::find_if(m_vSessions, [&p](const auto &s) { return (uintptr_t)s.second.get() == p; });
return it != m_vSessions.end() ? it->second.get() : nullptr;
}
std::vector<std::shared_ptr<CSession>> CSessionManager::getSessions() const {
+ std::lock_guard<std::mutex> lock(m_mutex);
+
return m_vSessions | std::views::transform([](const auto &s) { return s.second; }) | std::ranges::to<std::vector>();
}
void CSessionManager::kick(CSession *session, const bool kill, const std::string &reason) {
- for (auto &_session : m_vSessions)
+ std::unique_lock<std::mutex> lock(m_mutex);
+
+ for (auto &_session : m_vSessions) {
+ lock.unlock();
if (_session.second.get() == session)
kick(&_session, kill, reason);
+ lock.lock();
+ }
}
void CSessionManager::kick(std::pair<std::jthread, std::shared_ptr<CSession>> *session, const bool kill, const std::string &reason) {
- auto it = std::ranges::find_if(m_vSessions, [session](const auto &s) { return s.second.get() == session->second.get(); });
+ std::unique_lock<std::mutex> lock(m_mutex);
+ auto it = std::ranges::find_if(m_vSessions, [session](const auto &s) { return s.second.get() == session->second.get(); });
+ lock.unlock();
if (session->second)
// this only exist when the session is registered
@@ -115,8 +148,11 @@ void CSessionManager::kick(std::pair<std::jthread, std::shared_ptr<CSession>> *s
// but we don't need to notify people if the session didn't even "join"/register anyways
g_pSessionManager->broadcast(NFormatter::fmt(NONEWLINE, "{} has left the chat", session->second->m_name), session->second.get());
+ lock.lock();
if (it != m_vSessions.end()) {
+ lock.unlock();
if (!reason.empty()) {
+ lock.unlock();
it->second->setDeaf(false);
it->second->write(reason);
}
@@ -124,7 +160,9 @@ void CSessionManager::kick(std::pair<std::jthread, std::shared_ptr<CSession>> *s
if (it->first.joinable())
it->first.detach(); // .detach the thread since it's removing itself
it->second.reset();
+ lock.lock();
m_vSessions.erase(it);
+ lock.unlock();
if (kill && native_handle != 0)
// cancel(terminal/kill) the thread if it doesn't exit on its own
// pthread_cancel cuz it's the safest https://stackoverflow.com/a/3438576