diff 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
line wrap: on
line diff
--- a/seobeo/os/s_linux_edge.c	Thu Oct 30 09:53:22 2025 -0700
+++ b/seobeo/os/s_linux_edge.c	Sun Nov 09 06:25:16 2025 -0800
@@ -2,72 +2,163 @@
 #include "seobeo/seobeo.h"
 
 
-void  *Seobeo_Web_Edge_Worker(void *vargs)
-{
+void *Seobeo_Web_Edge_Worker(void *vargs) {
   WorkerArgs *args = vargs;
-  uint32 max_events = 64;
+  const int max_events = 64;
   struct epoll_event events[max_events];
-  while (1)
-  {
+
+  while (1) {
     int n = epoll_wait(args->evfd, events, max_events, -1);
-    if (n < 0) continue;
+    if (n < 0) {
+      perror("epoll_wait");
+      continue;
+    }
+
+    for (int i = 0; i < n; i++) {
+      Seobeo_PHandle phandle = events[i].data.ptr;
 
-    for (int i = 0; i < n; i++)
-    {
-      Seobeo_PHandle socket_fd = events[i].data.ptr;
-      // when server....
-      if (socket_fd == args->srv)
-      {
-        Seobeo_PHandle cli =
-          Seobeo_Stream_Handle_Server_Accept(socket_fd);
-        if (!cli) continue;
-
+      if (phandle == args->srv) {
+        while (1) {
+          Seobeo_PHandle p_cli_handle = Seobeo_Stream_Handle_Server_Accept(args->srv);
+          if (!p_cli_handle) break;
 
-        struct epoll_event client_ev = {
-          .events = EPOLLIN | EPOLLET,  
-          .data.ptr = cli
-        };
-        epoll_ctl(args->evfd, EPOLL_CTL_ADD,
-                  cli->socket, &client_ev);
-      }
-      // when client....
-      else
-      {
-        Seobeo_Web_HandleClientRequest(socket_fd, args->cache); // This frees
+          struct epoll_event client_ev = {
+            .events = EPOLLIN | EPOLLET,
+            .data.ptr = p_cli_handle
+          };
+          if (epoll_ctl(args->evfd, EPOLL_CTL_ADD, p_cli_handle->socket, &client_ev) < 0)
+          {
+            perror("epoll_ctl ADD client");
+            Seobeo_Handle_Destroy(p_cli_handle);
+          }
+        }
+      } else {
+        Seobeo_Web_HandleClientRequest(phandle, args->cache);
+        epoll_ctl(args->evfd, EPOLL_CTL_DEL, phandle->socket, NULL);
+        Seobeo_Handle_Destroy(phandle);
       }
     }
   }
+
   return NULL;
 }
 
-void  Seobeo_Web_Edge(
+void Seobeo_Web_Edge(
     Seobeo_PHandle p_server_handle,
-    int            thread_count,
-    Dowa_PHashMap   p_html_cache)
-{
+    int thread_count,
+    Dowa_PHashMap p_html_cache) {
+
   int epfd = epoll_create1(0);
+  if (epfd < 0) {
+    perror("epoll_create1");
+    return;
+  }
+
   struct epoll_event ev = {
-    .events   = EPOLLIN,
+    .events = EPOLLIN | EPOLLET,
     .data.ptr = p_server_handle
   };
-  epoll_ctl(epfd, EPOLL_CTL_ADD,
-            p_server_handle->socket, &ev);
+  if (epoll_ctl(epfd, EPOLL_CTL_ADD, p_server_handle->socket, &ev) < 0) {
+    perror("epoll_ctl ADD server");
+    close(epfd);
+    return;
+  }
 
   pthread_attr_t attr;
   pthread_attr_init(&attr);
   pthread_attr_setstacksize(&attr, 5 * 1024 * 1024); // 5 MB
 
-  pthread_t  threads[thread_count];
-  for (int i = 0; i < thread_count; i++)
-  {
+  for (int i = 0; i < thread_count; i++) {
     WorkerArgs *args = malloc(sizeof(WorkerArgs));
     *args = (WorkerArgs){ p_server_handle, p_html_cache, epfd };
 
-    pthread_create(&threads[i], NULL, Seobeo_Web_Edge_Worker, args);
+    pthread_t tid;
+    pthread_create(&tid, &attr, Seobeo_Web_Edge_Worker, args);
+    pthread_detach(tid);
   }
-  for (int i = 0; i < thread_count; i++)
+
+  while (1) pause();
+}
+
+
+void Seobeo_Web_Edge_2(Seobeo_PHandle p_handle_server, Dowa_PHashMap cache) {
+  const int MAX_EVENTS = 1024;
+  struct epoll_event events[MAX_EVENTS];
+  char keybuf[32];
+
+  int epfd = epoll_create1(0);
+  if (epfd < 0)
+  {
+    perror("epoll_create1");
+    return;
+  }
+
+  struct epoll_event ev = {
+    .events = EPOLLIN | EPOLLET,
+    .data.fd = p_handle_server->socket
+  };
+  if (epoll_ctl(epfd, EPOLL_CTL_ADD, p_handle_server->socket, &ev) < 0)
   {
-    pthread_join(threads[i], NULL);
+    perror("epoll_ctl ADD server");
+    close(epfd);
+    return;
   }
-  return;
+
+  Dowa_PHashMap handles = Dowa_HashMap_Create(1024);
+  snprintf(keybuf, sizeof(keybuf), "%d", p_handle_server->socket);
+  Dowa_HashMap_Push_Value(handles, keybuf, p_handle_server, sizeof(p_handle_server));
+
+  while (1) {
+    int n = epoll_wait(epfd, events, MAX_EVENTS, -1);
+    if (n < 0)
+    {
+      if (errno == EINTR) continue;
+      perror("epoll_wait");
+      break;
+    }
+
+    for (int i = 0; i < n; i++)
+    {
+      int fd = events[i].data.fd;
+
+      if (fd == p_handle_server->socket)
+      {
+        while (1)
+        {
+          Seobeo_PHandle p_handle_client = Seobeo_Stream_Handle_Server_Accept(p_handle_server);
+          if (!p_handle_client) break;
+
+          struct epoll_event client_ev = {
+            .events = EPOLLIN | EPOLLET,
+            .data.fd = p_handle_client->socket
+          };
+          if (epoll_ctl(epfd, EPOLL_CTL_ADD, p_handle_client->socket, &client_ev) < 0)
+          {
+            perror("epoll_ctl ADD client");
+            continue;
+          }
+
+          snprintf(keybuf, sizeof(keybuf), "%d", p_handle_client->socket);
+          if (p_handle_client)
+              Dowa_HashMap_Push_Value_With_Type_NoCopy(handles, keybuf, p_handle_client,
+                                                       sizeof(p_handle_client), DOWA_HASH_MAP_TYPE_HASHMAP);
+        }
+        continue;
+      }
+
+      snprintf(keybuf, sizeof(keybuf), "%d", fd);
+      Seobeo_PHandle p_handle_client = Dowa_HashMap_Get(handles, keybuf);
+      if (!p_handle_client)
+      {
+        // might happen if client closed between event and lookup
+        epoll_ctl(epfd, EPOLL_CTL_DEL, fd, NULL);
+        continue;
+      }
+
+      Seobeo_Web_HandleClientRequest(p_handle_client, cache);
+    }
+  }
+
+  close(epfd);
 }
+