Make it multithreaded
This commit is contained in:
parent
08355a63ec
commit
f6b4341d39
@ -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;
|
||||||
};
|
};
|
||||||
|
59
src/App.cpp
59
src/App.cpp
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user