summaryrefslogtreecommitdiff
path: root/databases/flare/files/patch-kqueue-server.cc
blob: 313520a98d93074eb2b7105a271d507a46d86bf7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
--- src/lib/server.cc.orig	2009-10-09 19:08:47.000000000 +0900
+++ src/lib/server.cc	2010-05-30 23:58:14.924160278 +0900
@@ -21,6 +21,9 @@
 #ifdef HAVE_EPOLL
 		_epoll_socket(0),
 #endif
+#ifdef HAVE_KQUEUE
+		_kqueue_socket(-1),
+#endif
 		_back_log(SOMAXCONN) {
 }
 
@@ -55,6 +58,14 @@
 	}
 #endif
 
+#ifdef HAVE_KQUEUE
+	if (this->_kqueue_socket >= 0) {
+		if (::close(this->_kqueue_socket) < 0) {
+			log_err("close() failed: %s (%d) (sock=kqueue)", util::strerror(errno), errno);
+		}
+	}
+#endif
+
 	for (int i = 0; i < this->_listen_socket_index; i++) {
 		int sock = this->_listen_socket[i];
 
@@ -139,6 +150,12 @@
 	}
 #endif
 
+#ifdef HAVE_KQUEUE
+	if (this->_add_kqueue_socket(sock) < 0) {
+		return -1;
+	}
+#endif
+
 	return 0;
 }
 
@@ -195,6 +212,12 @@
 	}
 #endif
 
+#ifdef HAVE_KQUEUE
+	if (this->_add_kqueue_socket(sock) < 0) {
+		return -1;
+	}
+#endif
+
 	return 0;
 }
 
@@ -204,10 +227,14 @@
 vector<shared_connection> server::wait() {
 	vector<shared_connection> connection_list;
 
-#ifdef HAVE_EPOLL
+#if defined(HAVE_EPOLL)
 	const char* poll_type = "epoll_wait";		// just for logging
 	struct epoll_event ev_list[this->max_listen_socket];
 	int n = epoll_wait(this->_epoll_socket, ev_list, this->max_listen_socket, -1);
+#elif defined(HAVE_KQUEUE)
+	const char* poll_type = "kqueue_wait";		// just for logging
+	struct kevent kev[this->max_listen_socket];
+	int n = kevent(this->_kqueue_socket, NULL, 0, kev, this->max_listen_socket, NULL);
 #else
 	const char* poll_type = "select";		// just for logging
 	fd_set fds;
@@ -227,9 +254,12 @@
 	}
 
 	// accpet anyway
-#ifdef HAVE_EPOLL
+#if defined(HAVE_EPOLL)
 	for (int i = 0; i < n; i++) {
 		int listen_socket = ev_list[i].data.fd;
+#elif defined(HAVE_KQUEUE)
+	for (int i = 0; i < n; i++) {
+		int listen_socket = kev[i].ident;
 #else
 	for (int i = 0; i < this->_listen_socket_index; i++) {
 		if (!FD_ISSET(this->_listen_socket[i], &fds)) {
@@ -369,6 +399,32 @@
 	return 0;
 }
 #endif
+
+#ifdef HAVE_KQUEUE
+/**
+ *  add listen socket to kqueue
+ */
+int server::_add_kqueue_socket(int sock) {
+	if (this->_kqueue_socket <= 0) {
+		this->_kqueue_socket = kqueue();
+		if (this->_kqueue_socket < 0) {
+			log_err("kqueue() failed: %s (%s)", util::strerror(errno), errno);
+			return -1;
+		}
+	}
+
+	struct kevent kev;
+	EV_SET(&kev, sock, EVFILT_READ, EV_ADD, 0, 0, NULL);
+	if (kevent(this->_kqueue_socket, &kev, 1, NULL, 0, NULL) < 0 ) {
+		log_err("kevent() failed: %s (%d) (sock=%d)", util::strerror(errno), errno, sock);
+		return -1;
+	} else {
+		log_debug("added listen socket to kevent (kqueue_socket=%d, listen_socket=%d)", this->_kqueue_socket, sock);
+	}
+
+	return 0;
+}
+#endif
 // }}}
 
 // {{{ private methods