From d8bb6a2047ec77c1285da6d9b6429639b2a7fa98 Mon Sep 17 00:00:00 2001 From: 3lswear Date: Sun, 27 Feb 2022 18:14:34 +0300 Subject: [PATCH] feat: add epoll_handle and cleanup --- src/Server/Server.cpp | 142 ++++++++++++++++++------------------------ src/Server/Server.hpp | 12 ++-- 2 files changed, 67 insertions(+), 87 deletions(-) diff --git a/src/Server/Server.cpp b/src/Server/Server.cpp index 7ae4f32..cec8983 100644 --- a/src/Server/Server.cpp +++ b/src/Server/Server.cpp @@ -1,6 +1,5 @@ #include "Server.hpp" #include -#include #define THREAD_NUM 100 #define MAX_EVENTS @@ -49,28 +48,27 @@ void Server::sendData(Client &client, int fd) else send_len = BUFFSIZE; - /* DBOUT << YELLO << tmp << ENDL; */ - /* DBOUT << GREEN << client.getCounter() << ENDL; */ - DBOUT << WARNING << getDebugTime() << OKCYAN << " sent " << send_len << " to client " << fd << ENDL; sent = send(fd, tmp + client.getCounter(), send_len, MSG_NOSIGNAL); - if (sent < 0) + DBOUT << getDebugTime() + << " sent " + << send_len << + "/" << sent << + " to client " << fd << ENDL; + if (sent <= 0) { - DBOUT << WARNING << getDebugTime() << FAIL << " SEND FAILED !@!!!" << ENDL; + DBOUT << getDebugTime() << FAIL << " SEND FAILED" << ENDL; client.done = true; } else if (sent > 0) client.increaseCounter(); - } void Server::readSocket(Client &client, int fd) { - int status; int bytes_read; std::string stringBUF(BUFFSIZE, 0); DBOUT << TURQ << "IN readSocket" << ENDL; - // DBOUT << "client in readSocket "<< &client << ENDL; bytes_read = recv(fd, &stringBUF[0], BUFFSIZE, 0); if (bytes_read == 0) { @@ -80,7 +78,6 @@ void Server::readSocket(Client &client, int fd) else if (bytes_read == -1) { DBOUT << WARNING << getDebugTime() << FAIL << " bytes_read -1" << ENDL; - // client.allRead = true; client.done = true; } else @@ -88,18 +85,10 @@ void Server::readSocket(Client &client, int fd) stringBUF.erase(bytes_read, stringBUF.size()); client.setRawData(stringBUF); client.increaseRecvCounter(bytes_read); - status = client.parseRequest(); - // client.printClientInfo(); + client.parseRequest(); if (client.allRecved()) client.allRead = true; - - // DBOUT << GREEN << "recvCounter " << client.getRecvCounter() << ENDL; - // DBOUT << GREEN << "contentLength " << client.getRequest().getContentLength() << ENDL; - // DBOUT << GREEN << "allRead " << client.allRead << ENDL; - - // DBOUT << BLUE << "status is " << Response::getReasonPhrase(status) << ENDL; } - (void)status; } inline int Server::delete_client_force(std::map &client_map, int fd) @@ -109,14 +98,12 @@ inline int Server::delete_client_force(std::map &client_map, int << fd << ENDL; - int ret; - ret = epoll_ctl(_epoll_fd, EPOLL_CTL_DEL, fd, NULL); - assert(ret == 0); + epoll_handle(EPOLL_CTL_DEL, fd, 0); close(fd); client_map[fd]->clear(); delete (client_map[fd]); client_map.erase(fd); - return (ret); + return (0); } @@ -124,56 +111,45 @@ inline int Server::delete_client(std::map &client_map, int fd) { if (client_map[fd]->getRequest().getConnection() == "close") { - DBOUT << WARNING << getDebugTime() << OKCYAN + DBOUT << WARNING << getDebugTime() << " completely deleting client " << fd << ENDL; - int ret; - ret = epoll_ctl(_epoll_fd, EPOLL_CTL_DEL, fd, NULL); + epoll_handle(EPOLL_CTL_DEL, fd, 0); close(fd); client_map[fd]->clear(); delete (client_map[fd]); client_map.erase(fd); - return (ret); } else { - DBOUT << WARNING << getDebugTime() << OKCYAN + DBOUT << WARNING << getDebugTime() << " deleting only client " << fd << ENDL; - int ret; - struct epoll_event ev; - t_tmp_fd *tmp_fd; + t_fd_info *tmp_fd; - ev.events = EPOLLIN; - ev.data.fd = fd; - ret = epoll_ctl(_epoll_fd, EPOLL_CTL_MOD, fd, &ev); + epoll_handle(EPOLL_CTL_MOD, fd, EPOLLIN); - //Добавляю фд в список - tmp_fd = new t_tmp_fd; + tmp_fd = new t_fd_info; tmp_fd->ip_port = client_map[fd]->getIpPort(); gettimeofday(&tmp_fd->last_modif, NULL); vacant_fds[fd] = tmp_fd; - //Очищаю клиента client_map[fd]->clear(); - // delete (client_map[fd]); client_map[fd]->~Client(); - // client_map.erase(fd); - return (ret); } + return (0); } -inline int Server::delete_fd(std::map &map, - std::map::iterator &it, +inline int Server::delete_fd(std::map &map, + std::map::iterator &it, std::map &client_map) { - int ret; - ret = epoll_ctl(_epoll_fd, EPOLL_CTL_DEL, it->first, NULL); - DBOUT << WARNING << getDebugTime() << OKCYAN + epoll_handle(EPOLL_CTL_DEL, it->first, 0); + DBOUT << WARNING << getDebugTime() << " deleting fd " << it->first << ENDL; @@ -182,7 +158,7 @@ inline int Server::delete_fd(std::map &map, client_map.erase(it->first); map.erase(it++); - return (ret); + return (0); } @@ -236,13 +212,23 @@ void Server::setup_server_socks(std::map &configurations_map) throw std::domain_error("No servers were set up. Exiting."); } +inline void Server::epoll_handle(int op, int fd, int event) +{ + struct epoll_event ev; + ev.data.fd = fd; + ev.events = event; + + if (epoll_ctl(_epoll_fd, op, fd, &ev)) + { + std::cerr << getDebugTime() << FAIL; + perror("epoll_ctl"); + std::cerr << RESET; + } +} + inline void Server::add_to_epoll_list(int fd, unsigned int ep_events) { - struct epoll_event ev; - ev.events = ep_events; - ev.data.fd = fd; - - assert(epoll_ctl(_epoll_fd, EPOLL_CTL_ADD, fd, &ev) == 0); + epoll_handle(EPOLL_CTL_ADD, fd, ep_events); setNonBlock(fd); DBOUT << GREEN << "add socket " @@ -277,7 +263,7 @@ void Server::run(void) std::map client_map; std::map configurations_map; - std::map::iterator fd_it; + std::map::iterator fd_it; unsigned int client_events = EPOLLIN; @@ -290,12 +276,14 @@ void Server::run(void) while (1) { - int ready_num = epoll_wait(_epoll_fd, _events, MAX_CLIENT, 5000); - DBOUT << TURQ << "ready_num " << ready_num << ENDL; if (ready_num < 0) - throw std::logic_error("epoll_ret"); + { + std::cerr << getDebugTime() << FAIL; + perror("epoll_wait"); + std::cerr << RESET; + } for (int i = 0; i < ready_num; i++) { @@ -304,7 +292,7 @@ void Server::run(void) std::map::iterator sock_it; DBOUT << "FD is " << fd << ENDL; - /* print_epoll_events(events); */ + print_epoll_events(events); if ((events & EPOLLIN) && (sock_it = configurations_map.find(fd)) != configurations_map.end()) @@ -317,45 +305,38 @@ void Server::run(void) add_to_epoll_list(client_sock, client_events); } else - throw std::logic_error("accept didnt work"); + { + std::cerr << getDebugTime() << WARNING; + perror("Accept"); + std::cerr << RESET; + } } else { - fd_it = vacant_fds.find(fd); - if (fd_it != vacant_fds.end()) - { - // client_map[fd] = new Client(fd_it->second->ip_port); - // DBOUT << "addr of client_map[fd] " << client_map[fd] << ENDL; - new (client_map[fd]) Client(fd_it->second->ip_port); - delete fd_it->second; - vacant_fds.erase(fd); - } - else if (events & EPOLLIN) + if (events & EPOLLIN) { + fd_it = vacant_fds.find(fd); + if (fd_it != vacant_fds.end()) + { + DBOUT << "creating new client for vacant fd" << ENDL; + new (client_map[fd]) Client(fd_it->second->ip_port); + delete fd_it->second; + vacant_fds.erase(fd); + } readSocket(*client_map[fd], fd); DBOUT << "left redsocket " << ENDL; if (client_map[fd]->done) - { - delete_client(client_map, fd); - std::map::iterator it = vacant_fds.find(fd); - delete_fd(vacant_fds, it, client_map); - } + delete_client_force(client_map, fd); else if (client_map[fd]->readyToSend()) { client_map[fd]->generateRespons(_configs); - struct epoll_event ev; - - ev.events = EPOLLOUT; - ev.data.fd = fd; - assert( epoll_ctl(_epoll_fd, EPOLL_CTL_MOD, fd, &ev) == 0); + epoll_handle(EPOLL_CTL_MOD, fd, EPOLLOUT); DBOUT << WARNING << getDebugTime() << OKCYAN << " rearmed to EPOLLOUT" << ENDL; } } else if (events & EPOLLOUT) { - DBOUT << GREEN << "doing sendData" << ENDL; - // client_map[fd]->printClientInfo(); sendData(*client_map[fd], fd); if (client_map[fd]->allSended()) { @@ -365,10 +346,8 @@ void Server::run(void) } } fd_it = vacant_fds.begin(); - DBOUT << "entering cleaning fd loop" << ENDL; while (fd_it != vacant_fds.end()) { - DBOUT << "loop iteration" <second->last_modif, LIFE_TIME)) { free(client_map[fd_it->first]); @@ -378,7 +357,6 @@ void Server::run(void) ++fd_it; } } - DBOUT << RED << "end;" << ENDL; } //----------------------------------------------Other------------------------------------------------------------------------------------------------ diff --git a/src/Server/Server.hpp b/src/Server/Server.hpp index 15e14f5..130078a 100644 --- a/src/Server/Server.hpp +++ b/src/Server/Server.hpp @@ -19,6 +19,7 @@ class Server std::string _ip; std::vector _configs; void add_to_epoll_list(int fd, unsigned int ep_events); + void epoll_handle(int op, int fd, int event); static void print_epoll_events(unsigned int events); @@ -31,6 +32,7 @@ class Server void sendData(Client &client, int fd); void readSocket(Client &client, int fd); int delete_client(std::map &map, int fd); + int delete_client_force(std::map &map, int fd); enum e_req_status @@ -48,17 +50,17 @@ class Server size_t left; enum e_req_status req_status; } t_client_status; - typedef struct s_tmp_fd + typedef struct s_fd_info { serverListen ip_port; struct timeval last_modif; - }t_tmp_fd; + } t_fd_info; bool TimeToDie(struct timeval &last_modif, int lifeTime); -int delete_fd(std::map &map, - std::map::iterator &it, +int delete_fd(std::map &map, + std::map::iterator &it, std::map &client_map); - std::map vacant_fds; + std::map vacant_fds; public: Server();