1818 */
1919
2020#define _GNU_SOURCE
21+
22+ #include <sys/types.h>
23+ #include <sys/event.h>
24+ #include <sys/resource.h>
25+ #include <sys/socket.h>
26+ #include <sys/time.h>
27+ #include <sys/uio.h>
28+
2129#include <arpa/inet.h>
30+ #include <netinet/in.h>
31+ #include <netinet/tcp.h>
32+
2233#include <ctype.h>
2334#include <errno.h>
2435#include <fcntl.h>
25- #include <netinet/in.h>
26- #include <netinet/tcp.h>
2736#include <pthread.h>
2837#include <pthread_np.h>
2938#include <setjmp.h>
3039#include <signal.h>
3140#include <stdio.h>
3241#include <stdlib.h>
3342#include <string.h>
34- #include <sys/epoll.h>
35- #include <sys/resource.h>
36- #include <sys/socket.h>
37- #include <sys/time.h>
38- #include <sys/types.h>
39- #include <sys/uio.h>
4043#include <unistd.h>
4144
4245#include "lwan.h"
@@ -339,24 +342,29 @@ static void *
339342_thread (void * data )
340343{
341344 lwan_thread_t * t = data ;
342- struct epoll_event events [t -> lwan -> thread .max_fd ];
343- int epoll_fd = t -> epoll_fd , n_fds , i ;
345+ struct kevent events [t -> lwan -> thread .max_fd ];
346+ int kqueue_fd = t -> kqueue_fd , n_fds , i ;
344347 unsigned int death_time = 0 ;
345348
346349 lwan_request_t * requests = t -> lwan -> requests ;
347350 int * death_queue = calloc (1 , t -> lwan -> thread .max_fd * sizeof (int ));
348351 int death_queue_last = 0 , death_queue_first = 0 , death_queue_population = 0 ;
349352
353+ const struct timespec keep_alive_length = {
354+ .tv_sec = 1 ,
355+ .tv_nsec = 0
356+ };
357+
350358 for (; ; ) {
351- switch (n_fds = epoll_wait ( epoll_fd , events , N_ELEMENTS (events ),
352- death_queue_population ? 1000 : -1 )) {
359+ switch (n_fds = kevent ( kqueue_fd , NULL , 0 , events , N_ELEMENTS (events ),
360+ death_queue_population ? & keep_alive_length : NULL )) {
353361 case -1 :
354362 switch (errno ) {
355363 case EBADF :
356364 case EINVAL :
357- goto epoll_fd_closed ;
365+ goto kqueue_fd_closed ;
358366 case EINTR :
359- perror ("epoll_wait " );
367+ perror ("kevent " );
360368 }
361369 continue ;
362370 case 0 : /* timeout: shutdown waiting sockets */
@@ -381,18 +389,19 @@ _thread(void *data)
381389 break ;
382390 default : /* activity in some of this poller's file descriptor */
383391 for (i = 0 ; i < n_fds ; ++ i ) {
384- lwan_request_t * request = & requests [events [i ].data . fd ];
392+ lwan_request_t * request = & requests [events [i ].ident ];
385393
386- if (events [i ].events & (EPOLLRDHUP | EPOLLHUP )) {
387- if (epoll_ctl (epoll_fd , EPOLL_CTL_DEL , events [i ].data .fd , & events [i ]) < 0 )
388- perror ("epoll_ctl" );
394+ if (events [i ].flags & EV_EOF ) {
395+ struct kevent ev ;
396+ EV_SET (& ev , events [i ].ident , EVFILT_READ , EV_DELETE , 0 , 0 , NULL );
397+ kevent (kqueue_fd , & ev , 1 , NULL , 0 , NULL );
389398 goto invalidate_request ;
390399 }
391400
392401 if (!request -> flags .alive ) {
393402 /* Reset the whole thing. */
394403 memset (request , 0 , sizeof (* request ));
395- request -> fd = events [i ].data . fd ;
404+ request -> fd = events [i ].ident ;
396405 }
397406
398407 /*
@@ -416,22 +425,22 @@ _thread(void *data)
416425 * socket again. Or not. Mwahahaha.
417426 */
418427 if (!request -> flags .alive ) {
419- death_queue [death_queue_last ++ ] = events [i ].data . fd ;
428+ death_queue [death_queue_last ++ ] = events [i ].ident ;
420429 ++ death_queue_population ;
421430 death_queue_last %= t -> lwan -> thread .max_fd ;
422431 request -> flags .alive = true;
423432 }
424433 continue ;
425434 }
426435
427- close (events [i ].data . fd );
436+ close (events [i ].ident );
428437invalidate_request :
429438 request -> flags .alive = false;
430439 }
431440 }
432441 }
433442
434- epoll_fd_closed :
443+ kqueue_fd_closed :
435444 free (death_queue );
436445
437446 return NULL ;
@@ -444,8 +453,8 @@ _create_thread(lwan_t *l, int thread_n)
444453 lwan_thread_t * thread = & l -> thread .threads [thread_n ];
445454
446455 thread -> lwan = l ;
447- if ((thread -> epoll_fd = epoll_create1 ( 0 )) < 0 ) {
448- perror ("epoll_create " );
456+ if ((thread -> kqueue_fd = kqueue ( )) < 0 ) {
457+ perror ("kqueue (_create_thread) " );
449458 exit (-1 );
450459 }
451460
@@ -511,7 +520,7 @@ _thread_shutdown(lwan_t *l)
511520 * finalized.
512521 */
513522 for (i = l -> thread .count - 1 ; i >= 0 ; i -- )
514- close (l -> thread .threads [i ].epoll_fd );
523+ close (l -> thread .threads [i ].kqueue_fd );
515524 for (i = l -> thread .count - 1 ; i >= 0 ; i -- )
516525 pthread_join (l -> thread .threads [i ].id , NULL );
517526
@@ -719,14 +728,13 @@ _schedule_request(lwan_t *l)
719728ALWAYS_INLINE static void
720729_push_request_fd (lwan_t * l , int fd )
721730{
722- int epoll_fd = l -> thread .threads [_schedule_request (l )].epoll_fd ;
723- struct epoll_event event = {
724- .events = EPOLLIN | EPOLLRDHUP | EPOLLERR | EPOLLET ,
725- .data .fd = fd
726- };
731+ int kqueue_fd = l -> thread .threads [_schedule_request (l )].kqueue_fd ;
732+ struct kevent event ;
733+
734+ EV_SET (& event , fd , EVFILT_READ , EV_ADD | EV_CLEAR , 0 , l -> thread .count * l -> thread .max_fd , NULL );
727735
728- if (UNLIKELY (epoll_ctl ( epoll_fd , EPOLL_CTL_ADD , fd , & event ) < 0 )) {
729- perror ("epoll_ctl " );
736+ if (UNLIKELY (kevent ( kqueue_fd , & event , 1 , NULL , 0 , NULL ) < 0 )) {
737+ perror ("kevent " );
730738 exit (-1 );
731739 }
732740}
@@ -746,37 +754,43 @@ lwan_main_loop(lwan_t *l)
746754
747755 signal (SIGINT , _cleanup );
748756
749- int epoll_fd = epoll_create1 (0 );
750- struct epoll_event events [128 ];
751- struct epoll_event ev = {
752- .events = EPOLLIN ,
753- };
754-
755757 if (fcntl (l -> main_socket , F_SETFL , O_NONBLOCK ) < 0 ) {
756758 perror ("fcntl: main socket" );
757759 exit (-1 );
758760 }
759- if (epoll_ctl (epoll_fd , EPOLL_CTL_ADD , l -> main_socket , & ev ) < 0 ) {
760- perror ("epoll_ctl" );
761- exit (-1 );
761+
762+ int kqueue_fd = kqueue ();
763+ if (kqueue_fd < 0 ) {
764+ perror ("kqueue" );
765+ return ;
762766 }
763767
768+ struct kevent events [128 ];
769+ struct kevent ev ;
770+
771+ EV_SET (& ev , l -> main_socket , EVFILT_READ , EV_ADD , 0 , l -> thread .count * l -> thread .max_fd , NULL );
772+
764773 for (;;) {
765774 int n_fds ;
766- for (n_fds = epoll_wait ( epoll_fd , events , N_ELEMENTS (events ), -1 );
775+ for (n_fds = kevent ( kqueue_fd , & ev , 1 , events , N_ELEMENTS (events ), NULL );
767776 n_fds > 0 ;
768777 -- n_fds ) {
769- int child_fd = accept4 (l -> main_socket , NULL , NULL , SOCK_NONBLOCK );
778+ int child_fd = accept (l -> main_socket , NULL , NULL );
770779 if (UNLIKELY (child_fd < 0 )) {
771780 perror ("accept" );
772781 continue ;
773782 }
783+ if (UNLIKELY (fcntl (child_fd , F_SETFL , O_NONBLOCK ) < 0 )) {
784+ perror ("fnctl" );
785+ close (child_fd );
786+ continue ;
787+ }
774788
775789 _push_request_fd (l , child_fd );
776790 }
777791 }
778792
779- close (epoll_fd );
793+ close (kqueue_fd );
780794}
781795
782796int
0 commit comments