evdispatch 0.2.5 → 0.2.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +3 -0
- data/Manifest.txt +32 -32
- data/ext/revdispatch/extconf.rb +1 -1
- data/ext/revdispatch/libdispatch-0.1/Changelog +1 -0
- data/ext/revdispatch/libdispatch-0.1/configure +1 -1
- data/ext/revdispatch/libdispatch-0.1/configure.ac +1 -1
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/Changes +24 -0
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/Makefile.in +172 -234
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/aclocal.m4 +6449 -6665
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/autogen.sh +1 -2
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/config.guess +3 -3
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/config.h.in +6 -0
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/config.sub +3 -3
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/configure +496 -783
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/configure.ac +1 -1
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev++.h +32 -8
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev.3 +91 -23
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev.c +119 -22
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev.h +59 -37
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev.pod +96 -20
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_poll.c +17 -14
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_vars.h +3 -0
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_wrap.h +2 -0
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/event.c +1 -1
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/libev.m4 +2 -2
- data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ltmain.sh +92 -151
- data/ext/revdispatch/libdispatch-0.1/src/ev_http.cc +11 -6
- data/ext/revdispatch/libdispatch-0.1/test/stress_test.cc +1 -1
- data/ext/revdispatch/server.rb +11 -23
- data/ext/revdispatch/stest.rb +3 -3
- data/lib/evdispatch/version.rb +1 -1
- data/website/index.html +1 -1
- metadata +35 -35
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/LICENSE +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/Makefile.am +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/README +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_epoll.c +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_kqueue.c +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_port.c +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_select.c +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/ev_win32.c +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/event.h +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/install-sh +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/missing +0 -0
- /data/ext/revdispatch/libdispatch-0.1/{libev-3.2 → libev-3.31}/mkinstalldirs +0 -0
|
@@ -100,6 +100,8 @@ struct ev_loop;
|
|
|
100
100
|
# define EV_P_ EV_P,
|
|
101
101
|
# define EV_A loop
|
|
102
102
|
# define EV_A_ EV_A,
|
|
103
|
+
# define EV_DEFAULT_UC ev_default_loop_uc ()
|
|
104
|
+
# define EV_DEFAULT_UC_ EV_DEFAULT_UC,
|
|
103
105
|
# define EV_DEFAULT ev_default_loop (0)
|
|
104
106
|
# define EV_DEFAULT_ EV_DEFAULT,
|
|
105
107
|
#else
|
|
@@ -109,28 +111,37 @@ struct ev_loop;
|
|
|
109
111
|
# define EV_A_
|
|
110
112
|
# define EV_DEFAULT
|
|
111
113
|
# define EV_DEFAULT_
|
|
112
|
-
|
|
114
|
+
# define EV_DEFAULT_UC
|
|
115
|
+
# define EV_DEFAULT_UC_
|
|
113
116
|
# undef EV_EMBED_ENABLE
|
|
114
117
|
#endif
|
|
115
118
|
|
|
119
|
+
#if __STDC_VERSION__ >= 199901L || __GNUC__ >= 3
|
|
120
|
+
# define EV_INLINE static inline
|
|
121
|
+
#else
|
|
122
|
+
# define EV_INLINE static
|
|
123
|
+
#endif
|
|
124
|
+
|
|
125
|
+
/*****************************************************************************/
|
|
126
|
+
|
|
116
127
|
/* eventmask, revents, events... */
|
|
117
|
-
#define EV_UNDEF -
|
|
118
|
-
#define EV_NONE
|
|
119
|
-
#define EV_READ
|
|
120
|
-
#define EV_WRITE
|
|
121
|
-
#define EV_IOFDSET
|
|
122
|
-
#define EV_TIMEOUT
|
|
123
|
-
#define EV_PERIODIC
|
|
124
|
-
#define EV_SIGNAL
|
|
125
|
-
#define EV_CHILD
|
|
126
|
-
#define EV_STAT
|
|
127
|
-
#define EV_IDLE
|
|
128
|
-
#define EV_PREPARE
|
|
129
|
-
#define EV_CHECK
|
|
130
|
-
#define EV_EMBED
|
|
131
|
-
#define EV_FORK
|
|
132
|
-
#define EV_ASYNC
|
|
133
|
-
#define EV_ERROR
|
|
128
|
+
#define EV_UNDEF -1 /* guaranteed to be invalid */
|
|
129
|
+
#define EV_NONE 0x00 /* no events */
|
|
130
|
+
#define EV_READ 0x01 /* ev_io detected read will not block */
|
|
131
|
+
#define EV_WRITE 0x02 /* ev_io detected write will not block */
|
|
132
|
+
#define EV_IOFDSET 0x80 /* internal use only */
|
|
133
|
+
#define EV_TIMEOUT 0x00000100 /* timer timed out */
|
|
134
|
+
#define EV_PERIODIC 0x00000200 /* periodic timer timed out */
|
|
135
|
+
#define EV_SIGNAL 0x00000400 /* signal was received */
|
|
136
|
+
#define EV_CHILD 0x00000800 /* child/pid had status change */
|
|
137
|
+
#define EV_STAT 0x00001000 /* stat data changed */
|
|
138
|
+
#define EV_IDLE 0x00002000 /* event loop is idling */
|
|
139
|
+
#define EV_PREPARE 0x00004000 /* event loop about to poll */
|
|
140
|
+
#define EV_CHECK 0x00008000 /* event loop finished poll */
|
|
141
|
+
#define EV_EMBED 0x00010000 /* embedded event loop needs sweep */
|
|
142
|
+
#define EV_FORK 0x00020000 /* event loop resumed in child */
|
|
143
|
+
#define EV_ASYNC 0x00040000 /* async intra-loop signal */
|
|
144
|
+
#define EV_ERROR 0x80000000 /* sent when an error occurs */
|
|
134
145
|
|
|
135
146
|
/* can be used to add custom fields to all watchers, while losing binary compatibility */
|
|
136
147
|
#ifndef EV_COMMON
|
|
@@ -327,7 +338,7 @@ typedef struct ev_async
|
|
|
327
338
|
EV_ATOMIC_T sent; /* private */
|
|
328
339
|
} ev_async;
|
|
329
340
|
|
|
330
|
-
# define ev_async_pending(w) ((
|
|
341
|
+
# define ev_async_pending(w) ((w)->sent + 0)
|
|
331
342
|
#endif
|
|
332
343
|
|
|
333
344
|
/* the presence of this union forces similar struct layout */
|
|
@@ -355,24 +366,24 @@ union ev_any_watcher
|
|
|
355
366
|
#if EV_EMBED_ENABLE
|
|
356
367
|
struct ev_embed embed;
|
|
357
368
|
#endif
|
|
358
|
-
#if
|
|
369
|
+
#if EV_ASYNC_ENABLE
|
|
359
370
|
struct ev_async async;
|
|
360
371
|
#endif
|
|
361
372
|
};
|
|
362
373
|
|
|
363
374
|
/* bits for ev_default_loop and ev_loop_new */
|
|
364
375
|
/* the default */
|
|
365
|
-
#define EVFLAG_AUTO
|
|
376
|
+
#define EVFLAG_AUTO 0x00000000U /* not quite a mask */
|
|
366
377
|
/* flag bits */
|
|
367
|
-
#define EVFLAG_NOENV
|
|
368
|
-
#define EVFLAG_FORKCHECK
|
|
378
|
+
#define EVFLAG_NOENV 0x01000000U /* do NOT consult environment */
|
|
379
|
+
#define EVFLAG_FORKCHECK 0x02000000U /* check for a fork in each iteration */
|
|
369
380
|
/* method bits to be ored together */
|
|
370
|
-
#define EVBACKEND_SELECT
|
|
371
|
-
#define EVBACKEND_POLL
|
|
372
|
-
#define EVBACKEND_EPOLL
|
|
373
|
-
#define EVBACKEND_KQUEUE
|
|
374
|
-
#define EVBACKEND_DEVPOLL
|
|
375
|
-
#define EVBACKEND_PORT
|
|
381
|
+
#define EVBACKEND_SELECT 0x00000001U /* about anywhere */
|
|
382
|
+
#define EVBACKEND_POLL 0x00000002U /* !win */
|
|
383
|
+
#define EVBACKEND_EPOLL 0x00000004U /* linux */
|
|
384
|
+
#define EVBACKEND_KQUEUE 0x00000008U /* bsd */
|
|
385
|
+
#define EVBACKEND_DEVPOLL 0x00000010U /* solaris 8 */ /* NYI */
|
|
386
|
+
#define EVBACKEND_PORT 0x00000020U /* solaris 10 */
|
|
376
387
|
|
|
377
388
|
#if EV_PROTOTYPES
|
|
378
389
|
int ev_version_major (void);
|
|
@@ -400,18 +411,29 @@ void ev_set_allocator (void *(*cb)(void *ptr, long size));
|
|
|
400
411
|
void ev_set_syserr_cb (void (*cb)(const char *msg));
|
|
401
412
|
|
|
402
413
|
# if EV_MULTIPLICITY
|
|
414
|
+
EV_INLINE struct ev_loop *
|
|
415
|
+
ev_default_loop_uc (void)
|
|
416
|
+
{
|
|
417
|
+
extern struct ev_loop *ev_default_loop_ptr;
|
|
418
|
+
|
|
419
|
+
return ev_default_loop_ptr;
|
|
420
|
+
}
|
|
421
|
+
|
|
403
422
|
/* the default loop is the only one that handles signals and child watchers */
|
|
404
423
|
/* you can call this as often as you like */
|
|
405
|
-
|
|
424
|
+
EV_INLINE struct ev_loop *
|
|
406
425
|
ev_default_loop (unsigned int flags)
|
|
407
426
|
{
|
|
408
|
-
|
|
409
|
-
extern struct ev_loop *ev_default_loop_init (unsigned int flags);
|
|
427
|
+
struct ev_loop *loop = ev_default_loop_uc ();
|
|
410
428
|
|
|
411
|
-
if (!
|
|
412
|
-
|
|
429
|
+
if (!loop)
|
|
430
|
+
{
|
|
431
|
+
extern struct ev_loop *ev_default_loop_init (unsigned int flags);
|
|
413
432
|
|
|
414
|
-
|
|
433
|
+
loop = ev_default_loop_init (flags);
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
return loop;
|
|
415
437
|
}
|
|
416
438
|
|
|
417
439
|
/* create and destroy alternative loops that don't handle signals */
|
|
@@ -425,7 +447,7 @@ ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after
|
|
|
425
447
|
|
|
426
448
|
int ev_default_loop (unsigned int flags); /* returns true when successful */
|
|
427
449
|
|
|
428
|
-
|
|
450
|
+
EV_INLINE ev_tstamp
|
|
429
451
|
ev_now (void)
|
|
430
452
|
{
|
|
431
453
|
extern ev_tstamp ev_rt_now;
|
|
@@ -434,7 +456,7 @@ ev_now (void)
|
|
|
434
456
|
}
|
|
435
457
|
# endif
|
|
436
458
|
|
|
437
|
-
|
|
459
|
+
EV_INLINE int
|
|
438
460
|
ev_is_default_loop (EV_P)
|
|
439
461
|
{
|
|
440
462
|
#if EV_MULTIPLICITY
|
|
@@ -198,18 +198,21 @@ See the description of C<ev_embed> watchers for more info.
|
|
|
198
198
|
=item ev_set_allocator (void *(*cb)(void *ptr, long size))
|
|
199
199
|
|
|
200
200
|
Sets the allocation function to use (the prototype is similar - the
|
|
201
|
-
semantics
|
|
202
|
-
allocate and free memory (no surprises here). If it returns zero
|
|
203
|
-
memory needs to be allocated, the library might abort
|
|
204
|
-
potentially destructive action.
|
|
205
|
-
|
|
201
|
+
semantics are identical to the C<realloc> C89/SuS/POSIX function). It is
|
|
202
|
+
used to allocate and free memory (no surprises here). If it returns zero
|
|
203
|
+
when memory needs to be allocated (C<size != 0>), the library might abort
|
|
204
|
+
or take some potentially destructive action.
|
|
205
|
+
|
|
206
|
+
Since some systems (at least OpenBSD and Darwin) fail to implement
|
|
207
|
+
correct C<realloc> semantics, libev will use a wrapper around the system
|
|
208
|
+
C<realloc> and C<free> functions by default.
|
|
206
209
|
|
|
207
210
|
You could override this function in high-availability programs to, say,
|
|
208
211
|
free some memory if it cannot allocate memory, to use a special allocator,
|
|
209
212
|
or even to sleep a while and retry until some memory is available.
|
|
210
213
|
|
|
211
214
|
Example: Replace the libev allocator with one that waits a bit and then
|
|
212
|
-
retries).
|
|
215
|
+
retries (example requires a standards-compliant C<realloc>).
|
|
213
216
|
|
|
214
217
|
static void *
|
|
215
218
|
persistent_realloc (void *ptr, size_t size)
|
|
@@ -258,13 +261,6 @@ An event loop is described by a C<struct ev_loop *>. The library knows two
|
|
|
258
261
|
types of such loops, the I<default> loop, which supports signals and child
|
|
259
262
|
events, and dynamically created loops which do not.
|
|
260
263
|
|
|
261
|
-
If you use threads, a common model is to run the default event loop
|
|
262
|
-
in your main thread (or in a separate thread) and for each thread you
|
|
263
|
-
create, you also create another event loop. Libev itself does no locking
|
|
264
|
-
whatsoever, so if you mix calls to the same event loop in different
|
|
265
|
-
threads, make sure you lock (this is usually a bad idea, though, even if
|
|
266
|
-
done correctly, because it's hideous and inefficient).
|
|
267
|
-
|
|
268
264
|
=over 4
|
|
269
265
|
|
|
270
266
|
=item struct ev_loop *ev_default_loop (unsigned int flags)
|
|
@@ -360,7 +356,7 @@ but it scales phenomenally better. While poll and select usually scale
|
|
|
360
356
|
like O(total_fds) where n is the total number of fds (or the highest fd),
|
|
361
357
|
epoll scales either O(1) or O(active_fds). The epoll design has a number
|
|
362
358
|
of shortcomings, such as silently dropping events in some hard-to-detect
|
|
363
|
-
cases and
|
|
359
|
+
cases and requiring a syscall per fd change, no fork support and bad
|
|
364
360
|
support for dup.
|
|
365
361
|
|
|
366
362
|
While stopping, setting and starting an I/O watcher in the same iteration
|
|
@@ -2384,6 +2380,9 @@ it a private API).
|
|
|
2384
2380
|
will fail and all watchers will have the same priority, even though there
|
|
2385
2381
|
is an ev_pri field.
|
|
2386
2382
|
|
|
2383
|
+
=item * In libevent, the last base created gets the signals, in libev, the
|
|
2384
|
+
first base created (== the default loop) gets the signals.
|
|
2385
|
+
|
|
2387
2386
|
=item * Other members are not supported.
|
|
2388
2387
|
|
|
2389
2388
|
=item * The libev emulation is I<not> ABI compatible to libevent, you need
|
|
@@ -2635,6 +2634,16 @@ suitable for use with C<EV_A>.
|
|
|
2635
2634
|
Similar to the other two macros, this gives you the value of the default
|
|
2636
2635
|
loop, if multiple loops are supported ("ev loop default").
|
|
2637
2636
|
|
|
2637
|
+
=item C<EV_DEFAULT_UC>, C<EV_DEFAULT_UC_>
|
|
2638
|
+
|
|
2639
|
+
Usage identical to C<EV_DEFAULT> and C<EV_DEFAULT_>, but requires that the
|
|
2640
|
+
default loop has been initialised (C<UC> == unchecked). Their behaviour
|
|
2641
|
+
is undefined when the default loop has not been initialised by a previous
|
|
2642
|
+
execution of C<EV_DEFAULT>, C<EV_DEFAULT_> or C<ev_default_init (...)>.
|
|
2643
|
+
|
|
2644
|
+
It is often prudent to use C<EV_DEFAULT> when initialising the first
|
|
2645
|
+
watcher in a function but use C<EV_DEFAULT_UC> afterwards.
|
|
2646
|
+
|
|
2638
2647
|
=back
|
|
2639
2648
|
|
|
2640
2649
|
Example: Declare and initialise a check watcher, utilising the above
|
|
@@ -2739,9 +2748,9 @@ For this of course you need the m4 file:
|
|
|
2739
2748
|
|
|
2740
2749
|
=head2 PREPROCESSOR SYMBOLS/MACROS
|
|
2741
2750
|
|
|
2742
|
-
Libev can be configured via a variety of preprocessor symbols you have to
|
|
2743
|
-
before including any of its files. The default
|
|
2744
|
-
|
|
2751
|
+
Libev can be configured via a variety of preprocessor symbols you have to
|
|
2752
|
+
define before including any of its files. The default in the absense of
|
|
2753
|
+
autoconf is noted for every option.
|
|
2745
2754
|
|
|
2746
2755
|
=over 4
|
|
2747
2756
|
|
|
@@ -2777,6 +2786,14 @@ note about libraries in the description of C<EV_USE_MONOTONIC>, though.
|
|
|
2777
2786
|
If defined to be C<1>, libev will assume that C<nanosleep ()> is available
|
|
2778
2787
|
and will use it for delays. Otherwise it will use C<select ()>.
|
|
2779
2788
|
|
|
2789
|
+
=item EV_USE_EVENTFD
|
|
2790
|
+
|
|
2791
|
+
If defined to be C<1>, then libev will assume that C<eventfd ()> is
|
|
2792
|
+
available and will probe for kernel support at runtime. This will improve
|
|
2793
|
+
C<ev_signal> and C<ev_async> performance and reduce resource consumption.
|
|
2794
|
+
If undefined, it will be enabled if the headers indicate GNU/Linux + Glibc
|
|
2795
|
+
2.7 or newer, otherwise disabled.
|
|
2796
|
+
|
|
2780
2797
|
=item EV_USE_SELECT
|
|
2781
2798
|
|
|
2782
2799
|
If undefined or defined to be C<1>, libev will compile in support for the
|
|
@@ -2822,8 +2839,9 @@ takes precedence over select.
|
|
|
2822
2839
|
|
|
2823
2840
|
If defined to be C<1>, libev will compile in support for the Linux
|
|
2824
2841
|
C<epoll>(7) backend. Its availability will be detected at runtime,
|
|
2825
|
-
otherwise another method will be used as fallback. This is the
|
|
2826
|
-
|
|
2842
|
+
otherwise another method will be used as fallback. This is the preferred
|
|
2843
|
+
backend for GNU/Linux systems. If undefined, it will be enabled if the
|
|
2844
|
+
headers indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
|
|
2827
2845
|
|
|
2828
2846
|
=item EV_USE_KQUEUE
|
|
2829
2847
|
|
|
@@ -2852,7 +2870,8 @@ reserved for future expansion, works like the USE symbols above.
|
|
|
2852
2870
|
|
|
2853
2871
|
If defined to be C<1>, libev will compile in support for the Linux inotify
|
|
2854
2872
|
interface to speed up C<ev_stat> watchers. Its actual availability will
|
|
2855
|
-
be detected at runtime.
|
|
2873
|
+
be detected at runtime. If undefined, it will be enabled if the headers
|
|
2874
|
+
indicate GNU/Linux + Glibc 2.4 or newer, otherwise disabled.
|
|
2856
2875
|
|
|
2857
2876
|
=item EV_ATOMIC_T
|
|
2858
2877
|
|
|
@@ -3049,6 +3068,63 @@ And a F<ev_cpp.C> implementation file that contains libev proper and is compiled
|
|
|
3049
3068
|
#include "ev.c"
|
|
3050
3069
|
|
|
3051
3070
|
|
|
3071
|
+
=head1 THREADS AND COROUTINES
|
|
3072
|
+
|
|
3073
|
+
=head2 THREADS
|
|
3074
|
+
|
|
3075
|
+
Libev itself is completely threadsafe, but it uses no locking. This
|
|
3076
|
+
means that you can use as many loops as you want in parallel, as long as
|
|
3077
|
+
only one thread ever calls into one libev function with the same loop
|
|
3078
|
+
parameter.
|
|
3079
|
+
|
|
3080
|
+
Or put differently: calls with different loop parameters can be done in
|
|
3081
|
+
parallel from multiple threads, calls with the same loop parameter must be
|
|
3082
|
+
done serially (but can be done from different threads, as long as only one
|
|
3083
|
+
thread ever is inside a call at any point in time, e.g. by using a mutex
|
|
3084
|
+
per loop).
|
|
3085
|
+
|
|
3086
|
+
If you want to know which design is best for your problem, then I cannot
|
|
3087
|
+
help you but by giving some generic advice:
|
|
3088
|
+
|
|
3089
|
+
=over 4
|
|
3090
|
+
|
|
3091
|
+
=item * most applications have a main thread: use the default libev loop
|
|
3092
|
+
in that thread, or create a seperate thread running only the default loop.
|
|
3093
|
+
|
|
3094
|
+
This helps integrating other libraries or software modules that use libev
|
|
3095
|
+
themselves and don't care/know about threading.
|
|
3096
|
+
|
|
3097
|
+
=item * one loop per thread is usually a good model.
|
|
3098
|
+
|
|
3099
|
+
Doing this is almost never wrong, sometimes a better-performance model
|
|
3100
|
+
exists, but it is always a good start.
|
|
3101
|
+
|
|
3102
|
+
=item * other models exist, such as the leader/follower pattern, where one
|
|
3103
|
+
loop is handed through multiple threads in a kind of round-robbin fashion.
|
|
3104
|
+
|
|
3105
|
+
Chosing a model is hard - look around, learn, know that usually you cna do
|
|
3106
|
+
better than you currently do :-)
|
|
3107
|
+
|
|
3108
|
+
=item * often you need to talk to some other thread which blocks in the
|
|
3109
|
+
event loop - C<ev_async> watchers can be used to wake them up from other
|
|
3110
|
+
threads safely (or from signal contexts...).
|
|
3111
|
+
|
|
3112
|
+
=back
|
|
3113
|
+
|
|
3114
|
+
=head2 COROUTINES
|
|
3115
|
+
|
|
3116
|
+
Libev is much more accomodating to coroutines ("cooperative threads"):
|
|
3117
|
+
libev fully supports nesting calls to it's functions from different
|
|
3118
|
+
coroutines (e.g. you can call C<ev_loop> on the same loop from two
|
|
3119
|
+
different coroutines and switch freely between both coroutines running the
|
|
3120
|
+
loop, as long as you don't confuse yourself). The only exception is that
|
|
3121
|
+
you must not do this from C<ev_periodic> reschedule callbacks.
|
|
3122
|
+
|
|
3123
|
+
Care has been invested into making sure that libev does not keep local
|
|
3124
|
+
state inside C<ev_loop>, and other calls do not usually allow coroutine
|
|
3125
|
+
switches.
|
|
3126
|
+
|
|
3127
|
+
|
|
3052
3128
|
=head1 COMPLEXITIES
|
|
3053
3129
|
|
|
3054
3130
|
In this section the complexities of (many of) the algorithms used inside
|
|
@@ -86,7 +86,7 @@ poll_modify (EV_P_ int fd, int oev, int nev)
|
|
|
86
86
|
static void
|
|
87
87
|
poll_poll (EV_P_ ev_tstamp timeout)
|
|
88
88
|
{
|
|
89
|
-
|
|
89
|
+
struct pollfd *p;
|
|
90
90
|
int res = poll (polls, pollcnt, (int)ceil (timeout * 1000.));
|
|
91
91
|
|
|
92
92
|
if (expect_false (res < 0))
|
|
@@ -97,20 +97,23 @@ poll_poll (EV_P_ ev_tstamp timeout)
|
|
|
97
97
|
fd_enomem (EV_A);
|
|
98
98
|
else if (errno != EINTR)
|
|
99
99
|
syserr ("(libev) poll");
|
|
100
|
-
|
|
101
|
-
return;
|
|
102
100
|
}
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
101
|
+
else
|
|
102
|
+
for (p = polls; res; ++p)
|
|
103
|
+
if (expect_false (p->revents)) /* this expect is debatable */
|
|
104
|
+
{
|
|
105
|
+
--res;
|
|
106
|
+
|
|
107
|
+
if (expect_false (p->revents & POLLNVAL))
|
|
108
|
+
fd_kill (EV_A_ p->fd);
|
|
109
|
+
else
|
|
110
|
+
fd_event (
|
|
111
|
+
EV_A_
|
|
112
|
+
p->fd,
|
|
113
|
+
(p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
|
|
114
|
+
| (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
|
|
115
|
+
);
|
|
116
|
+
}
|
|
114
117
|
}
|
|
115
118
|
|
|
116
119
|
int inline_size
|
|
@@ -55,6 +55,9 @@ VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
|
|
|
55
55
|
VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
|
|
56
56
|
VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))
|
|
57
57
|
|
|
58
|
+
#if EV_USE_EVENTFD || EV_GENWRAP
|
|
59
|
+
VARx(int, evfd)
|
|
60
|
+
#endif
|
|
58
61
|
VAR (evpipe, int evpipe [2])
|
|
59
62
|
VARx(ev_io, pipeev)
|
|
60
63
|
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
#define backend_fudge ((loop)->backend_fudge)
|
|
14
14
|
#define backend_modify ((loop)->backend_modify)
|
|
15
15
|
#define backend_poll ((loop)->backend_poll)
|
|
16
|
+
#define evfd ((loop)->evfd)
|
|
16
17
|
#define evpipe ((loop)->evpipe)
|
|
17
18
|
#define pipeev ((loop)->pipeev)
|
|
18
19
|
#define curpid ((loop)->curpid)
|
|
@@ -84,6 +85,7 @@
|
|
|
84
85
|
#undef backend_fudge
|
|
85
86
|
#undef backend_modify
|
|
86
87
|
#undef backend_poll
|
|
88
|
+
#undef evfd
|
|
87
89
|
#undef evpipe
|
|
88
90
|
#undef pipeev
|
|
89
91
|
#undef curpid
|
|
@@ -2,9 +2,9 @@ dnl this file is part of libev, do not make local modifications
|
|
|
2
2
|
dnl http://software.schmorp.de/pkg/libev
|
|
3
3
|
|
|
4
4
|
dnl libev support
|
|
5
|
-
AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h sys/queue.h port.h poll.h sys/select.h)
|
|
5
|
+
AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h sys/queue.h port.h poll.h sys/select.h sys/eventfd.h)
|
|
6
6
|
|
|
7
|
-
AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select)
|
|
7
|
+
AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd)
|
|
8
8
|
|
|
9
9
|
AC_CHECK_FUNC(clock_gettime, [], [
|
|
10
10
|
if test -z "$LIBEV_M4_AVOID_LIBRT"; then
|