Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/external/bsd/wpa/dist/src/utils Add kqueue(2) support.
details: https://anonhg.NetBSD.org/src/rev/2235dc9060bc
branches: trunk
changeset: 343038:2235dc9060bc
user: roy <roy%NetBSD.org@localhost>
date: Wed Jan 20 15:07:52 2016 +0000
description:
Add kqueue(2) support.
diffstat:
external/bsd/wpa/dist/src/utils/eloop.c | 166 ++++++++++++++++++++++++++++---
1 files changed, 150 insertions(+), 16 deletions(-)
diffs (truncated from 341 to 300 lines):
diff -r cd9fbe9d40a0 -r 2235dc9060bc external/bsd/wpa/dist/src/utils/eloop.c
--- a/external/bsd/wpa/dist/src/utils/eloop.c Wed Jan 20 14:43:40 2016 +0000
+++ b/external/bsd/wpa/dist/src/utils/eloop.c Wed Jan 20 15:07:52 2016 +0000
@@ -18,7 +18,12 @@
#error Do not define both of poll and epoll
#endif
-#if !defined(CONFIG_ELOOP_POLL) && !defined(CONFIG_ELOOP_EPOLL)
+#if defined(CONFIG_ELOOP_POLL) && defined(CONFIG_ELOOP_KQUEUE)
+#error Do not define both of poll and kqueue
+#endif
+
+#if !defined(CONFIG_ELOOP_POLL) && !defined(CONFIG_ELOOP_EPOLL) && \
+ !defined(CONFIG_ELOOP_KQUEUE)
#define CONFIG_ELOOP_SELECT
#endif
@@ -30,6 +35,10 @@
#include <sys/epoll.h>
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+#include <sys/event.h>
+#endif /* CONFIG_ELOOP_KQUEUE */
+
struct eloop_sock {
int sock;
void *eloop_data;
@@ -61,7 +70,7 @@
struct eloop_sock_table {
int count;
struct eloop_sock *table;
-#ifdef CONFIG_ELOOP_EPOLL
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
eloop_event_type type;
#else /* CONFIG_ELOOP_EPOLL */
int changed;
@@ -78,13 +87,20 @@
struct pollfd *pollfds;
struct pollfd **pollfds_map;
#endif /* CONFIG_ELOOP_POLL */
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
+ int max_fd;
+ struct eloop_sock *fd_table;
+#endif
#ifdef CONFIG_ELOOP_EPOLL
int epollfd;
int epoll_max_event_num;
- int epoll_max_fd;
- struct eloop_sock *epoll_table;
struct epoll_event *epoll_events;
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ int kqueuefd;
+ int kqueue_nevents;
+ struct kevent *kqueue_events;
+#endif /* CONFIG_ELOOP_KQUEUE */
struct eloop_sock_table readers;
struct eloop_sock_table writers;
struct eloop_sock_table exceptions;
@@ -160,6 +176,14 @@
eloop.writers.type = EVENT_TYPE_WRITE;
eloop.exceptions.type = EVENT_TYPE_EXCEPTION;
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ eloop.kqueuefd = kqueue();
+ if (eloop.kqueuefd < 0) {
+ wpa_printf(MSG_ERROR, "%s: kqueue failed. %s\n",
+ __func__, strerror(errno));
+ return -1;
+ }
+#endif /* CONFIG_ELOOP_KQUEUE */
#ifdef WPA_TRACE
signal(SIGSEGV, eloop_sigsegv_handler);
#endif /* WPA_TRACE */
@@ -176,6 +200,11 @@
struct epoll_event ev, *temp_events;
int next;
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ struct eloop_sock *temp_table;
+ int next, filter;
+ struct kevent ke;
+#endif
struct eloop_sock *tmp;
int new_max_sock;
@@ -211,18 +240,20 @@
eloop.pollfds = n;
}
#endif /* CONFIG_ELOOP_POLL */
-#ifdef CONFIG_ELOOP_EPOLL
- if (new_max_sock >= eloop.epoll_max_fd) {
- next = eloop.epoll_max_fd == 0 ? 16 : eloop.epoll_max_fd * 2;
- temp_table = os_realloc_array(eloop.epoll_table, next,
+#if defined(CONFIG_ELOOP_EPOLL) || defined(CONFIG_ELOOP_KQUEUE)
+ if (new_max_sock >= eloop.max_fd) {
+ next = eloop.max_fd == 0 ? 16 : eloop.max_fd * 2;
+ temp_table = os_realloc_array(eloop.fd_table, next,
sizeof(struct eloop_sock));
if (temp_table == NULL)
return -1;
- eloop.epoll_max_fd = next;
- eloop.epoll_table = temp_table;
+ eloop.max_fd = next;
+ eloop.fd_table = temp_table;
}
+#endif
+#ifdef CONFIG_ELOOP_EPOLL
if (eloop.count + 1 > eloop.epoll_max_event_num) {
next = eloop.epoll_max_event_num == 0 ? 8 :
eloop.epoll_max_event_num * 2;
@@ -238,6 +269,21 @@
eloop.epoll_events = temp_events;
}
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ if (eloop.count + 1 > eloop.kqueue_nevents) {
+ next = eloop.kqueue_nevents == 0 ? 8 : eloop.kqueue_nevents * 2;
+ os_free(eloop.kqueue_events);
+ eloop.kqueue_events = os_malloc(next *
+ sizeof(eloop.kqueue_events));
+ if (eloop.kqueue_events == NULL) {
+ wpa_printf(MSG_ERROR, "%s: malloc for kqueue failed. "
+ "%s\n", __func__, strerror(errno));
+ return -1;
+ }
+
+ eloop.kqueue_nevents = next;
+ }
+#endif /* CONFIG_ELOOP_KQUEUE */
eloop_trace_sock_remove_ref(table);
tmp = os_realloc_array(table->table, table->count + 1,
@@ -256,7 +302,7 @@
table->table = tmp;
eloop.max_sock = new_max_sock;
eloop.count++;
-#ifndef CONFIG_ELOOP_EPOLL
+#if !defined(CONFIG_ELOOP_EPOLL) && !defined(CONFIG_ELOOP_KQUEUE)
table->changed = 1;
#endif /* CONFIG_ELOOP_EPOLL */
eloop_trace_sock_add_ref(table);
@@ -285,9 +331,29 @@
"failed. %s\n", __func__, sock, strerror(errno));
return -1;
}
- os_memcpy(&eloop.epoll_table[sock], &table->table[table->count - 1],
+ os_memcpy(&eloop.fd_table[sock], &table->table[table->count - 1],
sizeof(struct eloop_sock));
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ switch (table->type) {
+ case EVENT_TYPE_READ:
+ filter = EVFILT_READ;
+ break;
+ case EVENT_TYPE_WRITE:
+ filter = EVFILT_WRITE;
+ break;
+ default:
+ filter = 0;
+ }
+ EV_SET(&ke, sock, filter, EV_ADD, 0, 0, NULL);
+ if (kevent(eloop.kqueuefd, &ke, 1, NULL, 0, NULL) == -1) {
+ wpa_printf(MSG_ERROR, "%s: kevent(ADD) for fd=%d "
+ "failed. %s\n", __func__, sock, strerror(errno));
+ return -1;
+ }
+ os_memcpy(&eloop.fd_table[sock], &table->table[table->count - 1],
+ sizeof(struct eloop_sock));
+#endif /* CONFIG_ELOOP_KQUEUE */
return 0;
}
@@ -295,6 +361,9 @@
static void eloop_sock_table_remove_sock(struct eloop_sock_table *table,
int sock)
{
+#ifdef CONFIG_ELOOP_KQUEUE
+ struct kevent ke;
+#endif
int i;
if (table == NULL || table->table == NULL || table->count == 0)
@@ -314,7 +383,7 @@
}
table->count--;
eloop.count--;
-#ifndef CONFIG_ELOOP_EPOLL
+#if !defined(CONFIG_ELOOP_EPOLL) && !defined(CONFIG_ELOOP_KQUEUE)
table->changed = 1;
#endif /* CONFIG_ELOOP_EPOLL */
eloop_trace_sock_add_ref(table);
@@ -324,8 +393,17 @@
"failed. %s\n", __func__, sock, strerror(errno));
return;
}
- os_memset(&eloop.epoll_table[sock], 0, sizeof(struct eloop_sock));
+ os_memset(&eloop.fd_table[sock], 0, sizeof(struct eloop_sock));
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ EV_SET(&ke, sock, 0, EV_DELETE, 0, 0, NULL);
+ if (kevent(eloop.kqueuefd, &ke, 1, NULL, 0, NULL) == -1) {
+ wpa_printf(MSG_ERROR, "%s: kevent(DEL) for fd=%d "
+ "failed. %s\n", __func__, sock, strerror(errno));
+ return;
+ }
+ os_memset(&eloop.fd_table[sock], 0, sizeof(struct eloop_sock));
+#endif /* CONFIG_ELOOP_KQUEUE */
}
@@ -518,7 +596,7 @@
int i;
for (i = 0; i < nfds; i++) {
- table = &eloop.epoll_table[events[i].data.fd];
+ table = &eloop.fd_table[events[i].data.fd];
if (table->handler == NULL)
continue;
table->handler(table->sock, table->eloop_data,
@@ -528,6 +606,22 @@
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+static void eloop_sock_table_dispatch(struct kevent *events, int nfds)
+{
+ struct eloop_sock *table;
+ int i;
+
+ for (i = 0; i < nfds; i++) {
+ table = &eloop.fd_table[events[i].ident];
+ if (table->handler == NULL)
+ continue;
+ table->handler(table->sock, table->eloop_data,
+ table->user_data);
+ }
+}
+#endif /* CONFIG_ELOOP_KQUEUE */
+
static void eloop_sock_table_destroy(struct eloop_sock_table *table)
{
if (table) {
@@ -908,6 +1002,9 @@
#ifdef CONFIG_ELOOP_EPOLL
int timeout_ms = -1;
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ struct timespec ts;
+#endif /* CONFIG_ELOOP_KQUEUE */
int res;
struct os_reltime tv, now;
@@ -938,6 +1035,10 @@
_tv.tv_sec = tv.sec;
_tv.tv_usec = tv.usec;
#endif /* CONFIG_ELOOP_SELECT */
+#ifdef CONFIG_ELOOP_KQUEUE
+ ts.tv_sec = tv.sec;
+ ts.tv_nsec = tv.usec * 1000L;
+#endif /* CONFIG_ELOOP_KQUEUE */
}
#ifdef CONFIG_ELOOP_POLL
@@ -963,6 +1064,15 @@
eloop.count, timeout_ms);
}
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ if (eloop.count == 0) {
+ res = 0;
+ } else {
+ res = kevent(eloop.kqueuefd, NULL, 0,
+ eloop.kqueue_events, eloop.kqueue_nevents,
+ timeout ? &ts : NULL);
+ }
+#endif /* CONFIG_ELOOP_KQUEUE */
if (res < 0 && errno != EINTR && errno != 0) {
wpa_printf(MSG_ERROR, "eloop: %s: %s",
#ifdef CONFIG_ELOOP_POLL
@@ -974,6 +1084,10 @@
#ifdef CONFIG_ELOOP_EPOLL
"epoll"
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ "kqueue"
+#endif /* CONFIG_ELOOP_EKQUEUE */
+
, strerror(errno));
goto out;
}
@@ -1011,6 +1125,9 @@
#ifdef CONFIG_ELOOP_EPOLL
eloop_sock_table_dispatch(eloop.epoll_events, res);
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef CONFIG_ELOOP_KQUEUE
+ eloop_sock_table_dispatch(eloop.kqueue_events, res);
Home |
Main Index |
Thread Index |
Old Index