-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.cpp
94 lines (78 loc) · 3.36 KB
/
main.cpp
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 <iostream>
#include <sys/socket.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/epoll.h>
#include <csignal>
#include "concurrent_hashmap.h"
#include "connection.h"
#include "helper.h"
#include "request.h"
#include "handler.h"
#include "epoll_helper.h"
#include "thread_poll.h"
const unsigned int MAX_EVENTS = 128;
const unsigned int FD_SIZE = 1024;
using std::bind;
concurrent_hashmap<int, shared_ptr<connection>> connection_storage;
int main() {
signal(SIGPIPE, SIG_IGN);
thread_poll poll(8);
sockaddr_in server_addr{};
server_addr.sin_port = htons(8788);
server_addr.sin_family = AF_INET;
server_addr.sin_addr.s_addr = htonl(INADDR_ANY);
int epoll_fd = epoll_create(FD_SIZE);
struct epoll_event events[MAX_EVENTS];
int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
epoll_helper::create_event(epoll_fd, listen_fd, EPOLLIN);
bind(listen_fd, reinterpret_cast<sockaddr *>(&server_addr), sizeof(server_addr));
listen(listen_fd, 5);
helper::set_non_block(listen_fd);
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wmissing-noreturn"
while (true) {
const int active = epoll_wait(epoll_fd, events, MAX_EVENTS, -1);
for (int i = 0; i < active; i++) {
const int fd = events[i].data.fd, ev = events[i].events;
if (fd == listen_fd && (ev & (EPOLLIN | EPOLLERR))) {
sockaddr_in client_addr{};
socklen_t client_addr_len = sizeof(client_addr);
int conn_fd = accept(listen_fd, reinterpret_cast<sockaddr *>(&client_addr), &client_addr_len);
if (conn_fd != -1) {
printf("[%d] Connection Established\n", conn_fd);
helper::set_non_block(conn_fd);
handler::print_client_info(reinterpret_cast<sockaddr *>(&client_addr), client_addr_len);
epoll_helper::create_event(epoll_fd, conn_fd, EPOLLIN | EPOLLOUT | EPOLLET);
if (connection_storage.count(conn_fd)) {
connection_storage.erase(conn_fd);
}
connection_storage.set(conn_fd, shared_ptr<connection>(new connection()));
}
} else if (ev & EPOLLIN) {
int conn_fd = events[i].data.fd;
printf("[%d] trigger epoll_in event \n", conn_fd);
if (!connection_storage.count(conn_fd)) {
printf("[%d] conn_fd invalid \n", conn_fd);
continue;
}
poll.push(bind(handler::read, epoll_fd, conn_fd, connection_storage.get(conn_fd)));
} else if (ev & EPOLLOUT) {
int conn_fd = events[i].data.fd;
printf("[%d] trigger epoll_out event \n", conn_fd);
if (!connection_storage.count(conn_fd)) {
printf("[%d] conn_fd invalid \n", conn_fd);
continue;
}
poll.push(bind(handler::write, epoll_fd, conn_fd, connection_storage.get(conn_fd)));
} else if (ev & EPOLLERR) {
int conn_fd = events[i].data.fd;
printf("[%d] trigger epoll_err event \n", conn_fd);
connection_storage.erase(conn_fd);
printf("[%d] disposed \n", conn_fd);
}
}
}
#pragma clang diagnostic pop
return 0;
}