From e9a7062c07f0dedfa74c46d8043333ba3a628dc6 Mon Sep 17 00:00:00 2001 From: Pablu23 Date: Thu, 11 Jul 2024 18:00:03 +0200 Subject: [PATCH] Added multithreading --- router.cpp | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- router.hpp | 14 ++++++++++++++ 2 files changed, 64 insertions(+), 1 deletion(-) diff --git a/router.cpp b/router.cpp index b1c34fb..b54c3ef 100644 --- a/router.cpp +++ b/router.cpp @@ -1,5 +1,6 @@ #include "router.hpp" #include +#include #include Router::Router(int port) { @@ -14,13 +15,61 @@ int Router::Start() { if (err != 0) return err; + StartThreadLoop(); + err = listen(m_socket, 5); if (err != 0) return err; - std::vector buffer(1024); while (true) { int client = accept(m_socket, nullptr, nullptr); + QueueClient(client); + } + + StopThreadLoop(); +} + +void Router::QueueClient(int fd) { + { + std::unique_lock lock(m_mutex); + m_clients.push(fd); + } + m_cond.notify_one(); +} + +void Router::StartThreadLoop() { + const uint32_t numThreads = std::thread::hardware_concurrency(); + for (auto i = 0; i < numThreads; ++i) { + m_threads.emplace_back(std::thread(&Router::ThreadLoop, this)); + } +} + +void Router::StopThreadLoop() { + { + std::unique_lock lock(m_mutex); + m_shouldTerminate = true; + } + m_cond.notify_all(); + for (std::thread &active_thread : m_threads) { + active_thread.join(); + } + m_threads.clear(); +} + +void Router::ThreadLoop() { + std::vector buffer(1024); + while (true) { + int client; + { + std::unique_lock lock(m_mutex); + m_cond.wait(lock, + [this] { return !m_clients.empty() || m_shouldTerminate; }); + if (m_shouldTerminate) + return; + client = m_clients.front(); + m_clients.pop(); + } + int read = recv(client, buffer.data(), buffer.size(), 0); Request req(buffer); Response res = Route(req); diff --git a/router.hpp b/router.hpp index 06a3da2..0dc5d64 100644 --- a/router.hpp +++ b/router.hpp @@ -3,9 +3,12 @@ #include "request.hpp" #include "response.hpp" +#include #include #include +#include #include +#include #include class Router { @@ -15,6 +18,17 @@ private: sockaddr_in m_address; Response Route(Request req); +private: + std::mutex m_mutex; + std::condition_variable m_cond; + std::vector m_threads; + std::queue m_clients; + bool m_shouldTerminate = false; + void StartThreadLoop(); + void ThreadLoop(); + void QueueClient(int client); + void StopThreadLoop(); + public: Router(int port); void Handle(std::string pathPattern,