This repository was archived by the owner on Aug 25, 2025. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathServer.cpp
More file actions
94 lines (74 loc) · 2.08 KB
/
Server.cpp
File metadata and controls
94 lines (74 loc) · 2.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
#include "Server.hpp"
#include <cstdint>
#include <stdexcept>
Server::Server(std::string passwd) : _fd(epoll_create1(0)), _password(passwd) {
if(_fd == -1)
throw std::runtime_error("Server::Server: ERROR - Failed to create epoll file");
_events.reserve(_max_events * sizeof(epoll_event));
}
Server::~Server() { close(_fd); }
int Server::getServerFd() const {
return _fd;
}
void Server::addClient(const Client client) {
_clients.try_emplace(client._fd, client);
}
void Server::removeClient(const Client client) {
if(!_clients.empty())
_clients.erase(client._fd);
}
void Server::_reloadHandler(Client &client) const {
uint32_t event = 0;
struct epoll_event ev{};
ev.data.fd = client._fd;
bool firstEvent = true;
for (uint32_t evt: eventTypes) {
if (client.handler(evt)) {
event = evt;
firstEvent = false;
} else {
event |= evt;
}
if (firstEvent)
event = EPOLLET;
else
event |= EPOLLET;
ev.events = event;
if (client.isInitialized) {
epoll_ctl(this->_fd, EPOLL_CTL_MOD, client._fd, &ev);
} else {
epoll_ctl(this->_fd, EPOLL_CTL_ADD, client._fd, &ev);
client.isInitialized = true;
}
}
}
void Server::poll(int tout) {
int nbrEvents = epoll_wait(_fd, &_events[0], _max_events, tout);
(void)nbrEvents;
for (int idx = 0; idx < _max_events; idx++) {
uint32_t events = _events[idx].events;
int fd = _events[idx].data.fd;
for (uint32_t eventType : eventTypes) {
if (_clients.count(fd) == 0)
return ;
if (_clients.at(fd).handler(eventType))
_clients.at(fd).getHandler(eventType)(fd);
}
if (events & (EPOLLRDHUP & EPOLLHUP))
removeClient(_clients.at(fd));
}
}
void Server::registerHandler(const int fd, uint32_t eventType, std::function<void(int)> handler) {
if (_clients.count(fd) == 0)
throw std::runtime_error("Server::registerHandler: Error - no such file descriptor");
Client &cli = _clients.at(fd);
for (uint32_t eventT: eventTypes) {
if (eventT & eventType) {
cli.setHandler(eventType, handler);
}
}
_reloadHandler(cli);
}
void Server::addOwnSocket(int sockfd) {
_clients.try_emplace(sockfd, Client(sockfd));
}