Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

add kqueue API support

test on macosx OK
  • Loading branch information...
commit fde092ee23c4b66506206acba2118d932cc12d0c 1 parent 77898f0
@Cofyc Cofyc authored
Showing with 78 additions and 0 deletions.
  1. +78 −0 mread.c
View
78 mread.c
@@ -1,7 +1,26 @@
#include "mread.h"
#include "ringbuffer.h"
+/* Test for polling API */
+#ifdef __linux__
+#define HAVE_EPOLL 1
+#endif
+
+#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || defined (__NetBSD__)
+#define HAVE_KQUEUE 1
+#endif
+
+#if !defined(HAVE_EPOLL) && !defined(HAVE_KQUEUE)
+#error "system does not support epoll or kqueue API"
+#endif
+/* ! Test for polling API */
+
+#ifdef HAVE_EPOLL
#include <sys/epoll.h>
+#elif HAVE_KQUEUE
+#include <sys/event.h>
+#endif
+
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
@@ -38,7 +57,11 @@ struct socket {
struct mread_pool {
int listen_fd;
+#ifdef HAVE_EPOLL
int epoll_fd;
+#elif HAVE_KQUEUE
+ int kqueue_fd;
+#endif
int max_connection;
int closed;
int active;
@@ -47,7 +70,11 @@ struct mread_pool {
struct socket * free_socket;
int queue_len;
int queue_head;
+#ifdef HAVE_EPOLL
struct epoll_event ev[READQUEUE];
+#elif HAVE_KQUEUE
+ struct kevent ev[READQUEUE];
+#endif
struct ringbuffer * rb;
};
@@ -120,6 +147,7 @@ mread_create(int port , int max , int buffer_size) {
return NULL;
}
+#ifdef HAVE_EPOLL
int epoll_fd = epoll_create(max + 1);
if (epoll_fd == -1) {
close(listen_fd);
@@ -135,11 +163,30 @@ mread_create(int port , int max , int buffer_size) {
close(epoll_fd);
return NULL;
}
+#elif HAVE_KQUEUE
+ int kqueue_fd = kqueue();
+ if (kqueue_fd == -1) {
+ close(listen_fd);
+ return NULL;
+ }
+
+ struct kevent ke;
+ EV_SET(&ke, listen_fd, EVFILT_READ, EV_ADD, 0, 0, LISTENSOCKET);
+ if (kevent(kqueue_fd, &ke, 1, NULL, 0, NULL) == -1) {
+ close(listen_fd);
+ close(kqueue_fd);
+ return NULL;
+ }
+#endif
struct mread_pool * self = malloc(sizeof(*self));
self->listen_fd = listen_fd;
+#ifdef HAVE_EPOLL
self->epoll_fd = epoll_fd;
+#elif HAVE_KQUEUE
+ self->kqueue_fd = kqueue_fd;
+#endif
self->max_connection = max;
self->closed = 0;
self->active = -1;
@@ -172,7 +219,11 @@ mread_close(struct mread_pool *self) {
if (self->listen_fd >= 0) {
close(self->listen_fd);
}
+#ifdef HAVE_EPOLL
close(self->epoll_fd);
+#elif HAVE_KQUEUE
+ close(self->kqueue_fd);
+#endif
_release_rb(self->rb);
free(self);
}
@@ -180,7 +231,14 @@ mread_close(struct mread_pool *self) {
static int
_read_queue(struct mread_pool * self, int timeout) {
self->queue_head = 0;
+#ifdef HAVE_EPOLL
int n = epoll_wait(self->epoll_fd , self->ev, READQUEUE, timeout);
+#elif HAVE_KQUEUE
+ struct timespec timeoutspec;
+ timeoutspec.tv_sec = timeout;
+ timeoutspec.tv_nsec = 0;
+ int n = kevent(self->kqueue_fd, NULL, 0, self->ev, READQUEUE, &timeoutspec);
+#endif
if (n == -1) {
self->queue_len = 0;
return -1;
@@ -194,7 +252,11 @@ _read_one(struct mread_pool * self) {
if (self->queue_head >= self->queue_len) {
return NULL;
}
+#ifdef HAVE_EPOLL
return self->ev[self->queue_head ++].data.ptr;
+#elif HAVE_KQUEUE
+ return self->ev[self->queue_head ++].udata;
+#endif
}
static struct socket *
@@ -219,6 +281,7 @@ _add_client(struct mread_pool * self, int fd) {
close(fd);
return;
}
+#ifdef HAVE_EPOLL
struct epoll_event ev;
ev.events = EPOLLIN;
ev.data.ptr = s;
@@ -226,6 +289,14 @@ _add_client(struct mread_pool * self, int fd) {
close(fd);
return;
}
+#elif HAVE_KQUEUE
+ struct kevent ke;
+ EV_SET(&ke, fd, EVFILT_READ, EV_ADD, 0, 0, s);
+ if (kevent(self->kqueue_fd, &ke, 1, NULL, 0, NULL) == -1) {
+ close(fd);
+ return;
+ }
+#endif
s->fd = fd;
s->node = NULL;
@@ -310,7 +381,14 @@ mread_close_client(struct mread_pool * self, int id) {
s->temp = NULL;
close(s->fd);
printf("MREAD close %d (fd=%d)\n",id,s->fd);
+
+#ifdef HAVE_EPOLL
epoll_ctl(self->epoll_fd, EPOLL_CTL_DEL, s->fd , NULL);
+#elif HAVE_KQUEUE
+ struct kevent ke;
+ EV_SET(&ke, s->fd, EVFILT_READ, EV_DELETE, 0, 0, NULL);
+ kevent(self->kqueue_fd, &ke, 1, NULL, 0, NULL);
+#endif
++self->closed;
}
Please sign in to comment.
Something went wrong with that request. Please try again.