Make it multithreaded
This commit is contained in:
parent
08355a63ec
commit
f6b4341d39
@ -4,6 +4,7 @@
|
||||
#include <memory>
|
||||
#include <netinet/in.h>
|
||||
#include <string>
|
||||
#include <thread>
|
||||
|
||||
namespace webcxx {
|
||||
class Response;
|
||||
@ -34,6 +35,8 @@ private:
|
||||
int m_socket_fd;
|
||||
static std::shared_ptr<App> s_instance;
|
||||
|
||||
void connection_thread();
|
||||
|
||||
std::string static_resource_path = "/static";
|
||||
|
||||
int m_current_connection_fd;
|
||||
@ -42,8 +45,9 @@ private:
|
||||
|
||||
int handle_request(Request& req);
|
||||
|
||||
void get_client_addr();
|
||||
std::string m_client_ip;
|
||||
std::string get_client_addr();
|
||||
|
||||
std::vector<std::shared_ptr<std::thread>> m_threads;
|
||||
|
||||
struct Action {
|
||||
std::function<Response(Request &)> get_action;
|
||||
@ -57,6 +61,7 @@ private:
|
||||
std::map<int, std::function<Response(void)>> m_error_action_map;
|
||||
|
||||
static void app_terminate(int); // Terminate the current app.
|
||||
static void app_connection_thread();
|
||||
|
||||
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::get_client_addr() {
|
||||
std::string webcxx::App::get_client_addr() {
|
||||
char result[INET_ADDRSTRLEN];
|
||||
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,
|
||||
@ -195,6 +195,35 @@ void webcxx::App::set_static_resource_path(const std::string& 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() {
|
||||
m_is_running = true;
|
||||
struct pollfd poll_info;
|
||||
@ -222,35 +251,17 @@ int webcxx::App::main_loop() {
|
||||
continue;
|
||||
}
|
||||
if (poll_info.revents & POLL_IN) {
|
||||
auto addrlen = sizeof(sockaddr);
|
||||
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;
|
||||
m_threads.push_back(std::make_shared<std::thread>(app_connection_thread));
|
||||
}
|
||||
}
|
||||
|
||||
if (!m_is_running) {
|
||||
close(m_current_connection_fd);
|
||||
break;
|
||||
}
|
||||
|
||||
Request req(m_current_connection_fd);
|
||||
req.m_ip = m_client_ip;
|
||||
|
||||
int status;
|
||||
|
||||
if((status = handle_request(req)))
|
||||
{
|
||||
return status;
|
||||
}
|
||||
|
||||
close(m_current_connection_fd);
|
||||
for(auto& thread : m_threads)
|
||||
{
|
||||
thread->join();
|
||||
}
|
||||
close(m_socket_fd);
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user