Mercurial
diff seobeo/os/s_macos_edge.c @ 62:ea9ef388ab97
[Seobeo] Fixed issues with epoll or kqeue in different threads. Initizlied the event looop inside of the thread itself.
| author | June Park <parkjune1995@gmail.com> |
|---|---|
| date | Tue, 23 Dec 2025 11:48:11 -0800 |
| parents | c0f6c8c7829f |
| children | ecb6ee6a22c3 |
line wrap: on
line diff
--- a/seobeo/os/s_macos_edge.c Sat Dec 20 21:07:34 2025 -0500 +++ b/seobeo/os/s_macos_edge.c Tue Dec 23 11:48:11 2025 -0800 @@ -6,41 +6,66 @@ { WorkerArgs *args = vargs; struct kevent evlist[64]; + + // Each thread creates its own kqueue to avoid race conditions + int kq = kqueue(); + if (kq < 0) { + perror("kqueue"); + return NULL; + } + + // Add server socket to this thread's kqueue + struct kevent kev = { + .ident = args->srv->socket, + .filter = EVFILT_READ, + .flags = EV_ADD, + .udata = args->srv + }; + kevent(kq, &kev, 1, NULL, 0, NULL); + while (1) { - int ne = kevent(args->evfd, NULL, 0, evlist, 64, NULL); - if (ne < 0) continue; + int ne = kevent(kq, NULL, 0, evlist, 64, NULL); + if (ne < 0) { + if (errno == EINTR) continue; + perror("kevent"); + continue; + } for (int i = 0; i < ne; i++) { Seobeo_PHandle h = evlist[i].udata; if (h == args->srv) { - Seobeo_PHandle cli = - Seobeo_Stream_Handle_Server_Accept(args->srv); + // Accept new connections in a loop (for edge-triggered behavior) + while (1) { + Seobeo_PHandle cli = Seobeo_Stream_Handle_Server_Accept(args->srv); + if (!cli) break; - if (!cli) continue; - struct kevent kev = { - .ident = cli->socket, + struct kevent client_kev = { + .ident = cli->socket, + .filter = EVFILT_READ, + .flags = EV_ADD | EV_ONESHOT, + .udata = cli + }; + kevent(kq, &client_kev, 1, NULL, 0, NULL); + } + } else { + // Remove from kqueue first + struct kevent del_kev = { + .ident = h->socket, .filter = EVFILT_READ, - .flags = EV_ADD | EV_ONESHOT, - .udata = cli + .flags = EV_DELETE, }; - kevent(args->evfd, &kev, 1, NULL, 0, NULL); - } else { - if (h != args->srv) { - struct kevent kev = { - .ident = h->socket, - .filter = EVFILT_READ, - .flags = EV_DELETE, - }; - kevent(args->evfd, &kev, 1, NULL, 0, NULL); // Remove from kqueue first - - Seobeo_Web_HandleClientRequest(h, args->cache); // this frees - } + kevent(kq, &del_kev, 1, NULL, 0, NULL); + + // Handle request (this function destroys the handle internally) + Seobeo_Web_HandleClientRequest(h, args->cache); } } } + + close(kq); return NULL; } @@ -49,15 +74,6 @@ int thread_count, Dowa_PHashMap p_html_cache) { - int kq = kqueue(); - struct kevent kev = { - .ident = p_server_handle->socket, - .filter = EVFILT_READ, - .flags = EV_ADD, - .udata = p_server_handle - }; - kevent(kq, &kev, 1, NULL, 0, NULL); - pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setstacksize(&attr, 5 * 1024 * 1024); // 5 MB @@ -66,13 +82,15 @@ for (int i = 0; i < thread_count; i++) { WorkerArgs *args = malloc(sizeof(WorkerArgs)); - *args = (WorkerArgs){ p_server_handle, p_html_cache, kq }; + *args = (WorkerArgs){ p_server_handle, p_html_cache }; - pthread_create(&threads[i], NULL, Seobeo_Web_Edge_Worker, args); + pthread_create(&threads[i], &attr, Seobeo_Web_Edge_Worker, args); } for (int i = 0; i < thread_count; i++) { pthread_join(threads[i], NULL); } + + pthread_attr_destroy(&attr); return; }