summaryrefslogtreecommitdiff
path: root/src/sessionManager.cpp
diff options
context:
space:
mode:
authorlittleblack111 <littleblack11111@gmail.com>2025-06-12 21:41:41 +0800
committerlittleblack111 <littleblack11111@gmail.com>2025-06-13 20:22:51 +0800
commit6f7b994684032060f0a2d7af82f4f3572293b8d6 (patch)
tree793d328cbcd6761365267550b55db45aee9b21fc /src/sessionManager.cpp
parent6a51ab4525c59e9fe2bdbd92493019b0a98c6b94 (diff)
internal!: organized internal structure, using cmake now
Diffstat (limited to 'src/sessionManager.cpp')
-rw-r--r--src/sessionManager.cpp141
1 files changed, 0 insertions, 141 deletions
diff --git a/src/sessionManager.cpp b/src/sessionManager.cpp
deleted file mode 100644
index 7ed1a8e..0000000
--- a/src/sessionManager.cpp
+++ /dev/null
@@ -1,141 +0,0 @@
-#include "sessionManager.hpp"
-#include "IOManager.hpp"
-#include "chatServer.hpp"
-#include "format.hpp"
-#include "log.hpp"
-#include "session.hpp"
-#include <algorithm>
-#include <ranges>
-#include <unistd.h>
-#include <utility>
-
-void CSessionManager::shutdownSessions() {
- if (m_vSessions.empty())
- return;
-
- for (auto &[thread, session] : m_vSessions) {
- if (session) {
- session->setDeaf(false);
- session->write("Server shutting down");
- if (!session->getName().empty())
- g_pSessionManager->broadcast(NFormatter::fmt(NONEWLINE, "{} has left the chat", session->getName()), std::weak_ptr<CSession>(session));
- }
- }
-
- for (auto &[thread, session] : m_vSessions) {
- if (thread.joinable())
- thread.detach();
- session.reset();
- }
-
- m_vSessions.clear();
-}
-
-CSessionManager::CSessionManager() {
- if (std::atexit([]() {
- if (g_pSessionManager)
- g_pSessionManager->shutdownSessions();
- }))
- log(ERR, "Failed to register SessionManager atexit handler, will fallback to quick_exit after hang");
-
- log(LOG, "SessionManager: initialized");
-};
-
-CSessionManager::~CSessionManager() {
- for (auto &[thread, session] : m_vSessions) {
- if (thread.joinable())
- thread.detach();
- kick(std::weak_ptr<CSession>(session));
- }
-
- log(SYS, "SessionManager: bye");
-}
-
-void CSessionManager::newSession() {
- std::shared_ptr session = std::make_shared<CSession>();
- auto &instance = m_vSessions.emplace_back(std::jthread([session]() { session->run(); }), session);
- instance.second->self = std::weak_ptr<CSession>(instance.second);
-}
-
-void CSessionManager::run() {
- while (true)
- newSession();
-}
-
-void CSessionManager::broadcast(const std::string &msg, std::optional<std::weak_ptr<CSession>> self) const {
- for (const auto &[thread, session] : m_vSessions)
- if (!self || (self && session != self->lock()))
- session->write(msg);
-
- g_pIOManager->addCustom({"", msg});
-}
-
-void CSessionManager::broadcast(const CChatManager::SMessage &msg) const {
- for (const auto &[thread, session] : m_vSessions) {
- if (!session)
- continue;
-
- session->writeChat(msg);
- }
-
- 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; });
-
- if (it != m_vSessions.end()) {
- if (!it->second->isValid()) {
- kick(std::weak_ptr<CSession>(it->second), true, "Connection lost");
- return false;
- }
- return true;
- }
- return false;
-}
-
-std::shared_ptr<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; });
- return it != m_vSessions.end() ? it->second : nullptr;
-}
-
-std::shared_ptr<CSession> CSessionManager::getByIp(const std::string &ip) const {
- auto it = std::ranges::find_if(m_vSessions, [&ip](const auto &s) { log(LOG, s.second->getIp()); return s.second->getIp() == ip; });
- return it != m_vSessions.end() ? it->second : nullptr;
-}
-
-std::vector<std::shared_ptr<CSession>> CSessionManager::getSessions() const {
- return m_vSessions | std::views::transform([](const auto &s) { return s.second; }) | std::ranges::to<std::vector>();
-}
-
-void CSessionManager::kick(std::weak_ptr<CSession> session_weak, const bool kill, const std::string &reason) {
- auto session = session_weak.lock();
- if (!session)
- return;
-
- for (auto it = m_vSessions.begin(); it != m_vSessions.end(); ++it) {
- if (it->second == session) {
- if (session)
- // this only exist when the session is registered
- // not sure why the second is null, but m_name definately is since it's setted during register
- // 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->getName()), session_weak);
-
- if (!reason.empty()) {
- session->setDeaf(false);
- session->write(reason);
- }
- const auto native_handle = it->first.native_handle();
- if (it->first.joinable())
- it->first.detach(); // .detach the thread since it's removing itself
- it->second.reset();
- m_vSessions.erase(it);
- 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
- // need a condition because it might crash if the thread is already dead
- pthread_cancel(native_handle);
- return;
- }
- }
-}