Make it multithreaded

This commit is contained in:
apio 2022-11-03 21:55:40 +01:00
parent 08355a63ec
commit f6b4341d39
2 changed files with 43 additions and 27 deletions

View File

@ -4,6 +4,7 @@
#include <memory> #include <memory>
#include <netinet/in.h> #include <netinet/in.h>
#include <string> #include <string>
#include <thread>
namespace webcxx { namespace webcxx {
class Response; class Response;
@ -34,6 +35,8 @@ private:
int m_socket_fd; int m_socket_fd;
static std::shared_ptr<App> s_instance; static std::shared_ptr<App> s_instance;
void connection_thread();
std::string static_resource_path = "/static"; std::string static_resource_path = "/static";
int m_current_connection_fd; int m_current_connection_fd;
@ -42,8 +45,9 @@ private:
int handle_request(Request& req); int handle_request(Request& req);
void get_client_addr(); std::string get_client_addr();
std::string m_client_ip;
std::vector<std::shared_ptr<std::thread>> m_threads;
struct Action { struct Action {
std::function<Response(Request &)> get_action; std::function<Response(Request &)> get_action;
@ -57,6 +61,7 @@ private:
std::map<int, std::function<Response(void)>> m_error_action_map; std::map<int, std::function<Response(void)>> m_error_action_map;
static void app_terminate(int); // Terminate the current app. static void app_terminate(int); // Terminate the current app.
static void app_connection_thread();
friend class ErrorWatcher; friend class ErrorWatcher;
}; };

View File

@ -146,10 +146,10 @@ int webcxx::App::socket_init(int port) {
void webcxx::App::terminate() { m_is_running = false; } void webcxx::App::terminate() { m_is_running = false; }
void webcxx::App::get_client_addr() { std::string webcxx::App::get_client_addr() {
char result[INET_ADDRSTRLEN]; char result[INET_ADDRSTRLEN];
inet_ntop(AF_INET, &m_addr.sin_addr.s_addr, result, sizeof(result)); inet_ntop(AF_INET, &m_addr.sin_addr.s_addr, result, sizeof(result));
m_client_ip = result; return std::string(result);
} }
void webcxx::App::on(int methods, std::string path, void webcxx::App::on(int methods, std::string path,
@ -195,6 +195,35 @@ void webcxx::App::set_static_resource_path(const std::string& path)
static_resource_path = path; static_resource_path = path;
} }
void webcxx::App::connection_thread()
{
auto addrlen = sizeof(sockaddr);
int fd = accept(m_socket_fd, (struct sockaddr *)&m_addr, (socklen_t *)&addrlen);
if (fd < 0) {
perror("accept");
close(fd);
return;
}
std::string ip = get_client_addr();
Request req(fd);
req.m_ip = ip;
int status;
if((status = handle_request(req)))
{
return;
}
close(fd);
}
void webcxx::App::app_connection_thread()
{
if(!current_app()) return;
current_app()->connection_thread();
}
int webcxx::App::main_loop() { int webcxx::App::main_loop() {
m_is_running = true; m_is_running = true;
struct pollfd poll_info; struct pollfd poll_info;
@ -222,35 +251,17 @@ int webcxx::App::main_loop() {
continue; continue;
} }
if (poll_info.revents & POLL_IN) { if (poll_info.revents & POLL_IN) {
auto addrlen = sizeof(sockaddr); m_threads.push_back(std::make_shared<std::thread>(app_connection_thread));
m_current_connection_fd = accept(
m_socket_fd, (struct sockaddr *)&m_addr, (socklen_t *)&addrlen);
if (m_current_connection_fd < 0) {
perror("accept");
close(m_socket_fd);
return 1;
}
get_client_addr();
is_ready = true;
} }
} }
if (!m_is_running) { if (!m_is_running) {
close(m_current_connection_fd);
break; break;
} }
Request req(m_current_connection_fd);
req.m_ip = m_client_ip;
int status;
if((status = handle_request(req)))
{
return status;
} }
for(auto& thread : m_threads)
close(m_current_connection_fd); {
thread->join();
} }
close(m_socket_fd); close(m_socket_fd);
return 0; return 0;