comparison seobeo/os/s_linux_edge.c @ 36:84672efec192

[Zenbu] WIP fixing issues regarding to using edge only. I think there is a problem where socket closes before sending back the info.
author MrJuneJune <me@mrjunejune.com>
date Sun, 09 Nov 2025 06:25:16 -0800
parents c0f6c8c7829f
children ea9ef388ab97 3e0e27684e6b
comparison
equal deleted inserted replaced
35:33b1caf051cd 36:84672efec192
1 #include <sys/epoll.h> 1 #include <sys/epoll.h>
2 #include "seobeo/seobeo.h" 2 #include "seobeo/seobeo.h"
3 3
4 4
5 void *Seobeo_Web_Edge_Worker(void *vargs) 5 void *Seobeo_Web_Edge_Worker(void *vargs) {
6 {
7 WorkerArgs *args = vargs; 6 WorkerArgs *args = vargs;
8 uint32 max_events = 64; 7 const int max_events = 64;
9 struct epoll_event events[max_events]; 8 struct epoll_event events[max_events];
10 while (1) 9
11 { 10 while (1) {
12 int n = epoll_wait(args->evfd, events, max_events, -1); 11 int n = epoll_wait(args->evfd, events, max_events, -1);
13 if (n < 0) continue; 12 if (n < 0) {
13 perror("epoll_wait");
14 continue;
15 }
14 16
15 for (int i = 0; i < n; i++) 17 for (int i = 0; i < n; i++) {
16 { 18 Seobeo_PHandle phandle = events[i].data.ptr;
17 Seobeo_PHandle socket_fd = events[i].data.ptr;
18 // when server....
19 if (socket_fd == args->srv)
20 {
21 Seobeo_PHandle cli =
22 Seobeo_Stream_Handle_Server_Accept(socket_fd);
23 if (!cli) continue;
24 19
20 if (phandle == args->srv) {
21 while (1) {
22 Seobeo_PHandle p_cli_handle = Seobeo_Stream_Handle_Server_Accept(args->srv);
23 if (!p_cli_handle) break;
25 24
26 struct epoll_event client_ev = { 25 struct epoll_event client_ev = {
27 .events = EPOLLIN | EPOLLET, 26 .events = EPOLLIN | EPOLLET,
28 .data.ptr = cli 27 .data.ptr = p_cli_handle
29 }; 28 };
30 epoll_ctl(args->evfd, EPOLL_CTL_ADD, 29 if (epoll_ctl(args->evfd, EPOLL_CTL_ADD, p_cli_handle->socket, &client_ev) < 0)
31 cli->socket, &client_ev); 30 {
32 } 31 perror("epoll_ctl ADD client");
33 // when client.... 32 Seobeo_Handle_Destroy(p_cli_handle);
34 else 33 }
35 { 34 }
36 Seobeo_Web_HandleClientRequest(socket_fd, args->cache); // This frees 35 } else {
36 Seobeo_Web_HandleClientRequest(phandle, args->cache);
37 epoll_ctl(args->evfd, EPOLL_CTL_DEL, phandle->socket, NULL);
38 Seobeo_Handle_Destroy(phandle);
37 } 39 }
38 } 40 }
39 } 41 }
42
40 return NULL; 43 return NULL;
41 } 44 }
42 45
43 void Seobeo_Web_Edge( 46 void Seobeo_Web_Edge(
44 Seobeo_PHandle p_server_handle, 47 Seobeo_PHandle p_server_handle,
45 int thread_count, 48 int thread_count,
46 Dowa_PHashMap p_html_cache) 49 Dowa_PHashMap p_html_cache) {
47 { 50
48 int epfd = epoll_create1(0); 51 int epfd = epoll_create1(0);
52 if (epfd < 0) {
53 perror("epoll_create1");
54 return;
55 }
56
49 struct epoll_event ev = { 57 struct epoll_event ev = {
50 .events = EPOLLIN, 58 .events = EPOLLIN | EPOLLET,
51 .data.ptr = p_server_handle 59 .data.ptr = p_server_handle
52 }; 60 };
53 epoll_ctl(epfd, EPOLL_CTL_ADD, 61 if (epoll_ctl(epfd, EPOLL_CTL_ADD, p_server_handle->socket, &ev) < 0) {
54 p_server_handle->socket, &ev); 62 perror("epoll_ctl ADD server");
63 close(epfd);
64 return;
65 }
55 66
56 pthread_attr_t attr; 67 pthread_attr_t attr;
57 pthread_attr_init(&attr); 68 pthread_attr_init(&attr);
58 pthread_attr_setstacksize(&attr, 5 * 1024 * 1024); // 5 MB 69 pthread_attr_setstacksize(&attr, 5 * 1024 * 1024); // 5 MB
59 70
60 pthread_t threads[thread_count]; 71 for (int i = 0; i < thread_count; i++) {
61 for (int i = 0; i < thread_count; i++)
62 {
63 WorkerArgs *args = malloc(sizeof(WorkerArgs)); 72 WorkerArgs *args = malloc(sizeof(WorkerArgs));
64 *args = (WorkerArgs){ p_server_handle, p_html_cache, epfd }; 73 *args = (WorkerArgs){ p_server_handle, p_html_cache, epfd };
65 74
66 pthread_create(&threads[i], NULL, Seobeo_Web_Edge_Worker, args); 75 pthread_t tid;
76 pthread_create(&tid, &attr, Seobeo_Web_Edge_Worker, args);
77 pthread_detach(tid);
67 } 78 }
68 for (int i = 0; i < thread_count; i++) 79
80 while (1) pause();
81 }
82
83
84 void Seobeo_Web_Edge_2(Seobeo_PHandle p_handle_server, Dowa_PHashMap cache) {
85 const int MAX_EVENTS = 1024;
86 struct epoll_event events[MAX_EVENTS];
87 char keybuf[32];
88
89 int epfd = epoll_create1(0);
90 if (epfd < 0)
69 { 91 {
70 pthread_join(threads[i], NULL); 92 perror("epoll_create1");
93 return;
71 } 94 }
72 return; 95
96 struct epoll_event ev = {
97 .events = EPOLLIN | EPOLLET,
98 .data.fd = p_handle_server->socket
99 };
100 if (epoll_ctl(epfd, EPOLL_CTL_ADD, p_handle_server->socket, &ev) < 0)
101 {
102 perror("epoll_ctl ADD server");
103 close(epfd);
104 return;
105 }
106
107 Dowa_PHashMap handles = Dowa_HashMap_Create(1024);
108 snprintf(keybuf, sizeof(keybuf), "%d", p_handle_server->socket);
109 Dowa_HashMap_Push_Value(handles, keybuf, p_handle_server, sizeof(p_handle_server));
110
111 while (1) {
112 int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
113 if (n < 0)
114 {
115 if (errno == EINTR) continue;
116 perror("epoll_wait");
117 break;
118 }
119
120 for (int i = 0; i < n; i++)
121 {
122 int fd = events[i].data.fd;
123
124 if (fd == p_handle_server->socket)
125 {
126 while (1)
127 {
128 Seobeo_PHandle p_handle_client = Seobeo_Stream_Handle_Server_Accept(p_handle_server);
129 if (!p_handle_client) break;
130
131 struct epoll_event client_ev = {
132 .events = EPOLLIN | EPOLLET,
133 .data.fd = p_handle_client->socket
134 };
135 if (epoll_ctl(epfd, EPOLL_CTL_ADD, p_handle_client->socket, &client_ev) < 0)
136 {
137 perror("epoll_ctl ADD client");
138 continue;
139 }
140
141 snprintf(keybuf, sizeof(keybuf), "%d", p_handle_client->socket);
142 if (p_handle_client)
143 Dowa_HashMap_Push_Value_With_Type_NoCopy(handles, keybuf, p_handle_client,
144 sizeof(p_handle_client), DOWA_HASH_MAP_TYPE_HASHMAP);
145 }
146 continue;
147 }
148
149 snprintf(keybuf, sizeof(keybuf), "%d", fd);
150 Seobeo_PHandle p_handle_client = Dowa_HashMap_Get(handles, keybuf);
151 if (!p_handle_client)
152 {
153 // might happen if client closed between event and lookup
154 epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
155 continue;
156 }
157
158 Seobeo_Web_HandleClientRequest(p_handle_client, cache);
159 }
160 }
161
162 close(epfd);
73 } 163 }
164