Mercurial
changeset 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 | 33b1caf051cd |
| children | fb9bcd3145cb |
| files | debugger.sh dowa/d_memory.c dowa/dowa.h mrjunejune/main.c seobeo/os/s_linux_edge.c seobeo/s_linux_network.c seobeo/s_web.c seobeo/seobeo.h seobeo/seobeo_internal.h |
| diffstat | 9 files changed, 241 insertions(+), 99 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/debugger.sh Sun Nov 09 06:25:16 2025 -0800 @@ -0,0 +1,3 @@ +#!/bin/bash + +bazel build //mrjunejune:mrjunejune_server -c dbg && gdb bazel-bin/mrjunejune/mrjunejune_server
--- a/dowa/d_memory.c Thu Oct 30 09:53:22 2025 -0700 +++ b/dowa/d_memory.c Sun Nov 09 06:25:16 2025 -0800 @@ -31,8 +31,8 @@ if (!p_arena) return; if (p_arena->buffer) - free(p_arena->buffer); - free(p_arena); + Dowa_Free(p_arena->buffer); + Dowa_Free(p_arena); } void *Dowa_Arena_Copy(Dowa_PArena p_arena, const void *src, size_t size) @@ -60,7 +60,7 @@ p_hash_map->entries = calloc(capacity, sizeof(*p_hash_map->entries)); if (p_hash_map->entries == NULL) { - free(p_hash_map); + Dowa_Free(p_hash_map); return NULL; } p_hash_map->capacity = capacity; @@ -87,7 +87,7 @@ memset(p_hash_map->entries, 0, capacity * sizeof *p_hash_map->entries); if (p_hash_map->entries == NULL) { - free(p_hash_map); + Dowa_Free(p_hash_map); return NULL; } p_hash_map->capacity = capacity; @@ -116,15 +116,15 @@ entry = p_hash_map->entries[idx]; if (entry) { - free(entry->key); - free(entry->buffer); - free(entry); + Dowa_Free(entry->key); + Dowa_Free(entry->buffer); + Dowa_Free(entry); } } } - free(p_hash_map->entries); + Dowa_Free(p_hash_map->entries); } - free(p_hash_map); + Dowa_Free(p_hash_map); } int32 Dowa_HashMap_Get_Position(Dowa_PHashMap p_hash_map, const char *key) @@ -169,17 +169,29 @@ { if (strcmp(entry->key, key) == 0) { - if (!p_hash_map->p_arena && entry->buffer) - free(entry->buffer); - entry->buffer = value; - entry->capacity = value_size; - entry->type = type; - return 0; + // Fails if it the key exists... + return -1; } - prev = entry; - entry = entry->next; } + // Overriding doesn't really make sense? when copying over + // as we need to free it. + // + //while (entry) + //{ + // if (strcmp(entry->key, key) == 0) + // { + // if (!p_hash_map->p_arena && entry->buffer) + // Dowa_Free(entry->buffer); + // entry->buffer = value; + // entry->capacity = value_size; + // entry->type = type; + // return 0; + // } + // prev = entry; + // entry = entry->next; + //} + // New Key entry = p_hash_map->p_arena ? Dowa_Arena_Allocate(p_hash_map->p_arena, sizeof(Dowa_HashEntry)) : @@ -217,7 +229,7 @@ if (strcmp(entry->key, key) == 0) { if (!p_hash_map->p_arena && entry->buffer) - free(entry->buffer); + Dowa_Free(entry->buffer); entry->buffer = p_hash_map->p_arena ? Dowa_Arena_Allocate(p_hash_map->p_arena, value_size) : @@ -274,9 +286,9 @@ Dowa_PHashEntry entry = p_hash_map->entries[idx]; if (entry && !(p_hash_map->p_arena)) { - free(entry->key); - free(entry->buffer); - free(entry); + Dowa_Free(entry->key); + Dowa_Free(entry->buffer); + Dowa_Free(entry); } p_hash_map->entries[idx] = NULL; if (p_hash_map->current_capacity > 0) @@ -368,14 +380,14 @@ if (fread(buf, 1, size, f) != size) { perror("fread"); - if (!p_hash_map->p_arena) free(buf); + if (!p_hash_map->p_arena) Dowa_Free(buf); fclose(f); continue; } fclose(f); Dowa_HashMap_Push_Value_With_Type(p_hash_map, entry->d_name, buf, size, DOWA_HASH_MAP_TYPE_STRING); - free(buf); // Dowa_HashMap_PushValue made its own copy + Dowa_Free(buf); // Dowa_HashMap_PushValue made its own copy } else if (S_ISDIR(st.st_mode)) {
--- a/dowa/dowa.h Thu Oct 30 09:53:22 2025 -0700 +++ b/dowa/dowa.h Sun Nov 09 06:25:16 2025 -0800 @@ -17,6 +17,13 @@ #define TRUE 1 #define FALSE 0 +#define Dowa_Free(p) do { \ + if (p) { \ + free(p); \ + (p) = NULL; \ + } \ +} while (0) + // Fixed-width integer types typedef unsigned int uint32; // 32-bit unsigned integer typedef int int32; // 32-bit signed integer
--- a/mrjunejune/main.c Thu Oct 30 09:53:22 2025 -0700 +++ b/mrjunejune/main.c Sun Nov 09 06:25:16 2025 -0800 @@ -11,6 +11,12 @@ #include "seobeo/seobeo.h" +volatile sig_atomic_t stop_server = 0; + +void handle_sigint(int sig) { + printf("Failed\n"); + stop_server = 1; +} int main(void) {
--- 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); } +
--- a/seobeo/s_linux_network.c Thu Oct 30 09:53:22 2025 -0700 +++ b/seobeo/s_linux_network.c Sun Nov 09 06:25:16 2025 -0800 @@ -37,9 +37,13 @@ } if (listen(socket_fd, 16) != 0) - { perror("listen"); close(socket_fd); return NULL; } + { + printf("Closing: %d", socket_fd); + perror("listen"); close(socket_fd); return NULL; + } - if(fcntl(socket_fd, F_SETFL, O_NONBLOCK) != 0) { perror("fcntl"); return NULL; } + int flags = fcntl(socket_fd, F_GETFL, 0); + if(fcntl(socket_fd, F_SETFL, flags | O_NONBLOCK) != 0) { perror("fcntl"); return NULL; } freeaddrinfo(server_infos); p_handle = malloc(sizeof(*p_handle)); @@ -62,9 +66,6 @@ p_handle->write_buffer_capacity = INITIAL_BUFFER_CAPACITY; p_handle->write_buffer_len = 0; - p_handle->file = NULL; - p_handle->text_copy = NULL; - p_handle->file_name = NULL; p_handle->destroyed = false; return p_handle; @@ -135,9 +136,6 @@ p_handle->write_buffer_capacity = INITIAL_BUFFER_CAPACITY; p_handle->write_buffer_len = 0; - p_handle->file = NULL; - p_handle->text_copy = NULL; - p_handle->file_name = NULL; p_handle->destroyed = false; return p_handle; @@ -194,14 +192,14 @@ if (!p_handle) return; bool expected = false; + // Need to check if (!atomic_compare_exchange_strong(&p_handle->destroyed, &expected, true)) { - // Already destroyed by another thread return; } - if (p_handle->host) free(p_handle->host); - if (p_handle->port) free(p_handle->port); + if (p_handle->host) Dowa_Free(p_handle->host); + if (p_handle->port) Dowa_Free(p_handle->port); if (p_handle->ssl) { @@ -216,15 +214,15 @@ p_handle->ssl_ctx = NULL; } - if (p_handle->socket) close(p_handle->socket); - - if (p_handle->read_buffer) free(p_handle->read_buffer); - if (p_handle->write_buffer) free(p_handle->write_buffer); + if (p_handle->socket) { + printf("Closing: %d", p_handle->socket); + close(p_handle->socket); + } - if (p_handle->text_copy) free(p_handle->text_copy); - if (p_handle->file_name) free(p_handle->file_name); + if (p_handle->read_buffer) Dowa_Free(p_handle->read_buffer); + if (p_handle->write_buffer) Dowa_Free(p_handle->write_buffer); - free(p_handle); + Dowa_Free(p_handle); } @@ -254,6 +252,7 @@ sent += (uint32)n; }else { + printf("socket: %d\n", p_handle->socket); ssize_t n = write( p_handle->socket, p_handle->write_buffer + sent, @@ -315,12 +314,28 @@ return 0; } + if (!p_handle) { + printf("[ERROR] p_handle is NULL before memcpy\n"); + return; + } + + if (!p_handle->write_buffer) { + printf("[ERROR] p_handle->write_buffer is NULL (len=%zu, size=%zu)\n", + p_handle->write_buffer_len, data_size); + return; + } + + printf("[DEBUG] memcpy -> dest=%p (write_buffer=%p + offset=%zu), src=%p, size=%zu\n", + p_handle->write_buffer + p_handle->write_buffer_len, + p_handle->write_buffer, + p_handle->write_buffer_len, + data, + data_size); + memcpy(p_handle->write_buffer + p_handle->write_buffer_len, data, data_size); p_handle->write_buffer_len += data_size; - // DEBUG - printf("\nheader data_size: %d\n\n", data_size); return 0; }
--- a/seobeo/s_web.c Thu Oct 30 09:53:22 2025 -0700 +++ b/seobeo/s_web.c Sun Nov 09 06:25:16 2025 -0800 @@ -58,6 +58,7 @@ void Seobeo_Web_HandleClientRequest(Seobeo_PHandle p_cli_handle, Dowa_PHashMap p_html_cache) { + printf("p_cli_handle: %p", p_cli_handle); Dowa_PHashEntry entry = NULL; Dowa_PHashMap p_current = p_html_cache; char *slash; @@ -80,9 +81,10 @@ (uint32)strlen(p_response_header)); Seobeo_Handle_Flush(p_cli_handle); goto clean_up; + return; } - Dowa_HashMap_Print(p_req_map); + // Dowa_HashMap_Print(p_req_map); // Extract method (GET, POST, etc.) const char *method = (const char*)Dowa_HashMap_Get(p_req_map, "HTTP_Method"); @@ -249,10 +251,12 @@ goto clean_up; clean_up: - if (p_cli_handle) - Seobeo_Handle_Destroy(p_cli_handle); - if (p_response_arena) - Dowa_Arena_Destroy(p_response_arena); + printf("clean up\n\n"); + return; +// if (p_cli_handle) +// Seobeo_Handle_Destroy(p_cli_handle); +// if (p_response_arena) +// Dowa_Arena_Destroy(p_response_arena); } @@ -400,12 +404,12 @@ Dowa_HashMap_Push_Value_With_Type(map, key, val, value_len + 1, DOWA_HASH_MAP_TYPE_STRING); - printf("Capacity: %d, Length: %d ", (int)map->p_arena->capacity, (int)map->p_arena->offset); - printf("value_len: %d, key: %s value %s position: %d\n\n", (int)value_len + 1, key, val, Dowa_HashMap_Get_Position(map, key)); - printf("Method: %s Position: %d Pointer %p\n\n", Dowa_HashMap_Get(map, "HTTP_Method"), Dowa_HashMap_Get_Position(map, "HTTP_Method"), map); + // printf("Capacity: %d, Length: %d ", (int)map->p_arena->capacity, (int)map->p_arena->offset); + // printf("value_len: %d, key: %s value %s position: %d\n\n", (int)value_len + 1, key, val, Dowa_HashMap_Get_Position(map, key)); + // printf("Method: %s Position: %d Pointer %p\n\n", Dowa_HashMap_Get(map, "HTTP_Method"), Dowa_HashMap_Get_Position(map, "HTTP_Method"), map); - free(key); - free(val); + Dowa_Free(key); + Dowa_Free(val); } line = next + 2; @@ -430,7 +434,7 @@ body[body_len] = '\0'; Dowa_HashMap_Push_Value(map, "Body", body, body_len + 1); - free(body); + Dowa_Free(body); Seobeo_Handle_Consume(p_handle, (uint32)body_len); } @@ -483,13 +487,13 @@ while (1) { - Seobeo_PHandle cli = + Seobeo_PHandle p_cli_handle = Seobeo_Stream_Handle_Server_Accept(p_server_handle); - if (!cli) continue; + if (!p_cli_handle) continue; if (fork() == 0) { - Seobeo_Web_HandleClientRequest(cli, + Seobeo_Web_HandleClientRequest(p_cli_handle, p_html_cache); _exit(0); } @@ -499,7 +503,8 @@ if (mode == SEOBEO_MODE_EDGE) { printf("EDGE MODE\n"); - Seobeo_Web_Edge(p_server_handle, thread_count, p_html_cache); + Seobeo_Web_Edge_2(p_server_handle, p_html_cache); + // Seobeo_Web_Edge(p_server_handle, thread_count, p_html_cache); } return -1;
--- a/seobeo/seobeo.h Thu Oct 30 09:53:22 2025 -0700 +++ b/seobeo/seobeo.h Sun Nov 09 06:25:16 2025 -0800 @@ -40,6 +40,8 @@ #define HTTP_NOT_FOUND 404 #define HTTP_INTERNAL_ERROR 500 +extern volatile sig_atomic_t stop_server; + // --- TCP --- // // --- Generate a Server Handle. ---// extern Seobeo_PHandle Seobeo_Stream_Handle_Server_Create(const char *host, const char* port);
--- a/seobeo/seobeo_internal.h Thu Oct 30 09:53:22 2025 -0700 +++ b/seobeo/seobeo_internal.h Sun Nov 09 06:25:16 2025 -0800 @@ -66,6 +66,7 @@ // --- Serving using Edge --- // extern void *Seobeo_Web_Edge_Worker(void *vargs); extern void Seobeo_Web_Edge(Seobeo_PHandle p_server_handle, int thread_count, Dowa_PHashMap p_html_cache); +extern void Seobeo_Web_Edge_2(Seobeo_PHandle p_server_handle, Dowa_PHashMap p_html_cache); #endif