103 lines
2.3 KiB
C
103 lines
2.3 KiB
C
#ifndef poll_socket_kqueue_h
|
|
#define poll_socket_kqueue_h
|
|
|
|
#include <netdb.h>
|
|
#include <unistd.h>
|
|
#include <fcntl.h>
|
|
#include <sys/event.h>
|
|
#include <sys/types.h>
|
|
#include <sys/socket.h>
|
|
#include <netinet/in.h>
|
|
#include <arpa/inet.h>
|
|
|
|
static bool
|
|
sp_invalid(int kfd) {
|
|
return kfd == -1;
|
|
}
|
|
|
|
static int
|
|
sp_create() {
|
|
return kqueue();
|
|
}
|
|
|
|
static void
|
|
sp_release(int kfd) {
|
|
close(kfd);
|
|
}
|
|
|
|
static void
|
|
sp_del(int kfd, int sock) {
|
|
struct kevent ke;
|
|
EV_SET(&ke, sock, EVFILT_READ, EV_DELETE, 0, 0, NULL);
|
|
kevent(kfd, &ke, 1, NULL, 0, NULL);
|
|
EV_SET(&ke, sock, EVFILT_WRITE, EV_DELETE, 0, 0, NULL);
|
|
kevent(kfd, &ke, 1, NULL, 0, NULL);
|
|
}
|
|
|
|
static int
|
|
sp_add(int kfd, int sock, void *ud) {
|
|
struct kevent ke;
|
|
EV_SET(&ke, sock, EVFILT_READ, EV_ADD, 0, 0, ud);
|
|
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
|
|
return 1;
|
|
}
|
|
EV_SET(&ke, sock, EVFILT_WRITE, EV_ADD, 0, 0, ud);
|
|
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
|
|
EV_SET(&ke, sock, EVFILT_READ, EV_DELETE, 0, 0, NULL);
|
|
kevent(kfd, &ke, 1, NULL, 0, NULL);
|
|
return 1;
|
|
}
|
|
EV_SET(&ke, sock, EVFILT_WRITE, EV_DISABLE, 0, 0, ud);
|
|
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
|
|
sp_del(kfd, sock);
|
|
return 1;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
static int
|
|
sp_enable(int kfd, int sock, void *ud, bool read_enable, bool write_enable) {
|
|
int ret = 0;
|
|
struct kevent ke;
|
|
EV_SET(&ke, sock, EVFILT_READ, read_enable ? EV_ENABLE : EV_DISABLE, 0, 0, ud);
|
|
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
|
|
ret |= 1;
|
|
}
|
|
EV_SET(&ke, sock, EVFILT_WRITE, write_enable ? EV_ENABLE : EV_DISABLE, 0, 0, ud);
|
|
if (kevent(kfd, &ke, 1, NULL, 0, NULL) == -1 || ke.flags & EV_ERROR) {
|
|
ret |= 1;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
static int
|
|
sp_wait(int kfd, struct event *e, int max) {
|
|
struct kevent ev[max];
|
|
int n = kevent(kfd, NULL, 0, ev, max, NULL);
|
|
|
|
int i;
|
|
for (i=0;i<n;i++) {
|
|
e[i].s = ev[i].udata;
|
|
unsigned filter = ev[i].filter;
|
|
bool eof = (ev[i].flags & EV_EOF) != 0;
|
|
e[i].write = (filter == EVFILT_WRITE) && (!eof);
|
|
e[i].read = (filter == EVFILT_READ);
|
|
e[i].error = (ev[i].flags & EV_ERROR) != 0;
|
|
e[i].eof = eof;
|
|
}
|
|
|
|
return n;
|
|
}
|
|
|
|
static void
|
|
sp_nonblocking(int fd) {
|
|
int flag = fcntl(fd, F_GETFL, 0);
|
|
if ( -1 == flag ) {
|
|
return;
|
|
}
|
|
|
|
fcntl(fd, F_SETFL, flag | O_NONBLOCK);
|
|
}
|
|
|
|
#endif
|