ebb 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
data/libev/ev.c CHANGED
@@ -156,6 +156,7 @@ extern "C" {
156
156
  # include <sys/wait.h>
157
157
  # include <unistd.h>
158
158
  #else
159
+ # include <io.h>
159
160
  # define WIN32_LEAN_AND_MEAN
160
161
  # include <windows.h>
161
162
  # ifndef EV_SELECT_IS_WINSOCKET
@@ -166,7 +167,11 @@ extern "C" {
166
167
  /* this block tries to deduce configuration from header-defined symbols and defaults */
167
168
 
168
169
  #ifndef EV_USE_MONOTONIC
169
- # define EV_USE_MONOTONIC 0
170
+ # if defined (_POSIX_MONOTONIC_CLOCK) && _POSIX_MONOTONIC_CLOCK >= 0
171
+ # define EV_USE_MONOTONIC 1
172
+ # else
173
+ # define EV_USE_MONOTONIC 0
174
+ # endif
170
175
  #endif
171
176
 
172
177
  #ifndef EV_USE_REALTIME
@@ -174,7 +179,11 @@ extern "C" {
174
179
  #endif
175
180
 
176
181
  #ifndef EV_USE_NANOSLEEP
177
- # define EV_USE_NANOSLEEP 0
182
+ # if _POSIX_C_SOURCE >= 199309L
183
+ # define EV_USE_NANOSLEEP 1
184
+ # else
185
+ # define EV_USE_NANOSLEEP 0
186
+ # endif
178
187
  #endif
179
188
 
180
189
  #ifndef EV_USE_SELECT
@@ -558,6 +567,9 @@ ev_sleep (ev_tstamp delay)
558
567
  tv.tv_sec = (time_t)delay;
559
568
  tv.tv_usec = (long)((delay - (ev_tstamp)(tv.tv_sec)) * 1e6);
560
569
 
570
+ /* here we rely on sys/time.h + sys/types.h + unistd.h providing select */
571
+ /* somehting nto guaranteed by newer posix versions, but guaranteed */
572
+ /* by older ones */
561
573
  select (0, 0, 0, 0, &tv);
562
574
  #endif
563
575
  }
@@ -701,13 +713,13 @@ fd_reify (EV_P)
701
713
  #if EV_SELECT_IS_WINSOCKET
702
714
  if (events)
703
715
  {
704
- unsigned long argp;
716
+ unsigned long arg;
705
717
  #ifdef EV_FD_TO_WIN32_HANDLE
706
718
  anfd->handle = EV_FD_TO_WIN32_HANDLE (fd);
707
719
  #else
708
720
  anfd->handle = _get_osfhandle (fd);
709
721
  #endif
710
- assert (("libev only supports socket fds in this configuration", ioctlsocket (anfd->handle, FIONREAD, &argp) == 0));
722
+ assert (("libev only supports socket fds in this configuration", ioctlsocket (anfd->handle, FIONREAD, &arg) == 0));
711
723
  }
712
724
  #endif
713
725
 
@@ -770,7 +782,7 @@ fd_ebadf (EV_P)
770
782
 
771
783
  for (fd = 0; fd < anfdmax; ++fd)
772
784
  if (anfds [fd].events)
773
- if (!fd_valid (fd) == -1 && errno == EBADF)
785
+ if (!fd_valid (fd) && errno == EBADF)
774
786
  fd_kill (EV_A_ fd);
775
787
  }
776
788
 
@@ -977,7 +989,7 @@ void inline_speed
977
989
  fd_intern (int fd)
978
990
  {
979
991
  #ifdef _WIN32
980
- int arg = 1;
992
+ unsigned long arg = 1;
981
993
  ioctlsocket (_get_osfhandle (fd), FIONBIO, &arg);
982
994
  #else
983
995
  fcntl (fd, F_SETFD, FD_CLOEXEC);
@@ -2563,6 +2575,12 @@ infy_fork (EV_P)
2563
2575
 
2564
2576
  #endif
2565
2577
 
2578
+ #ifdef _WIN32
2579
+ # define EV_LSTAT(p,b) _stati64 (p, b)
2580
+ #else
2581
+ # define EV_LSTAT(p,b) lstat (p, b)
2582
+ #endif
2583
+
2566
2584
  void
2567
2585
  ev_stat_stat (EV_P_ ev_stat *w)
2568
2586
  {
data/libev/ev.h CHANGED
@@ -90,6 +90,10 @@ typedef double ev_tstamp;
90
90
  /*****************************************************************************/
91
91
 
92
92
  #if EV_STAT_ENABLE
93
+ # ifdef _WIN32
94
+ # include <time.h>
95
+ # include <sys/types.h>
96
+ # endif
93
97
  # include <sys/stat.h>
94
98
  #endif
95
99
 
@@ -54,6 +54,8 @@
54
54
  #if EV_SELECT_IS_WINSOCKET
55
55
  # undef EV_SELECT_USE_FD_SET
56
56
  # define EV_SELECT_USE_FD_SET 1
57
+ # undef NFDBITS
58
+ # define NFDBITS 0
57
59
  #endif
58
60
 
59
61
  #if !EV_SELECT_USE_FD_SET
@@ -77,15 +79,24 @@ select_modify (EV_P_ int fd, int oev, int nev)
77
79
  int handle = fd;
78
80
  #endif
79
81
 
80
- if (nev & EV_READ)
81
- FD_SET (handle, (fd_set *)vec_ri);
82
- else
83
- FD_CLR (handle, (fd_set *)vec_ri);
82
+ /* FD_SET is broken on windows (it adds the fd to a set twice or more,
83
+ * which eventually leads to overflows). Need to call it only on changes.
84
+ */
85
+ #if EV_SELECT_IS_WINSOCKET
86
+ if ((oev ^ nev) & EV_READ)
87
+ #endif
88
+ if (nev & EV_READ)
89
+ FD_SET (handle, (fd_set *)vec_ri);
90
+ else
91
+ FD_CLR (handle, (fd_set *)vec_ri);
84
92
 
85
- if (nev & EV_WRITE)
86
- FD_SET (handle, (fd_set *)vec_wi);
87
- else
88
- FD_CLR (handle, (fd_set *)vec_wi);
93
+ #if EV_SELECT_IS_WINSOCKET
94
+ if ((oev ^ nev) & EV_WRITE)
95
+ #endif
96
+ if (nev & EV_WRITE)
97
+ FD_SET (handle, (fd_set *)vec_wi);
98
+ else
99
+ FD_CLR (handle, (fd_set *)vec_wi);
89
100
 
90
101
  #else
91
102
 
@@ -100,6 +111,9 @@ select_modify (EV_P_ int fd, int oev, int nev)
100
111
  vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
101
112
  vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
102
113
  vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
114
+ #ifdef _WIN32
115
+ vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
116
+ #endif
103
117
 
104
118
  for (; vec_max < new_max; ++vec_max)
105
119
  ((fd_mask *)vec_ri) [vec_max] =
@@ -122,19 +136,31 @@ select_poll (EV_P_ ev_tstamp timeout)
122
136
  {
123
137
  struct timeval tv;
124
138
  int res;
139
+ int fd_setsize;
140
+
141
+ tv.tv_sec = (long)timeout;
142
+ tv.tv_usec = (long)((timeout - (ev_tstamp)tv.tv_sec) * 1e6);
125
143
 
126
144
  #if EV_SELECT_USE_FD_SET
127
- memcpy (vec_ro, vec_ri, sizeof (fd_set));
128
- memcpy (vec_wo, vec_wi, sizeof (fd_set));
145
+ fd_setsize = sizeof (fd_set);
129
146
  #else
130
- memcpy (vec_ro, vec_ri, vec_max * NFDBYTES);
131
- memcpy (vec_wo, vec_wi, vec_max * NFDBYTES);
147
+ fd_setsize = vec_max * NFDBYTES;
132
148
  #endif
133
149
 
134
- tv.tv_sec = (long)timeout;
135
- tv.tv_usec = (long)((timeout - (ev_tstamp)tv.tv_sec) * 1e6);
136
-
150
+ memcpy (vec_ro, vec_ri, fd_setsize);
151
+ memcpy (vec_wo, vec_wi, fd_setsize);
152
+
153
+ #ifdef _WIN32
154
+ /* pass in the write set as except set.
155
+ * the idea behind this is to work around a windows bug that causes
156
+ * errors to be reported as an exception and not by setting
157
+ * the writable bit. this is so uncontrollably lame.
158
+ */
159
+ memcpy (vec_eo, vec_wi, fd_setsize);
160
+ res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
161
+ #else
137
162
  res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
163
+ #endif
138
164
 
139
165
  if (expect_false (res < 0))
140
166
  {
@@ -192,6 +218,9 @@ select_poll (EV_P_ ev_tstamp timeout)
192
218
 
193
219
  if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
194
220
  if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
221
+ #ifdef _WIN32
222
+ if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
223
+ #endif
195
224
 
196
225
  if (expect_true (events))
197
226
  fd_event (EV_A_ fd, events);
@@ -206,6 +235,9 @@ select_poll (EV_P_ ev_tstamp timeout)
206
235
  {
207
236
  fd_mask word_r = ((fd_mask *)vec_ro) [word];
208
237
  fd_mask word_w = ((fd_mask *)vec_wo) [word];
238
+ #ifdef _WIN32
239
+ word_w |= ((fd_mask *)vec_eo) [word];
240
+ #endif
209
241
 
210
242
  if (word_r || word_w)
211
243
  for (bit = NFDBITS; bit--; )
@@ -238,6 +270,9 @@ select_init (EV_P_ int flags)
238
270
  vec_ro = ev_malloc (sizeof (fd_set));
239
271
  vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
240
272
  vec_wo = ev_malloc (sizeof (fd_set));
273
+ #ifdef _WIN32
274
+ vec_eo = ev_malloc (sizeof (fd_set));
275
+ #endif
241
276
  #else
242
277
  vec_max = 0;
243
278
  vec_ri = 0;
@@ -72,6 +72,9 @@ VARx(void *, vec_ri)
72
72
  VARx(void *, vec_ro)
73
73
  VARx(void *, vec_wi)
74
74
  VARx(void *, vec_wo)
75
+ #if defined(_WIN32) || EV_GENWRAP
76
+ VARx(void *, vec_eo)
77
+ #endif
75
78
  VARx(int, vec_max)
76
79
  #endif
77
80
 
@@ -39,10 +39,13 @@
39
39
 
40
40
  #ifdef _WIN32
41
41
 
42
+ /* timeb.h is actually xsi legacy functionality */
42
43
  #include <sys/timeb.h>
43
44
 
44
45
  /* note: the comment below could not be substantiated, but what would I care */
45
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 */
46
49
  volatile double SIGFPE_REQ = 0.0f;
47
50
 
48
51
  /* oh, the humanity! */
@@ -22,6 +22,7 @@
22
22
  #define vec_ro ((loop)->vec_ro)
23
23
  #define vec_wi ((loop)->vec_wi)
24
24
  #define vec_wo ((loop)->vec_wo)
25
+ #define vec_eo ((loop)->vec_eo)
25
26
  #define vec_max ((loop)->vec_max)
26
27
  #define polls ((loop)->polls)
27
28
  #define pollmax ((loop)->pollmax)
@@ -94,6 +95,7 @@
94
95
  #undef vec_ro
95
96
  #undef vec_wi
96
97
  #undef vec_wo
98
+ #undef vec_eo
97
99
  #undef vec_max
98
100
  #undef polls
99
101
  #undef pollmax
@@ -0,0 +1,403 @@
1
+ /*
2
+ * libevent compatibility layer
3
+ *
4
+ * Copyright (c) 2007,2008 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 <stddef.h>
41
+ #include <stdlib.h>
42
+ #include <assert.h>
43
+
44
+ #ifndef WIN32
45
+ # include <sys/time.h>
46
+ #endif
47
+
48
+ #ifdef EV_EVENT_H
49
+ # include EV_EVENT_H
50
+ #else
51
+ # include "event.h"
52
+ #endif
53
+
54
+ #if EV_MULTIPLICITY
55
+ # define dLOOPev struct ev_loop *loop = (struct ev_loop *)ev->ev_base
56
+ # define dLOOPbase struct ev_loop *loop = (struct ev_loop *)base
57
+ #else
58
+ # define dLOOPev
59
+ # define dLOOPbase
60
+ #endif
61
+
62
+ /* never accessed, will always be cast from/to ev_loop */
63
+ struct event_base
64
+ {
65
+ int dummy;
66
+ };
67
+
68
+ static struct event_base *x_cur;
69
+
70
+ static void
71
+ tv_set (struct timeval *tv, ev_tstamp at)
72
+ {
73
+ tv->tv_sec = (long)at;
74
+ tv->tv_usec = (long)((at - (ev_tstamp)tv->tv_sec) * 1e6);
75
+ }
76
+
77
+ static ev_tstamp
78
+ tv_get (struct timeval *tv)
79
+ {
80
+ if (tv)
81
+ return tv->tv_sec + tv->tv_usec * 1e-6;
82
+ else
83
+ return -1.;
84
+ }
85
+
86
+ #define EVENT_VERSION(a,b) # a "." # b
87
+
88
+ const char *event_get_version (void)
89
+ {
90
+ return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR);
91
+ }
92
+
93
+ const char *event_get_method (void)
94
+ {
95
+ return "libev";
96
+ }
97
+
98
+ void *event_init (void)
99
+ {
100
+ #if EV_MULTIPLICITY
101
+ if (x_cur)
102
+ x_cur = (struct event_base *)ev_loop_new (EVFLAG_AUTO);
103
+ else
104
+ x_cur = (struct event_base *)ev_default_loop (EVFLAG_AUTO);
105
+ #else
106
+ assert (("multiple event bases not supported when not compiled with EV_MULTIPLICITY", !x_cur));
107
+
108
+ x_cur = (struct event_base *)(long)ev_default_loop (EVFLAG_AUTO);
109
+ #endif
110
+
111
+ return x_cur;
112
+ }
113
+
114
+ void event_base_free (struct event_base *base)
115
+ {
116
+ dLOOPbase;
117
+
118
+ #if EV_MULTIPLICITY
119
+ if (ev_default_loop (EVFLAG_AUTO) != loop)
120
+ ev_loop_destroy (loop);
121
+ #endif
122
+ }
123
+
124
+ int event_dispatch (void)
125
+ {
126
+ return event_base_dispatch (x_cur);
127
+ }
128
+
129
+ #ifdef EV_STANDALONE
130
+ void event_set_log_callback (event_log_cb cb)
131
+ {
132
+ /* nop */
133
+ }
134
+ #endif
135
+
136
+ int event_loop (int flags)
137
+ {
138
+ return event_base_loop (x_cur, flags);
139
+ }
140
+
141
+ int event_loopexit (struct timeval *tv)
142
+ {
143
+ return event_base_loopexit (x_cur, tv);
144
+ }
145
+
146
+ static void
147
+ x_cb (struct event *ev, int revents)
148
+ {
149
+ revents &= EV_READ | EV_WRITE | EV_TIMEOUT | EV_SIGNAL;
150
+
151
+ ev->ev_res = revents;
152
+ ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
153
+ }
154
+
155
+ static void
156
+ x_cb_sig (EV_P_ struct ev_signal *w, int revents)
157
+ {
158
+ struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.sig));
159
+
160
+ if (revents & EV_ERROR)
161
+ event_del (ev);
162
+
163
+ x_cb (ev, revents);
164
+ }
165
+
166
+ static void
167
+ x_cb_io (EV_P_ struct ev_io *w, int revents)
168
+ {
169
+ struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.io));
170
+
171
+ if ((revents & EV_ERROR) || !(ev->ev_events & EV_PERSIST))
172
+ event_del (ev);
173
+
174
+ x_cb (ev, revents);
175
+ }
176
+
177
+ static void
178
+ x_cb_to (EV_P_ struct ev_timer *w, int revents)
179
+ {
180
+ struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, to));
181
+
182
+ event_del (ev);
183
+
184
+ x_cb (ev, revents);
185
+ }
186
+
187
+ void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg)
188
+ {
189
+ if (events & EV_SIGNAL)
190
+ ev_init (&ev->iosig.sig, x_cb_sig);
191
+ else
192
+ ev_init (&ev->iosig.io, x_cb_io);
193
+
194
+ ev_init (&ev->to, x_cb_to);
195
+
196
+ ev->ev_base = x_cur; /* not threadsafe, but its like libevent works */
197
+ ev->ev_fd = fd;
198
+ ev->ev_events = events;
199
+ ev->ev_pri = 0;
200
+ ev->ev_callback = cb;
201
+ ev->ev_arg = arg;
202
+ ev->ev_res = 0;
203
+ ev->ev_flags = EVLIST_INIT;
204
+ }
205
+
206
+ int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
207
+ {
208
+ return event_base_once (x_cur, fd, events, cb, arg, tv);
209
+ }
210
+
211
+ int event_add (struct event *ev, struct timeval *tv)
212
+ {
213
+ dLOOPev;
214
+
215
+ if (ev->ev_events & EV_SIGNAL)
216
+ {
217
+ if (!ev_is_active (&ev->iosig.sig))
218
+ {
219
+ ev_signal_set (&ev->iosig.sig, ev->ev_fd);
220
+ ev_signal_start (EV_A_ &ev->iosig.sig);
221
+
222
+ ev->ev_flags |= EVLIST_SIGNAL;
223
+ }
224
+ }
225
+ else if (ev->ev_events & (EV_READ | EV_WRITE))
226
+ {
227
+ if (!ev_is_active (&ev->iosig.io))
228
+ {
229
+ ev_io_set (&ev->iosig.io, ev->ev_fd, ev->ev_events & (EV_READ | EV_WRITE));
230
+ ev_io_start (EV_A_ &ev->iosig.io);
231
+
232
+ ev->ev_flags |= EVLIST_INSERTED;
233
+ }
234
+ }
235
+
236
+ if (tv)
237
+ {
238
+ ev->to.repeat = tv_get (tv);
239
+ ev_timer_again (EV_A_ &ev->to);
240
+ ev->ev_flags |= EVLIST_TIMEOUT;
241
+ }
242
+ else
243
+ {
244
+ ev_timer_stop (EV_A_ &ev->to);
245
+ ev->ev_flags &= ~EVLIST_TIMEOUT;
246
+ }
247
+
248
+ ev->ev_flags |= EVLIST_ACTIVE;
249
+
250
+ return 0;
251
+ }
252
+
253
+ int event_del (struct event *ev)
254
+ {
255
+ dLOOPev;
256
+
257
+ if (ev->ev_events & EV_SIGNAL)
258
+ ev_signal_stop (EV_A_ &ev->iosig.sig);
259
+ else if (ev->ev_events & (EV_READ | EV_WRITE))
260
+ ev_io_stop (EV_A_ &ev->iosig.io);
261
+
262
+ if (ev_is_active (&ev->to))
263
+ ev_timer_stop (EV_A_ &ev->to);
264
+
265
+ ev->ev_flags = EVLIST_INIT;
266
+
267
+ return 0;
268
+ }
269
+
270
+ void event_active (struct event *ev, int res, short ncalls)
271
+ {
272
+ dLOOPev;
273
+
274
+ if (res & EV_TIMEOUT)
275
+ ev_feed_event (EV_A_ &ev->to, res & EV_TIMEOUT);
276
+
277
+ if (res & EV_SIGNAL)
278
+ ev_feed_event (EV_A_ &ev->iosig.sig, res & EV_SIGNAL);
279
+
280
+ if (res & (EV_READ | EV_WRITE))
281
+ ev_feed_event (EV_A_ &ev->iosig.io, res & (EV_READ | EV_WRITE));
282
+ }
283
+
284
+ int event_pending (struct event *ev, short events, struct timeval *tv)
285
+ {
286
+ short revents = 0;
287
+ dLOOPev;
288
+
289
+ if (ev->ev_events & EV_SIGNAL)
290
+ {
291
+ /* sig */
292
+ if (ev_is_active (&ev->iosig.sig) || ev_is_pending (&ev->iosig.sig))
293
+ revents |= EV_SIGNAL;
294
+ }
295
+ else if (ev->ev_events & (EV_READ | EV_WRITE))
296
+ {
297
+ /* io */
298
+ if (ev_is_active (&ev->iosig.io) || ev_is_pending (&ev->iosig.io))
299
+ revents |= ev->ev_events & (EV_READ | EV_WRITE);
300
+ }
301
+
302
+ if (ev->ev_events & EV_TIMEOUT || ev_is_active (&ev->to) || ev_is_pending (&ev->to))
303
+ {
304
+ revents |= EV_TIMEOUT;
305
+
306
+ if (tv)
307
+ tv_set (tv, ev_now (EV_A)); /* not sure if this is right :) */
308
+ }
309
+
310
+ return events & revents;
311
+ }
312
+
313
+ int event_priority_init (int npri)
314
+ {
315
+ return event_base_priority_init (x_cur, npri);
316
+ }
317
+
318
+ int event_priority_set (struct event *ev, int pri)
319
+ {
320
+ ev->ev_pri = pri;
321
+
322
+ return 0;
323
+ }
324
+
325
+ int event_base_set (struct event_base *base, struct event *ev)
326
+ {
327
+ ev->ev_base = base;
328
+
329
+ return 0;
330
+ }
331
+
332
+ int event_base_loop (struct event_base *base, int flags)
333
+ {
334
+ dLOOPbase;
335
+
336
+ ev_loop (EV_A_ flags);
337
+
338
+ return 0;
339
+ }
340
+
341
+ int event_base_dispatch (struct event_base *base)
342
+ {
343
+ return event_base_loop (base, 0);
344
+ }
345
+
346
+ static void
347
+ x_loopexit_cb (int revents, void *base)
348
+ {
349
+ dLOOPbase;
350
+
351
+ ev_unloop (EV_A_ EVUNLOOP_ONE);
352
+ }
353
+
354
+ int event_base_loopexit (struct event_base *base, struct timeval *tv)
355
+ {
356
+ ev_tstamp after = tv_get (tv);
357
+ dLOOPbase;
358
+
359
+ ev_once (EV_A_ -1, 0, after >= 0. ? after : 0., x_loopexit_cb, (void *)base);
360
+
361
+ return 0;
362
+ }
363
+
364
+ struct x_once
365
+ {
366
+ int fd;
367
+ void (*cb)(int, short, void *);
368
+ void *arg;
369
+ };
370
+
371
+ static void
372
+ x_once_cb (int revents, void *arg)
373
+ {
374
+ struct x_once *once = (struct x_once *)arg;
375
+
376
+ once->cb (once->fd, (short)revents, once->arg);
377
+ free (once);
378
+ }
379
+
380
+ int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
381
+ {
382
+ struct x_once *once = (struct x_once *)malloc (sizeof (struct x_once));
383
+ dLOOPbase;
384
+
385
+ if (!once)
386
+ return -1;
387
+
388
+ once->fd = fd;
389
+ once->cb = cb;
390
+ once->arg = arg;
391
+
392
+ ev_once (EV_A_ fd, events & (EV_READ | EV_WRITE), tv_get (tv), x_once_cb, (void *)once);
393
+
394
+ return 0;
395
+ }
396
+
397
+ int event_base_priority_init (struct event_base *base, int npri)
398
+ {
399
+ /*dLOOPbase;*/
400
+
401
+ return 0;
402
+ }
403
+