Skip to content

Commit a39a6ca

Browse files
author
jr3074
committedOct 15, 2011
Adding libev. Beginnings of autoconf.
1 parent bc0b6a8 commit a39a6ca

17 files changed

+6581
-12
lines changed
 

‎common.c

+1-3
Original file line numberDiff line numberDiff line change
@@ -135,12 +135,10 @@ int open_net(short port) {
135135
struct sockaddr_in me;
136136
int s, rc;
137137

138-
#ifdef HAVE_LZO_H
139138
if(lzo_init() != LZO_E_OK) {
140139
logit(1, "Error initialzing LZO library.");
141140
return -1;
142141
}
143-
#endif
144142

145143
s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
146144
if(s < 0) {
@@ -161,7 +159,7 @@ int open_net(short port) {
161159
return -1;
162160
}
163161

164-
#ifdef HAVE_IP_MTU_DISCOVER
162+
#ifdef IP_MTU_DISCOVER
165163
rc = IP_PMTUDISC_DO;
166164
setsockopt(s, IPPROTO_UDP, IP_MTU_DISCOVER, &rc, sizeof(int));
167165
#endif

‎configure.in

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
AC_INIT
2+
AC_INIT_AUTOMAKE([gssvpn,0.5])
3+
AC_CONFIG_HEADERS([config.h libev/config.h])
4+
5+
AC_PROG_INSTALL
6+
AC_PROG_LIBTOOL
7+
8+
AC_INCLUDES_DEFAULT
9+
AC_CHECK_HEADERS([fcntl.h net/if.h netdb.h netinit/in.h pwd.h
10+
sys/ioctl syslog.h net/ethernet.h arpa/inet.h])
11+
AC_CHECK_HEADER([gssapi/gssapi.h], [],
12+
[AC_MSG_ERROR([Requires GSSAPI header])]))
13+
AC_CHECK_HEADER([linux/if_tun.h], [AC_DEFINE([HAVE_IF_TUN])], [], [])
14+
15+
AC_SEARCH_LIBS([gss_accept_sec_context], [gssapi gssapi_krb5])
16+
AC_SEARCH_LIBS([gethostbyname], [resolve nsl])
17+
AC_SEARCH_LIBS([socket], [socket])
18+
19+
AC_FUNC_FORK
20+
AC_FUNC_MALLOC
21+
AC_FUNC_MEMCMP
22+
23+
AC_CHECK_FUNCS([gss_accept_sec_context gss_init_sec_context
24+
gss_wrap gss_unwrap gss_del_sec_context gss_release_buffer
25+
gss_acquire_creds], [], [AC_MSG_ERROR([Missing GSSAPI functions])])
26+
AC_CHECK_FUNCS([ioctl setsockopt bind recvfrom sendto socket])
27+
28+
m4_include([libev/libev.m4])
29+
30+
AC_CHECK_LIBS([gss_accept_sec_context], [gssapi gssapi_krb5])
31+
32+
AC_CONFIG_FILES([Makefile])
33+
AC_OUTPUT

‎gssvpn.c

+9-6
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ int do_netinit(struct ev_loop * loop, gss_buffer_desc * in) {
5252
return -1;
5353
}
5454

55-
memcpy(&ni, in.value, in.length);
55+
memcpy(&ni, in->value, in->length);
5656
memset(&ifr, 0, sizeof(ifr));
5757
strncpy(ifr.ifr_name, tapdev, IFNAMSIZ);
5858
ifr.ifr_addr.sa_family = AF_LINK;
@@ -70,21 +70,24 @@ int do_netinit(struct ev_loop * loop, gss_buffer_desc * in) {
7070
if(!netinit_util) {
7171
if(verbose)
7272
logit(-1, "Received %d bytes of netinit data, but no netinit util.",
73-
ni.length);
73+
ni.len);
7474
return 0;
7575
}
7676

7777
pid = fork();
7878
if(pid == 0) {
79-
char * lock = ni.payload;
80-
char ** args = malloc(sizeof(char*)) * 256;
79+
uint8_t * lock = ni.payload;
80+
char ** args = malloc(sizeof(char*)* 256);
8181
int argcount = 0;
82+
OM_uint32 min;
83+
8284
close(tapfd);
8385
close(netfd);
8486
gss_delete_sec_context(&min, &context, GSS_C_NO_BUFFER);
8587

88+
args[argcount++] = netinit_util;
8689
while(lock - ni.payload < ni.len && argcount < 255) {
87-
char * save = lock;
90+
uint8_t * save = lock;
8891
while(*lock != '\n' && lock - ni.payload < ni.len) lock++;
8992
if(*lock == '\n') {
9093
*lock = 0;
@@ -166,7 +169,7 @@ void netfd_read_cb(struct ev_loop * loop, ev_io * ios, int revents) {
166169
return;
167170
}
168171
else if(pac == PAC_NETINIT)
169-
do_netinit(&packet);
172+
do_netinit(loop, &packet);
170173
else if(pac == PAC_GSSINIT)
171174
do_gssinit(&packet);
172175
else if(pac == PAC_SHUTDOWN)

‎gssvpnd.c

+10-3
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ void netinit_read_cb(struct ev_loop * loop, ev_io * ios, int revents) {
118118
memcpy(c->ni->payload + c->ni->len, buf + offset, tocopy);
119119
c->ni->len += tocopy;
120120
if(c->ni->len == sizeof(c->ni->payload)) {
121-
ev_io_stop(loop, &ios);
121+
ev_io_stop(loop, ios);
122122
return;
123123
}
124124
}
@@ -219,7 +219,7 @@ void handle_netinit(struct ev_loop * loop, struct conn * client) {
219219
pid_t pid;
220220
int fds[2];
221221

222-
if(client->ci)
222+
if(client->ni)
223223
return;
224224

225225
if(!netinit_util) {
@@ -261,7 +261,14 @@ void handle_netinit(struct ev_loop * loop, struct conn * client) {
261261
pid = fork();
262262
if(pid == 0) {
263263
char portstr[6];
264+
char * filename = netinit_util + (strlen(netinit_util) - 1);
264265
uint8_t i;
266+
OM_uint32 min;
267+
268+
while(*filename != '/' && filename != netinit_util)
269+
filename--;
270+
if(*filename == '/')
271+
filename++;
265272

266273
sprintf(portstr, "%d", client->addr.sin_port);
267274
close(fds[0]);
@@ -279,7 +286,7 @@ void handle_netinit(struct ev_loop * loop, struct conn * client) {
279286
}
280287

281288
dup2(fds[1], fileno(stdout));
282-
if(execl(netinit_util, netinit_util, client->princname,
289+
if(execl(netinit_util, filename, client->princname,
283290
client->ipstr, portstr, NULL) < 0)
284291
exit(-1);
285292
}

‎libev/LICENSE

+36
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are
5+
met:
6+
7+
* Redistributions of source code must retain the above copyright
8+
notice, this list of conditions and the following disclaimer.
9+
10+
* Redistributions in binary form must reproduce the above
11+
copyright notice, this list of conditions and the following
12+
disclaimer in the documentation and/or other materials provided
13+
with the distribution.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16+
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17+
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18+
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19+
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
20+
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22+
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23+
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24+
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26+
27+
Alternatively, the contents of this package may be used under the terms
28+
of the GNU General Public License ("GPL") version 2 or any later version,
29+
in which case the provisions of the GPL are applicable instead of the
30+
above. If you wish to allow the use of your version of this package only
31+
under the terms of the GPL and not to allow others to use your version of
32+
this file under the BSD license, indicate your decision by deleting the
33+
provisions above and replace them with the notice and other provisions
34+
required by the GPL in this and the other files of this package. If you do
35+
not delete the provisions above, a recipient may use your version of this
36+
file under either the BSD or the GPL.

‎libev/README

+58
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
libev is a high-performance event loop/event model with lots of features.
2+
(see benchmark at http://libev.schmorp.de/bench.html)
3+
4+
5+
ABOUT
6+
7+
Homepage: http://software.schmorp.de/pkg/libev
8+
Mailinglist: libev@lists.schmorp.de
9+
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
10+
Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
11+
12+
Libev is modelled (very losely) after libevent and the Event perl
13+
module, but is faster, scales better and is more correct, and also more
14+
featureful. And also smaller. Yay.
15+
16+
Some of the specialties of libev not commonly found elsewhere are:
17+
18+
- extensive and detailed, readable documentation (not doxygen garbage).
19+
- fully supports fork, can detect fork in various ways and automatically
20+
re-arms kernel mechanisms that do not support fork.
21+
- highly optimised select, poll, epoll, kqueue and event ports backends.
22+
- filesystem object (path) watching (with optional linux inotify support).
23+
- wallclock-based times (using absolute time, cron-like).
24+
- relative timers/timeouts (handle time jumps).
25+
- fast intra-thread communication between multiple
26+
event loops (with optional fast linux eventfd backend).
27+
- extremely easy to embed.
28+
- very small codebase, no bloated library.
29+
- fully extensible by being able to plug into the event loop,
30+
integrate other event loops, integrate other event loop users.
31+
- very little memory use (small watchers, small event loop data).
32+
- optional C++ interface allowing method and function callbacks
33+
at no extra memory or runtime overhead.
34+
- optional Perl interface with similar characteristics (capable
35+
of running Glib/Gtk2 on libev, interfaces with Net::SNMP and
36+
libadns).
37+
- support for other languages (multiple C++ interfaces, D, Ruby,
38+
Python) available from third-parties.
39+
40+
Examples of programs that embed libev: the EV perl module,
41+
rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the Deliantra MMORPG
42+
server (http://www.deliantra.net/), Rubinius (a next-generation Ruby
43+
VM), the Ebb web server, the Rev event toolkit.
44+
45+
46+
CONTRIBUTORS
47+
48+
libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
49+
50+
The following people sent in patches or made other noteworthy
51+
contributions to the design (for minor patches, see the Changes
52+
file. If I forgot to include you, please shout at me, it was an
53+
accident):
54+
55+
W.C.A. Wijngaards
56+
Christopher Layne
57+
Chris Brody
58+

‎libev/ev.c

+3,913
Large diffs are not rendered by default.

‎libev/ev.h

+829
Large diffs are not rendered by default.

‎libev/ev_epoll.c

+266
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,266 @@
1+
/*
2+
* libev epoll fd activity backend
3+
*
4+
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modifica-
8+
* tion, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26+
* OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* the GNU General Public License ("GPL") version 2 or any later version,
30+
* in which case the provisions of the GPL are applicable instead of
31+
* the above. If you wish to allow the use of your version of this file
32+
* only under the terms of the GPL and not to allow others to use your
33+
* version of this file under the BSD license, indicate your decision
34+
* by deleting the provisions above and replace them with the notice
35+
* and other provisions required by the GPL. If you do not delete the
36+
* provisions above, a recipient may use your version of this file under
37+
* either the BSD or the GPL.
38+
*/
39+
40+
/*
41+
* general notes about epoll:
42+
*
43+
* a) epoll silently removes fds from the fd set. as nothing tells us
44+
* that an fd has been removed otherwise, we have to continually
45+
* "rearm" fds that we suspect *might* have changed (same
46+
* problem with kqueue, but much less costly there).
47+
* b) the fact that ADD != MOD creates a lot of extra syscalls due to a)
48+
* and seems not to have any advantage.
49+
* c) the inability to handle fork or file descriptors (think dup)
50+
* limits the applicability over poll, so this is not a generic
51+
* poll replacement.
52+
* d) epoll doesn't work the same as select with many file descriptors
53+
* (such as files). while not critical, no other advanced interface
54+
* seems to share this (rather non-unixy) limitation.
55+
* e) epoll claims to be embeddable, but in practise you never get
56+
* a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32).
57+
* f) epoll_ctl returning EPERM means the fd is always ready.
58+
*
59+
* lots of "weird code" and complication handling in this file is due
60+
* to these design problems with epoll, as we try very hard to avoid
61+
* epoll_ctl syscalls for common usage patterns and handle the breakage
62+
* ensuing from receiving events for closed and otherwise long gone
63+
* file descriptors.
64+
*/
65+
66+
#include <sys/epoll.h>
67+
68+
#define EV_EMASK_EPERM 0x80
69+
70+
static void
71+
epoll_modify (EV_P_ int fd, int oev, int nev)
72+
{
73+
struct epoll_event ev;
74+
unsigned char oldmask;
75+
76+
/*
77+
* we handle EPOLL_CTL_DEL by ignoring it here
78+
* on the assumption that the fd is gone anyways
79+
* if that is wrong, we have to handle the spurious
80+
* event in epoll_poll.
81+
* if the fd is added again, we try to ADD it, and, if that
82+
* fails, we assume it still has the same eventmask.
83+
*/
84+
if (!nev)
85+
return;
86+
87+
oldmask = anfds [fd].emask;
88+
anfds [fd].emask = nev;
89+
90+
/* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */
91+
ev.data.u64 = (uint64_t)(uint32_t)fd
92+
| ((uint64_t)(uint32_t)++anfds [fd].egen << 32);
93+
ev.events = (nev & EV_READ ? EPOLLIN : 0)
94+
| (nev & EV_WRITE ? EPOLLOUT : 0);
95+
96+
if (expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev)))
97+
return;
98+
99+
if (expect_true (errno == ENOENT))
100+
{
101+
/* if ENOENT then the fd went away, so try to do the right thing */
102+
if (!nev)
103+
goto dec_egen;
104+
105+
if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev))
106+
return;
107+
}
108+
else if (expect_true (errno == EEXIST))
109+
{
110+
/* EEXIST means we ignored a previous DEL, but the fd is still active */
111+
/* if the kernel mask is the same as the new mask, we assume it hasn't changed */
112+
if (oldmask == nev)
113+
goto dec_egen;
114+
115+
if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
116+
return;
117+
}
118+
else if (expect_true (errno == EPERM))
119+
{
120+
/* EPERM means the fd is always ready, but epoll is too snobbish */
121+
/* to handle it, unlike select or poll. */
122+
anfds [fd].emask = EV_EMASK_EPERM;
123+
124+
/* add fd to epoll_eperms, if not already inside */
125+
if (!(oldmask & EV_EMASK_EPERM))
126+
{
127+
array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2);
128+
epoll_eperms [epoll_epermcnt++] = fd;
129+
}
130+
131+
return;
132+
}
133+
134+
fd_kill (EV_A_ fd);
135+
136+
dec_egen:
137+
/* we didn't successfully call epoll_ctl, so decrement the generation counter again */
138+
--anfds [fd].egen;
139+
}
140+
141+
static void
142+
epoll_poll (EV_P_ ev_tstamp timeout)
143+
{
144+
int i;
145+
int eventcnt;
146+
147+
/* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */
148+
/* the default libev max wait time, however. */
149+
EV_RELEASE_CB;
150+
eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax,
151+
epoll_epermcnt ? 0 : ev_timeout_to_ms (timeout));
152+
EV_ACQUIRE_CB;
153+
154+
if (expect_false (eventcnt < 0))
155+
{
156+
if (errno != EINTR)
157+
ev_syserr ("(libev) epoll_wait");
158+
159+
return;
160+
}
161+
162+
for (i = 0; i < eventcnt; ++i)
163+
{
164+
struct epoll_event *ev = epoll_events + i;
165+
166+
int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */
167+
int want = anfds [fd].events;
168+
int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
169+
| (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
170+
171+
/* check for spurious notification */
172+
/* we assume that fd is always in range, as we never shrink the anfds array */
173+
if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
174+
{
175+
/* recreate kernel state */
176+
postfork = 1;
177+
continue;
178+
}
179+
180+
if (expect_false (got & ~want))
181+
{
182+
anfds [fd].emask = want;
183+
184+
/* we received an event but are not interested in it, try mod or del */
185+
/* I don't think we ever need MOD, but let's handle it anyways */
186+
ev->events = (want & EV_READ ? EPOLLIN : 0)
187+
| (want & EV_WRITE ? EPOLLOUT : 0);
188+
189+
/* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */
190+
/* which is fortunately easy to do for us. */
191+
if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev))
192+
{
193+
postfork = 1; /* an error occurred, recreate kernel state */
194+
continue;
195+
}
196+
}
197+
198+
fd_event (EV_A_ fd, got);
199+
}
200+
201+
/* if the receive array was full, increase its size */
202+
if (expect_false (eventcnt == epoll_eventmax))
203+
{
204+
ev_free (epoll_events);
205+
epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1);
206+
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
207+
}
208+
209+
/* now synthesize events for all fds where epoll fails, while select works... */
210+
for (i = epoll_epermcnt; i--; )
211+
{
212+
int fd = epoll_eperms [i];
213+
unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE);
214+
215+
if (anfds [fd].emask & EV_EMASK_EPERM && events)
216+
fd_event (EV_A_ fd, events);
217+
else
218+
epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
219+
}
220+
}
221+
222+
int inline_size
223+
epoll_init (EV_P_ int flags)
224+
{
225+
#ifdef EPOLL_CLOEXEC
226+
backend_fd = epoll_create1 (EPOLL_CLOEXEC);
227+
228+
if (backend_fd <= 0)
229+
#endif
230+
backend_fd = epoll_create (256);
231+
232+
if (backend_fd < 0)
233+
return 0;
234+
235+
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
236+
237+
backend_fudge = 0.; /* kernel sources seem to indicate this to be zero */
238+
backend_modify = epoll_modify;
239+
backend_poll = epoll_poll;
240+
241+
epoll_eventmax = 64; /* initial number of events receivable per poll */
242+
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
243+
244+
return EVBACKEND_EPOLL;
245+
}
246+
247+
void inline_size
248+
epoll_destroy (EV_P)
249+
{
250+
ev_free (epoll_events);
251+
array_free (epoll_eperm, EMPTY);
252+
}
253+
254+
void inline_size
255+
epoll_fork (EV_P)
256+
{
257+
close (backend_fd);
258+
259+
while ((backend_fd = epoll_create (256)) < 0)
260+
ev_syserr ("(libev) epoll_create");
261+
262+
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
263+
264+
fd_rearm_all (EV_A);
265+
}
266+

‎libev/ev_kqueue.c

+198
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
/*
2+
* libev kqueue backend
3+
*
4+
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modifica-
8+
* tion, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26+
* OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* the GNU General Public License ("GPL") version 2 or any later version,
30+
* in which case the provisions of the GPL are applicable instead of
31+
* the above. If you wish to allow the use of your version of this file
32+
* only under the terms of the GPL and not to allow others to use your
33+
* version of this file under the BSD license, indicate your decision
34+
* by deleting the provisions above and replace them with the notice
35+
* and other provisions required by the GPL. If you do not delete the
36+
* provisions above, a recipient may use your version of this file under
37+
* either the BSD or the GPL.
38+
*/
39+
40+
#include <sys/types.h>
41+
#include <sys/time.h>
42+
#include <sys/event.h>
43+
#include <string.h>
44+
#include <errno.h>
45+
46+
void inline_speed
47+
kqueue_change (EV_P_ int fd, int filter, int flags, int fflags)
48+
{
49+
++kqueue_changecnt;
50+
array_needsize (struct kevent, kqueue_changes, kqueue_changemax, kqueue_changecnt, EMPTY2);
51+
52+
EV_SET (&kqueue_changes [kqueue_changecnt - 1], fd, filter, flags, fflags, 0, 0);
53+
}
54+
55+
/* OS X at least needs this */
56+
#ifndef EV_ENABLE
57+
# define EV_ENABLE 0
58+
#endif
59+
#ifndef NOTE_EOF
60+
# define NOTE_EOF 0
61+
#endif
62+
63+
static void
64+
kqueue_modify (EV_P_ int fd, int oev, int nev)
65+
{
66+
if (oev != nev)
67+
{
68+
if (oev & EV_READ)
69+
kqueue_change (EV_A_ fd, EVFILT_READ , EV_DELETE, 0);
70+
71+
if (oev & EV_WRITE)
72+
kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_DELETE, 0);
73+
}
74+
75+
/* to detect close/reopen reliably, we have to re-add */
76+
/* event requests even when oev == nev */
77+
78+
if (nev & EV_READ)
79+
kqueue_change (EV_A_ fd, EVFILT_READ , EV_ADD | EV_ENABLE, NOTE_EOF);
80+
81+
if (nev & EV_WRITE)
82+
kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, NOTE_EOF);
83+
}
84+
85+
static void
86+
kqueue_poll (EV_P_ ev_tstamp timeout)
87+
{
88+
int res, i;
89+
struct timespec ts;
90+
91+
/* need to resize so there is enough space for errors */
92+
if (kqueue_changecnt > kqueue_eventmax)
93+
{
94+
ev_free (kqueue_events);
95+
kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_changecnt);
96+
kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
97+
}
98+
99+
EV_RELEASE_CB;
100+
EV_TS_SET (ts, timeout);
101+
res = kevent (backend_fd, kqueue_changes, kqueue_changecnt, kqueue_events, kqueue_eventmax, &ts);
102+
EV_ACQUIRE_CB;
103+
kqueue_changecnt = 0;
104+
105+
if (expect_false (res < 0))
106+
{
107+
if (errno != EINTR)
108+
ev_syserr ("(libev) kevent");
109+
110+
return;
111+
}
112+
113+
for (i = 0; i < res; ++i)
114+
{
115+
int fd = kqueue_events [i].ident;
116+
117+
if (expect_false (kqueue_events [i].flags & EV_ERROR))
118+
{
119+
int err = kqueue_events [i].data;
120+
121+
/* we are only interested in errors for fds that we are interested in :) */
122+
if (anfds [fd].events)
123+
{
124+
if (err == ENOENT) /* resubmit changes on ENOENT */
125+
kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
126+
else if (err == EBADF) /* on EBADF, we re-check the fd */
127+
{
128+
if (fd_valid (fd))
129+
kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
130+
else
131+
fd_kill (EV_A_ fd);
132+
}
133+
else /* on all other errors, we error out on the fd */
134+
fd_kill (EV_A_ fd);
135+
}
136+
}
137+
else
138+
fd_event (
139+
EV_A_
140+
fd,
141+
kqueue_events [i].filter == EVFILT_READ ? EV_READ
142+
: kqueue_events [i].filter == EVFILT_WRITE ? EV_WRITE
143+
: 0
144+
);
145+
}
146+
147+
if (expect_false (res == kqueue_eventmax))
148+
{
149+
ev_free (kqueue_events);
150+
kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_eventmax + 1);
151+
kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
152+
}
153+
}
154+
155+
int inline_size
156+
kqueue_init (EV_P_ int flags)
157+
{
158+
/* Initialize the kernel queue */
159+
if ((backend_fd = kqueue ()) < 0)
160+
return 0;
161+
162+
fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
163+
164+
backend_fudge = 0.;
165+
backend_modify = kqueue_modify;
166+
backend_poll = kqueue_poll;
167+
168+
kqueue_eventmax = 64; /* initial number of events receivable per poll */
169+
kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
170+
171+
kqueue_changes = 0;
172+
kqueue_changemax = 0;
173+
kqueue_changecnt = 0;
174+
175+
return EVBACKEND_KQUEUE;
176+
}
177+
178+
void inline_size
179+
kqueue_destroy (EV_P)
180+
{
181+
ev_free (kqueue_events);
182+
ev_free (kqueue_changes);
183+
}
184+
185+
void inline_size
186+
kqueue_fork (EV_P)
187+
{
188+
close (backend_fd);
189+
190+
while ((backend_fd = kqueue ()) < 0)
191+
ev_syserr ("(libev) kqueue");
192+
193+
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
194+
195+
/* re-register interest in fds */
196+
fd_rearm_all (EV_A);
197+
}
198+

‎libev/ev_poll.c

+148
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* libev poll fd activity backend
3+
*
4+
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modifica-
8+
* tion, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26+
* OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* the GNU General Public License ("GPL") version 2 or any later version,
30+
* in which case the provisions of the GPL are applicable instead of
31+
* the above. If you wish to allow the use of your version of this file
32+
* only under the terms of the GPL and not to allow others to use your
33+
* version of this file under the BSD license, indicate your decision
34+
* by deleting the provisions above and replace them with the notice
35+
* and other provisions required by the GPL. If you do not delete the
36+
* provisions above, a recipient may use your version of this file under
37+
* either the BSD or the GPL.
38+
*/
39+
40+
#include <poll.h>
41+
42+
void inline_size
43+
pollidx_init (int *base, int count)
44+
{
45+
/* consider using memset (.., -1, ...), which is practically guaranteed
46+
* to work on all systems implementing poll */
47+
while (count--)
48+
*base++ = -1;
49+
}
50+
51+
static void
52+
poll_modify (EV_P_ int fd, int oev, int nev)
53+
{
54+
int idx;
55+
56+
if (oev == nev)
57+
return;
58+
59+
array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init);
60+
61+
idx = pollidxs [fd];
62+
63+
if (idx < 0) /* need to allocate a new pollfd */
64+
{
65+
pollidxs [fd] = idx = pollcnt++;
66+
array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
67+
polls [idx].fd = fd;
68+
}
69+
70+
assert (polls [idx].fd == fd);
71+
72+
if (nev)
73+
polls [idx].events =
74+
(nev & EV_READ ? POLLIN : 0)
75+
| (nev & EV_WRITE ? POLLOUT : 0);
76+
else /* remove pollfd */
77+
{
78+
pollidxs [fd] = -1;
79+
80+
if (expect_true (idx < --pollcnt))
81+
{
82+
polls [idx] = polls [pollcnt];
83+
pollidxs [polls [idx].fd] = idx;
84+
}
85+
}
86+
}
87+
88+
static void
89+
poll_poll (EV_P_ ev_tstamp timeout)
90+
{
91+
struct pollfd *p;
92+
int res;
93+
94+
EV_RELEASE_CB;
95+
res = poll (polls, pollcnt, ev_timeout_to_ms (timeout));
96+
EV_ACQUIRE_CB;
97+
98+
if (expect_false (res < 0))
99+
{
100+
if (errno == EBADF)
101+
fd_ebadf (EV_A);
102+
else if (errno == ENOMEM && !syserr_cb)
103+
fd_enomem (EV_A);
104+
else if (errno != EINTR)
105+
ev_syserr ("(libev) poll");
106+
}
107+
else
108+
for (p = polls; res; ++p)
109+
{
110+
assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
111+
112+
if (expect_false (p->revents)) /* this expect is debatable */
113+
{
114+
--res;
115+
116+
if (expect_false (p->revents & POLLNVAL))
117+
fd_kill (EV_A_ p->fd);
118+
else
119+
fd_event (
120+
EV_A_
121+
p->fd,
122+
(p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
123+
| (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
124+
);
125+
}
126+
}
127+
}
128+
129+
int inline_size
130+
poll_init (EV_P_ int flags)
131+
{
132+
backend_fudge = 0.; /* posix says this is zero */
133+
backend_modify = poll_modify;
134+
backend_poll = poll_poll;
135+
136+
pollidxs = 0; pollidxmax = 0;
137+
polls = 0; pollmax = 0; pollcnt = 0;
138+
139+
return EVBACKEND_POLL;
140+
}
141+
142+
void inline_size
143+
poll_destroy (EV_P)
144+
{
145+
ev_free (pollidxs);
146+
ev_free (polls);
147+
}
148+

‎libev/ev_port.c

+179
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
/*
2+
* libev solaris event port backend
3+
*
4+
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modifica-
8+
* tion, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26+
* OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* the GNU General Public License ("GPL") version 2 or any later version,
30+
* in which case the provisions of the GPL are applicable instead of
31+
* the above. If you wish to allow the use of your version of this file
32+
* only under the terms of the GPL and not to allow others to use your
33+
* version of this file under the BSD license, indicate your decision
34+
* by deleting the provisions above and replace them with the notice
35+
* and other provisions required by the GPL. If you do not delete the
36+
* provisions above, a recipient may use your version of this file under
37+
* either the BSD or the GPL.
38+
*/
39+
40+
/* useful reading:
41+
*
42+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6268715 (random results)
43+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6455223 (just totally broken)
44+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6873782 (manpage ETIME)
45+
* http://bugs.opensolaris.org/view_bug.do?bug_id=6874410 (implementation ETIME)
46+
* http://www.mail-archive.com/networking-discuss@opensolaris.org/msg11898.html ETIME vs. nget
47+
* http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/event_port.c (libc)
48+
* http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325 (kernel)
49+
*/
50+
51+
#include <sys/types.h>
52+
#include <sys/time.h>
53+
#include <poll.h>
54+
#include <port.h>
55+
#include <string.h>
56+
#include <errno.h>
57+
58+
void inline_speed
59+
port_associate_and_check (EV_P_ int fd, int ev)
60+
{
61+
if (0 >
62+
port_associate (
63+
backend_fd, PORT_SOURCE_FD, fd,
64+
(ev & EV_READ ? POLLIN : 0)
65+
| (ev & EV_WRITE ? POLLOUT : 0),
66+
0
67+
)
68+
)
69+
{
70+
if (errno == EBADFD)
71+
fd_kill (EV_A_ fd);
72+
else
73+
ev_syserr ("(libev) port_associate");
74+
}
75+
}
76+
77+
static void
78+
port_modify (EV_P_ int fd, int oev, int nev)
79+
{
80+
/* we need to reassociate no matter what, as closes are
81+
* once more silently being discarded.
82+
*/
83+
if (!nev)
84+
{
85+
if (oev)
86+
port_dissociate (backend_fd, PORT_SOURCE_FD, fd);
87+
}
88+
else
89+
port_associate_and_check (EV_A_ fd, nev);
90+
}
91+
92+
static void
93+
port_poll (EV_P_ ev_tstamp timeout)
94+
{
95+
int res, i;
96+
struct timespec ts;
97+
uint_t nget = 1;
98+
99+
/* we initialise this to something we will skip in the loop, as */
100+
/* port_getn can return with nget unchanged, but no indication */
101+
/* whether it was the original value or has been updated :/ */
102+
port_events [0].portev_source = 0;
103+
104+
EV_RELEASE_CB;
105+
EV_TS_SET (ts, timeout);
106+
res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts);
107+
EV_ACQUIRE_CB;
108+
109+
/* port_getn may or may not set nget on error */
110+
/* so we rely on port_events [0].portev_source not being updated */
111+
if (res == -1 && errno != ETIME && errno != EINTR)
112+
ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)");
113+
114+
for (i = 0; i < nget; ++i)
115+
{
116+
if (port_events [i].portev_source == PORT_SOURCE_FD)
117+
{
118+
int fd = port_events [i].portev_object;
119+
120+
fd_event (
121+
EV_A_
122+
fd,
123+
(port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
124+
| (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
125+
);
126+
127+
fd_change (EV_A_ fd, EV__IOFDSET);
128+
}
129+
}
130+
131+
if (expect_false (nget == port_eventmax))
132+
{
133+
ev_free (port_events);
134+
port_eventmax = array_nextsize (sizeof (port_event_t), port_eventmax, port_eventmax + 1);
135+
port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
136+
}
137+
}
138+
139+
int inline_size
140+
port_init (EV_P_ int flags)
141+
{
142+
/* Initialize the kernel queue */
143+
if ((backend_fd = port_create ()) < 0)
144+
return 0;
145+
146+
assert (("libev: PORT_SOURCE_FD must not be zero", PORT_SOURCE_FD));
147+
148+
fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
149+
150+
backend_fudge = 1e-3; /* needed to compensate for port_getn returning early */
151+
backend_modify = port_modify;
152+
backend_poll = port_poll;
153+
154+
port_eventmax = 64; /* initial number of events receivable per poll */
155+
port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
156+
157+
return EVBACKEND_PORT;
158+
}
159+
160+
void inline_size
161+
port_destroy (EV_P)
162+
{
163+
ev_free (port_events);
164+
}
165+
166+
void inline_size
167+
port_fork (EV_P)
168+
{
169+
close (backend_fd);
170+
171+
while ((backend_fd = port_create ()) < 0)
172+
ev_syserr ("(libev) port");
173+
174+
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
175+
176+
/* re-register interest in fds */
177+
fd_rearm_all (EV_A);
178+
}
179+

‎libev/ev_select.c

+310
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,310 @@
1+
/*
2+
* libev select fd activity backend
3+
*
4+
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libev@schmorp.de>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modifica-
8+
* tion, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26+
* OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* the GNU General Public License ("GPL") version 2 or any later version,
30+
* in which case the provisions of the GPL are applicable instead of
31+
* the above. If you wish to allow the use of your version of this file
32+
* only under the terms of the GPL and not to allow others to use your
33+
* version of this file under the BSD license, indicate your decision
34+
* by deleting the provisions above and replace them with the notice
35+
* and other provisions required by the GPL. If you do not delete the
36+
* provisions above, a recipient may use your version of this file under
37+
* either the BSD or the GPL.
38+
*/
39+
40+
#ifndef _WIN32
41+
/* for unix systems */
42+
# include <inttypes.h>
43+
# ifndef __hpux
44+
/* for REAL unix systems */
45+
# include <sys/select.h>
46+
# endif
47+
#endif
48+
49+
#ifndef EV_SELECT_USE_FD_SET
50+
# ifdef NFDBITS
51+
# define EV_SELECT_USE_FD_SET 0
52+
# else
53+
# define EV_SELECT_USE_FD_SET 1
54+
# endif
55+
#endif
56+
57+
#if EV_SELECT_IS_WINSOCKET
58+
# undef EV_SELECT_USE_FD_SET
59+
# define EV_SELECT_USE_FD_SET 1
60+
# undef NFDBITS
61+
# define NFDBITS 0
62+
#endif
63+
64+
#if !EV_SELECT_USE_FD_SET
65+
# define NFDBYTES (NFDBITS / 8)
66+
#endif
67+
68+
#include <string.h>
69+
70+
static void
71+
select_modify (EV_P_ int fd, int oev, int nev)
72+
{
73+
if (oev == nev)
74+
return;
75+
76+
{
77+
#if EV_SELECT_USE_FD_SET
78+
79+
#if EV_SELECT_IS_WINSOCKET
80+
SOCKET handle = anfds [fd].handle;
81+
#else
82+
int handle = fd;
83+
#endif
84+
85+
assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE));
86+
87+
/* FD_SET is broken on windows (it adds the fd to a set twice or more,
88+
* which eventually leads to overflows). Need to call it only on changes.
89+
*/
90+
#if EV_SELECT_IS_WINSOCKET
91+
if ((oev ^ nev) & EV_READ)
92+
#endif
93+
if (nev & EV_READ)
94+
FD_SET (handle, (fd_set *)vec_ri);
95+
else
96+
FD_CLR (handle, (fd_set *)vec_ri);
97+
98+
#if EV_SELECT_IS_WINSOCKET
99+
if ((oev ^ nev) & EV_WRITE)
100+
#endif
101+
if (nev & EV_WRITE)
102+
FD_SET (handle, (fd_set *)vec_wi);
103+
else
104+
FD_CLR (handle, (fd_set *)vec_wi);
105+
106+
#else
107+
108+
int word = fd / NFDBITS;
109+
fd_mask mask = 1UL << (fd % NFDBITS);
110+
111+
if (expect_false (vec_max <= word))
112+
{
113+
int new_max = word + 1;
114+
115+
vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
116+
vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
117+
vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
118+
vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
119+
#ifdef _WIN32
120+
vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
121+
#endif
122+
123+
for (; vec_max < new_max; ++vec_max)
124+
((fd_mask *)vec_ri) [vec_max] =
125+
((fd_mask *)vec_wi) [vec_max] = 0;
126+
}
127+
128+
((fd_mask *)vec_ri) [word] |= mask;
129+
if (!(nev & EV_READ))
130+
((fd_mask *)vec_ri) [word] &= ~mask;
131+
132+
((fd_mask *)vec_wi) [word] |= mask;
133+
if (!(nev & EV_WRITE))
134+
((fd_mask *)vec_wi) [word] &= ~mask;
135+
#endif
136+
}
137+
}
138+
139+
static void
140+
select_poll (EV_P_ ev_tstamp timeout)
141+
{
142+
struct timeval tv;
143+
int res;
144+
int fd_setsize;
145+
146+
EV_RELEASE_CB;
147+
EV_TV_SET (tv, timeout);
148+
149+
#if EV_SELECT_USE_FD_SET
150+
fd_setsize = sizeof (fd_set);
151+
#else
152+
fd_setsize = vec_max * NFDBYTES;
153+
#endif
154+
155+
memcpy (vec_ro, vec_ri, fd_setsize);
156+
memcpy (vec_wo, vec_wi, fd_setsize);
157+
158+
#ifdef _WIN32
159+
/* pass in the write set as except set.
160+
* the idea behind this is to work around a windows bug that causes
161+
* errors to be reported as an exception and not by setting
162+
* the writable bit. this is so uncontrollably lame.
163+
*/
164+
memcpy (vec_eo, vec_wi, fd_setsize);
165+
res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
166+
#elif EV_SELECT_USE_FD_SET
167+
fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE;
168+
res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
169+
#else
170+
res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
171+
#endif
172+
EV_ACQUIRE_CB;
173+
174+
if (expect_false (res < 0))
175+
{
176+
#if EV_SELECT_IS_WINSOCKET
177+
errno = WSAGetLastError ();
178+
#endif
179+
#ifdef WSABASEERR
180+
/* on windows, select returns incompatible error codes, fix this */
181+
if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
182+
if (errno == WSAENOTSOCK)
183+
errno = EBADF;
184+
else
185+
errno -= WSABASEERR;
186+
#endif
187+
188+
#ifdef _WIN32
189+
/* select on windows erroneously returns EINVAL when no fd sets have been
190+
* provided (this is documented). what microsoft doesn't tell you that this bug
191+
* exists even when the fd sets _are_ provided, so we have to check for this bug
192+
* here and emulate by sleeping manually.
193+
* we also get EINVAL when the timeout is invalid, but we ignore this case here
194+
* and assume that EINVAL always means: you have to wait manually.
195+
*/
196+
if (errno == EINVAL)
197+
{
198+
ev_sleep (timeout);
199+
return;
200+
}
201+
#endif
202+
203+
if (errno == EBADF)
204+
fd_ebadf (EV_A);
205+
else if (errno == ENOMEM && !syserr_cb)
206+
fd_enomem (EV_A);
207+
else if (errno != EINTR)
208+
ev_syserr ("(libev) select");
209+
210+
return;
211+
}
212+
213+
#if EV_SELECT_USE_FD_SET
214+
215+
{
216+
int fd;
217+
218+
for (fd = 0; fd < anfdmax; ++fd)
219+
if (anfds [fd].events)
220+
{
221+
int events = 0;
222+
#if EV_SELECT_IS_WINSOCKET
223+
SOCKET handle = anfds [fd].handle;
224+
#else
225+
int handle = fd;
226+
#endif
227+
228+
if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
229+
if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
230+
#ifdef _WIN32
231+
if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
232+
#endif
233+
234+
if (expect_true (events))
235+
fd_event (EV_A_ fd, events);
236+
}
237+
}
238+
239+
#else
240+
241+
{
242+
int word, bit;
243+
for (word = vec_max; word--; )
244+
{
245+
fd_mask word_r = ((fd_mask *)vec_ro) [word];
246+
fd_mask word_w = ((fd_mask *)vec_wo) [word];
247+
#ifdef _WIN32
248+
word_w |= ((fd_mask *)vec_eo) [word];
249+
#endif
250+
251+
if (word_r || word_w)
252+
for (bit = NFDBITS; bit--; )
253+
{
254+
fd_mask mask = 1UL << bit;
255+
int events = 0;
256+
257+
events |= word_r & mask ? EV_READ : 0;
258+
events |= word_w & mask ? EV_WRITE : 0;
259+
260+
if (expect_true (events))
261+
fd_event (EV_A_ word * NFDBITS + bit, events);
262+
}
263+
}
264+
}
265+
266+
#endif
267+
}
268+
269+
int inline_size
270+
select_init (EV_P_ int flags)
271+
{
272+
backend_fudge = 0.; /* posix says this is zero */
273+
backend_modify = select_modify;
274+
backend_poll = select_poll;
275+
276+
#if EV_SELECT_USE_FD_SET
277+
vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
278+
vec_ro = ev_malloc (sizeof (fd_set));
279+
vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
280+
vec_wo = ev_malloc (sizeof (fd_set));
281+
#ifdef _WIN32
282+
vec_eo = ev_malloc (sizeof (fd_set));
283+
#endif
284+
#else
285+
vec_max = 0;
286+
vec_ri = 0;
287+
vec_ro = 0;
288+
vec_wi = 0;
289+
vec_wo = 0;
290+
#ifdef _WIN32
291+
vec_eo = 0;
292+
#endif
293+
#endif
294+
295+
return EVBACKEND_SELECT;
296+
}
297+
298+
void inline_size
299+
select_destroy (EV_P)
300+
{
301+
ev_free (vec_ri);
302+
ev_free (vec_ro);
303+
ev_free (vec_wi);
304+
ev_free (vec_wo);
305+
#ifdef _WIN32
306+
ev_free (vec_eo);
307+
#endif
308+
}
309+
310+

‎libev/ev_vars.h

+203
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,203 @@
1+
/*
2+
* loop member variable declarations
3+
*
4+
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modifica-
8+
* tion, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26+
* OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* the GNU General Public License ("GPL") version 2 or any later version,
30+
* in which case the provisions of the GPL are applicable instead of
31+
* the above. If you wish to allow the use of your version of this file
32+
* only under the terms of the GPL and not to allow others to use your
33+
* version of this file under the BSD license, indicate your decision
34+
* by deleting the provisions above and replace them with the notice
35+
* and other provisions required by the GPL. If you do not delete the
36+
* provisions above, a recipient may use your version of this file under
37+
* either the BSD or the GPL.
38+
*/
39+
40+
#define VARx(type,name) VAR(name, type name)
41+
42+
VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */
43+
VARx(ev_tstamp, mn_now) /* monotonic clock "now" */
44+
VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */
45+
46+
VARx(ev_tstamp, io_blocktime)
47+
VARx(ev_tstamp, timeout_blocktime)
48+
49+
VARx(int, backend)
50+
VARx(int, activecnt) /* total number of active events ("refcount") */
51+
VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */
52+
53+
VARx(int, backend_fd)
54+
VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
55+
VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
56+
VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
57+
58+
VARx(ANFD *, anfds)
59+
VARx(int, anfdmax)
60+
61+
VAR (pendings, ANPENDING *pendings [NUMPRI])
62+
VAR (pendingmax, int pendingmax [NUMPRI])
63+
VAR (pendingcnt, int pendingcnt [NUMPRI])
64+
VARx(ev_prepare, pending_w) /* dummy pending watcher */
65+
66+
/* for reverse feeding of events */
67+
VARx(W *, rfeeds)
68+
VARx(int, rfeedmax)
69+
VARx(int, rfeedcnt)
70+
71+
#if EV_USE_EVENTFD || EV_GENWRAP
72+
VARx(int, evfd)
73+
#endif
74+
VAR (evpipe, int evpipe [2])
75+
VARx(ev_io, pipe_w)
76+
77+
#if !defined(_WIN32) || EV_GENWRAP
78+
VARx(pid_t, curpid)
79+
#endif
80+
81+
VARx(char, postfork) /* true if we need to recreate kernel state after fork */
82+
83+
#if EV_USE_SELECT || EV_GENWRAP
84+
VARx(void *, vec_ri)
85+
VARx(void *, vec_ro)
86+
VARx(void *, vec_wi)
87+
VARx(void *, vec_wo)
88+
#if defined(_WIN32) || EV_GENWRAP
89+
VARx(void *, vec_eo)
90+
#endif
91+
VARx(int, vec_max)
92+
#endif
93+
94+
#if EV_USE_POLL || EV_GENWRAP
95+
VARx(struct pollfd *, polls)
96+
VARx(int, pollmax)
97+
VARx(int, pollcnt)
98+
VARx(int *, pollidxs) /* maps fds into structure indices */
99+
VARx(int, pollidxmax)
100+
#endif
101+
102+
#if EV_USE_EPOLL || EV_GENWRAP
103+
VARx(struct epoll_event *, epoll_events)
104+
VARx(int, epoll_eventmax)
105+
VARx(int *, epoll_eperms)
106+
VARx(int, epoll_epermcnt)
107+
VARx(int, epoll_epermmax)
108+
#endif
109+
110+
#if EV_USE_KQUEUE || EV_GENWRAP
111+
VARx(struct kevent *, kqueue_changes)
112+
VARx(int, kqueue_changemax)
113+
VARx(int, kqueue_changecnt)
114+
VARx(struct kevent *, kqueue_events)
115+
VARx(int, kqueue_eventmax)
116+
#endif
117+
118+
#if EV_USE_PORT || EV_GENWRAP
119+
VARx(struct port_event *, port_events)
120+
VARx(int, port_eventmax)
121+
#endif
122+
123+
#if EV_USE_IOCP || EV_GENWRAP
124+
VARx(HANDLE, iocp)
125+
#endif
126+
127+
VARx(int *, fdchanges)
128+
VARx(int, fdchangemax)
129+
VARx(int, fdchangecnt)
130+
131+
VARx(ANHE *, timers)
132+
VARx(int, timermax)
133+
VARx(int, timercnt)
134+
135+
#if EV_PERIODIC_ENABLE || EV_GENWRAP
136+
VARx(ANHE *, periodics)
137+
VARx(int, periodicmax)
138+
VARx(int, periodiccnt)
139+
#endif
140+
141+
#if EV_IDLE_ENABLE || EV_GENWRAP
142+
VAR (idles, ev_idle **idles [NUMPRI])
143+
VAR (idlemax, int idlemax [NUMPRI])
144+
VAR (idlecnt, int idlecnt [NUMPRI])
145+
#endif
146+
VARx(int, idleall) /* total number */
147+
148+
VARx(struct ev_prepare **, prepares)
149+
VARx(int, preparemax)
150+
VARx(int, preparecnt)
151+
152+
VARx(struct ev_check **, checks)
153+
VARx(int, checkmax)
154+
VARx(int, checkcnt)
155+
156+
#if EV_FORK_ENABLE || EV_GENWRAP
157+
VARx(struct ev_fork **, forks)
158+
VARx(int, forkmax)
159+
VARx(int, forkcnt)
160+
#endif
161+
162+
#if EV_CLEANUP_ENABLE || EV_GENWRAP
163+
VARx(struct ev_cleanup **, cleanups)
164+
VARx(int, cleanupmax)
165+
VARx(int, cleanupcnt)
166+
#endif
167+
168+
#if EV_ASYNC_ENABLE || EV_GENWRAP
169+
VARx(EV_ATOMIC_T, async_pending)
170+
VARx(struct ev_async **, asyncs)
171+
VARx(int, asyncmax)
172+
VARx(int, asynccnt)
173+
#endif
174+
175+
#if EV_USE_INOTIFY || EV_GENWRAP
176+
VARx(int, fs_fd)
177+
VARx(ev_io, fs_w)
178+
VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */
179+
VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])
180+
#endif
181+
182+
VARx(EV_ATOMIC_T, sig_pending)
183+
VARx(int, nosigmask)
184+
#if EV_USE_SIGNALFD || EV_GENWRAP
185+
VARx(int, sigfd)
186+
VARx(ev_io, sigfd_w)
187+
VARx(sigset_t, sigfd_set)
188+
#endif
189+
190+
VARx(unsigned int, origflags) /* original loop flags */
191+
192+
#if EV_FEATURE_API || EV_GENWRAP
193+
VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */
194+
VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */
195+
196+
VARx(void *, userdata)
197+
VAR (release_cb, void (*release_cb)(EV_P))
198+
VAR (acquire_cb, void (*acquire_cb)(EV_P))
199+
VAR (invoke_cb , void (*invoke_cb) (EV_P))
200+
#endif
201+
202+
#undef VARx
203+

‎libev/ev_win32.c

+153
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
/*
2+
* libev win32 compatibility cruft (_not_ a backend)
3+
*
4+
* Copyright (c) 2007,2008,2009 Marc Alexander Lehmann <libev@schmorp.de>
5+
* All rights reserved.
6+
*
7+
* Redistribution and use in source and binary forms, with or without modifica-
8+
* tion, are permitted provided that the following conditions are met:
9+
*
10+
* 1. Redistributions of source code must retain the above copyright notice,
11+
* this list of conditions and the following disclaimer.
12+
*
13+
* 2. Redistributions in binary form must reproduce the above copyright
14+
* notice, this list of conditions and the following disclaimer in the
15+
* documentation and/or other materials provided with the distribution.
16+
*
17+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26+
* OF THE POSSIBILITY OF SUCH DAMAGE.
27+
*
28+
* Alternatively, the contents of this file may be used under the terms of
29+
* the GNU General Public License ("GPL") version 2 or any later version,
30+
* in which case the provisions of the GPL are applicable instead of
31+
* the above. If you wish to allow the use of your version of this file
32+
* only under the terms of the GPL and not to allow others to use your
33+
* version of this file under the BSD license, indicate your decision
34+
* by deleting the provisions above and replace them with the notice
35+
* and other provisions required by the GPL. If you do not delete the
36+
* provisions above, a recipient may use your version of this file under
37+
* either the BSD or the GPL.
38+
*/
39+
40+
#ifdef _WIN32
41+
42+
/* timeb.h is actually xsi legacy functionality */
43+
#include <sys/timeb.h>
44+
45+
/* note: the comment below could not be substantiated, but what would I care */
46+
/* MSDN says this is required to handle SIGFPE */
47+
/* my wild guess would be that using something floating-pointy is required */
48+
/* for the crt to do something about it */
49+
volatile double SIGFPE_REQ = 0.0f;
50+
51+
/* oh, the humanity! */
52+
static int
53+
ev_pipe (int filedes [2])
54+
{
55+
struct sockaddr_in addr = { 0 };
56+
int addr_size = sizeof (addr);
57+
struct sockaddr_in adr2;
58+
int adr2_size = sizeof (adr2);
59+
SOCKET listener;
60+
SOCKET sock [2] = { -1, -1 };
61+
62+
if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
63+
return -1;
64+
65+
addr.sin_family = AF_INET;
66+
addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
67+
addr.sin_port = 0;
68+
69+
if (bind (listener, (struct sockaddr *)&addr, addr_size))
70+
goto fail;
71+
72+
if (getsockname (listener, (struct sockaddr *)&addr, &addr_size))
73+
goto fail;
74+
75+
if (listen (listener, 1))
76+
goto fail;
77+
78+
if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
79+
goto fail;
80+
81+
if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
82+
goto fail;
83+
84+
if ((sock [1] = accept (listener, 0, 0)) < 0)
85+
goto fail;
86+
87+
/* windows vista returns fantasy port numbers for sockets:
88+
* example for two interconnected tcp sockets:
89+
*
90+
* (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364
91+
* (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363
92+
* (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363
93+
* (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365
94+
*
95+
* wow! tridirectional sockets!
96+
*
97+
* this way of checking ports seems to work:
98+
*/
99+
if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size))
100+
goto fail;
101+
102+
if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size))
103+
goto fail;
104+
105+
errno = WSAEINVAL;
106+
if (addr_size != adr2_size
107+
|| addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */
108+
|| addr.sin_port != adr2.sin_port)
109+
goto fail;
110+
111+
closesocket (listener);
112+
113+
#if EV_SELECT_IS_WINSOCKET
114+
filedes [0] = EV_WIN32_HANDLE_TO_FD (sock [0]);
115+
filedes [1] = EV_WIN32_HANDLE_TO_FD (sock [1]);
116+
#else
117+
/* when select isn't winsocket, we also expect socket, connect, accept etc.
118+
* to work on fds */
119+
filedes [0] = sock [0];
120+
filedes [1] = sock [1];
121+
#endif
122+
123+
return 0;
124+
125+
fail:
126+
closesocket (listener);
127+
128+
if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
129+
if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);
130+
131+
return -1;
132+
}
133+
134+
#undef pipe
135+
#define pipe(filedes) ev_pipe (filedes)
136+
137+
#define EV_HAVE_EV_TIME 1
138+
ev_tstamp
139+
ev_time (void)
140+
{
141+
FILETIME ft;
142+
ULARGE_INTEGER ui;
143+
144+
GetSystemTimeAsFileTime (&ft);
145+
ui.u.LowPart = ft.dwLowDateTime;
146+
ui.u.HighPart = ft.dwHighDateTime;
147+
148+
/* msvc cannot convert ulonglong to double... yes, it is that sucky */
149+
return (LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-7;
150+
}
151+
152+
#endif
153+

‎libev/ev_wrap.h

+196
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,196 @@
1+
/* DO NOT EDIT, automatically generated by update_ev_wrap */
2+
#ifndef EV_WRAP_H
3+
#define EV_WRAP_H
4+
#define now_floor ((loop)->now_floor)
5+
#define mn_now ((loop)->mn_now)
6+
#define rtmn_diff ((loop)->rtmn_diff)
7+
#define io_blocktime ((loop)->io_blocktime)
8+
#define timeout_blocktime ((loop)->timeout_blocktime)
9+
#define backend ((loop)->backend)
10+
#define activecnt ((loop)->activecnt)
11+
#define loop_done ((loop)->loop_done)
12+
#define backend_fd ((loop)->backend_fd)
13+
#define backend_fudge ((loop)->backend_fudge)
14+
#define backend_modify ((loop)->backend_modify)
15+
#define backend_poll ((loop)->backend_poll)
16+
#define anfds ((loop)->anfds)
17+
#define anfdmax ((loop)->anfdmax)
18+
#define pendings ((loop)->pendings)
19+
#define pendingmax ((loop)->pendingmax)
20+
#define pendingcnt ((loop)->pendingcnt)
21+
#define pending_w ((loop)->pending_w)
22+
#define rfeeds ((loop)->rfeeds)
23+
#define rfeedmax ((loop)->rfeedmax)
24+
#define rfeedcnt ((loop)->rfeedcnt)
25+
#define evfd ((loop)->evfd)
26+
#define evpipe ((loop)->evpipe)
27+
#define pipe_w ((loop)->pipe_w)
28+
#define curpid ((loop)->curpid)
29+
#define postfork ((loop)->postfork)
30+
#define vec_ri ((loop)->vec_ri)
31+
#define vec_ro ((loop)->vec_ro)
32+
#define vec_wi ((loop)->vec_wi)
33+
#define vec_wo ((loop)->vec_wo)
34+
#define vec_eo ((loop)->vec_eo)
35+
#define vec_max ((loop)->vec_max)
36+
#define polls ((loop)->polls)
37+
#define pollmax ((loop)->pollmax)
38+
#define pollcnt ((loop)->pollcnt)
39+
#define pollidxs ((loop)->pollidxs)
40+
#define pollidxmax ((loop)->pollidxmax)
41+
#define epoll_events ((loop)->epoll_events)
42+
#define epoll_eventmax ((loop)->epoll_eventmax)
43+
#define epoll_eperms ((loop)->epoll_eperms)
44+
#define epoll_epermcnt ((loop)->epoll_epermcnt)
45+
#define epoll_epermmax ((loop)->epoll_epermmax)
46+
#define kqueue_changes ((loop)->kqueue_changes)
47+
#define kqueue_changemax ((loop)->kqueue_changemax)
48+
#define kqueue_changecnt ((loop)->kqueue_changecnt)
49+
#define kqueue_events ((loop)->kqueue_events)
50+
#define kqueue_eventmax ((loop)->kqueue_eventmax)
51+
#define port_events ((loop)->port_events)
52+
#define port_eventmax ((loop)->port_eventmax)
53+
#define iocp ((loop)->iocp)
54+
#define fdchanges ((loop)->fdchanges)
55+
#define fdchangemax ((loop)->fdchangemax)
56+
#define fdchangecnt ((loop)->fdchangecnt)
57+
#define timers ((loop)->timers)
58+
#define timermax ((loop)->timermax)
59+
#define timercnt ((loop)->timercnt)
60+
#define periodics ((loop)->periodics)
61+
#define periodicmax ((loop)->periodicmax)
62+
#define periodiccnt ((loop)->periodiccnt)
63+
#define idles ((loop)->idles)
64+
#define idlemax ((loop)->idlemax)
65+
#define idlecnt ((loop)->idlecnt)
66+
#define idleall ((loop)->idleall)
67+
#define prepares ((loop)->prepares)
68+
#define preparemax ((loop)->preparemax)
69+
#define preparecnt ((loop)->preparecnt)
70+
#define checks ((loop)->checks)
71+
#define checkmax ((loop)->checkmax)
72+
#define checkcnt ((loop)->checkcnt)
73+
#define forks ((loop)->forks)
74+
#define forkmax ((loop)->forkmax)
75+
#define forkcnt ((loop)->forkcnt)
76+
#define cleanups ((loop)->cleanups)
77+
#define cleanupmax ((loop)->cleanupmax)
78+
#define cleanupcnt ((loop)->cleanupcnt)
79+
#define async_pending ((loop)->async_pending)
80+
#define asyncs ((loop)->asyncs)
81+
#define asyncmax ((loop)->asyncmax)
82+
#define asynccnt ((loop)->asynccnt)
83+
#define fs_fd ((loop)->fs_fd)
84+
#define fs_w ((loop)->fs_w)
85+
#define fs_2625 ((loop)->fs_2625)
86+
#define fs_hash ((loop)->fs_hash)
87+
#define sig_pending ((loop)->sig_pending)
88+
#define nosigmask ((loop)->nosigmask)
89+
#define sigfd ((loop)->sigfd)
90+
#define sigfd_w ((loop)->sigfd_w)
91+
#define sigfd_set ((loop)->sigfd_set)
92+
#define origflags ((loop)->origflags)
93+
#define loop_count ((loop)->loop_count)
94+
#define loop_depth ((loop)->loop_depth)
95+
#define userdata ((loop)->userdata)
96+
#define release_cb ((loop)->release_cb)
97+
#define acquire_cb ((loop)->acquire_cb)
98+
#define invoke_cb ((loop)->invoke_cb)
99+
#else
100+
#undef EV_WRAP_H
101+
#undef now_floor
102+
#undef mn_now
103+
#undef rtmn_diff
104+
#undef io_blocktime
105+
#undef timeout_blocktime
106+
#undef backend
107+
#undef activecnt
108+
#undef loop_done
109+
#undef backend_fd
110+
#undef backend_fudge
111+
#undef backend_modify
112+
#undef backend_poll
113+
#undef anfds
114+
#undef anfdmax
115+
#undef pendings
116+
#undef pendingmax
117+
#undef pendingcnt
118+
#undef pending_w
119+
#undef rfeeds
120+
#undef rfeedmax
121+
#undef rfeedcnt
122+
#undef evfd
123+
#undef evpipe
124+
#undef pipe_w
125+
#undef curpid
126+
#undef postfork
127+
#undef vec_ri
128+
#undef vec_ro
129+
#undef vec_wi
130+
#undef vec_wo
131+
#undef vec_eo
132+
#undef vec_max
133+
#undef polls
134+
#undef pollmax
135+
#undef pollcnt
136+
#undef pollidxs
137+
#undef pollidxmax
138+
#undef epoll_events
139+
#undef epoll_eventmax
140+
#undef epoll_eperms
141+
#undef epoll_epermcnt
142+
#undef epoll_epermmax
143+
#undef kqueue_changes
144+
#undef kqueue_changemax
145+
#undef kqueue_changecnt
146+
#undef kqueue_events
147+
#undef kqueue_eventmax
148+
#undef port_events
149+
#undef port_eventmax
150+
#undef iocp
151+
#undef fdchanges
152+
#undef fdchangemax
153+
#undef fdchangecnt
154+
#undef timers
155+
#undef timermax
156+
#undef timercnt
157+
#undef periodics
158+
#undef periodicmax
159+
#undef periodiccnt
160+
#undef idles
161+
#undef idlemax
162+
#undef idlecnt
163+
#undef idleall
164+
#undef prepares
165+
#undef preparemax
166+
#undef preparecnt
167+
#undef checks
168+
#undef checkmax
169+
#undef checkcnt
170+
#undef forks
171+
#undef forkmax
172+
#undef forkcnt
173+
#undef cleanups
174+
#undef cleanupmax
175+
#undef cleanupcnt
176+
#undef async_pending
177+
#undef asyncs
178+
#undef asyncmax
179+
#undef asynccnt
180+
#undef fs_fd
181+
#undef fs_w
182+
#undef fs_2625
183+
#undef fs_hash
184+
#undef sig_pending
185+
#undef nosigmask
186+
#undef sigfd
187+
#undef sigfd_w
188+
#undef sigfd_set
189+
#undef origflags
190+
#undef loop_count
191+
#undef loop_depth
192+
#undef userdata
193+
#undef release_cb
194+
#undef acquire_cb
195+
#undef invoke_cb
196+
#endif

‎libev/libev.m4

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
dnl this file is part of libev, do not make local modifications
2+
dnl http://software.schmorp.de/pkg/libev
3+
4+
dnl libev support
5+
AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h)
6+
7+
AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd)
8+
9+
AC_CHECK_FUNCS(clock_gettime, [], [
10+
dnl on linux, try syscall wrapper first
11+
if test $(uname) = Linux; then
12+
AC_MSG_CHECKING(for clock_gettime syscall)
13+
AC_LINK_IFELSE([AC_LANG_PROGRAM(
14+
[#include <unistd.h>
15+
#include <sys/syscall.h>
16+
#include <time.h>],
17+
[struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts)])],
18+
[ac_have_clock_syscall=1
19+
AC_DEFINE(HAVE_CLOCK_SYSCALL, 1, "use syscall interface for clock_gettime")
20+
AC_MSG_RESULT(yes)],
21+
[AC_MSG_RESULT(no)])
22+
fi
23+
if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then
24+
AC_CHECK_LIB(rt, clock_gettime)
25+
unset ac_cv_func_clock_gettime
26+
AC_CHECK_FUNCS(clock_gettime)
27+
fi
28+
])
29+
30+
AC_CHECK_FUNCS(nanosleep, [], [
31+
if test -z "$LIBEV_M4_AVOID_LIBRT"; then
32+
AC_CHECK_LIB(rt, nanosleep)
33+
unset ac_cv_func_nanosleep
34+
AC_CHECK_FUNCS(nanosleep)
35+
fi
36+
])
37+
38+
AC_CHECK_LIB(m, ceil)
39+

0 commit comments

Comments
 (0)
Please sign in to comment.