rev 0.2.1 → 0.2.2
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/CHANGES +11 -1
- data/README +10 -2
- data/ext/http11_client/http11_parser.c +256 -966
- data/ext/http11_client/http11_parser.rl +3 -3
- data/ext/libev/Changes +21 -0
- data/ext/libev/LICENSE +12 -1
- data/ext/libev/README +39 -111
- data/ext/libev/ev.c +495 -115
- data/ext/libev/ev.h +17 -5
- data/ext/libev/ev_epoll.c +1 -1
- data/ext/libev/ev_kqueue.c +1 -1
- data/ext/libev/ev_poll.c +1 -1
- data/ext/libev/ev_port.c +1 -1
- data/ext/libev/ev_select.c +25 -8
- data/ext/libev/ev_vars.h +2 -2
- data/ext/libev/ev_win32.c +1 -1
- data/ext/rev/rev_buffer.c +6 -4
- data/lib/rev.rb +1 -1
- data/lib/rev/io.rb +1 -1
- data/lib/rev/socket.rb +2 -0
- data/rev.gemspec +1 -1
- metadata +1 -1
@@ -71,11 +71,11 @@
|
|
71
71
|
# elements
|
72
72
|
token = (ascii -- (CTL | tspecials));
|
73
73
|
|
74
|
-
Reason_Phrase = (any -- CRLF)
|
75
|
-
Status_Code = digit
|
74
|
+
Reason_Phrase = (any -- CRLF)* >mark %reason_phrase;
|
75
|
+
Status_Code = digit{3} >mark %status_code;
|
76
76
|
http_number = (digit+ "." digit+) ;
|
77
77
|
HTTP_Version = ("HTTP/" http_number) >mark %http_version ;
|
78
|
-
Status_Line = HTTP_Version " " Status_Code " " Reason_Phrase :> CRLF;
|
78
|
+
Status_Line = HTTP_Version " " Status_Code " "? Reason_Phrase :> CRLF;
|
79
79
|
|
80
80
|
field_name = token+ >start_field %write_field;
|
81
81
|
field_value = any* >start_value %write_value;
|
data/ext/libev/Changes
CHANGED
@@ -1,5 +1,26 @@
|
|
1
1
|
Revision history for libev, a high-performance and full-featured event loop.
|
2
2
|
|
3
|
+
3.41 Fri May 23 18:42:54 CEST 2008
|
4
|
+
- work around an (undocumented) bug in winsocket select: if you
|
5
|
+
provide only empty fd sets then select returns WSAEINVAL. how sucky.
|
6
|
+
- improve timer scheduling stability and reduce use of time_epsilon.
|
7
|
+
- use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces
|
8
|
+
codesize and makes for better cache-efficiency.
|
9
|
+
- use 3-based 4-heap for !EV_MINIMAL. this makes better use
|
10
|
+
of cpu cache lines and gives better growth behaviour than
|
11
|
+
2-based heaps.
|
12
|
+
- cache timestamp within heap for !EV_MINIMAL, to avoid random
|
13
|
+
memory accesses.
|
14
|
+
- document/add EV_USE_4HEAP and EV_HEAP_CACHE_AT.
|
15
|
+
- fix a potential aliasing issue in ev_timer_again.
|
16
|
+
- add/document ev_periodic_at, retract direct access to ->at.
|
17
|
+
- improve ev_stat docs.
|
18
|
+
- add portability requirements section.
|
19
|
+
- fix manpage headers etc.
|
20
|
+
- normalise WSA error codes to lower range on windows.
|
21
|
+
- add consistency check code that can be called automatically
|
22
|
+
or on demand to check for internal structures (ev_loop_verify).
|
23
|
+
|
3
24
|
3.31 Wed Apr 16 20:45:04 CEST 2008
|
4
25
|
- added last minute fix for ev_poll.c by Brandon Black.
|
5
26
|
|
data/ext/libev/LICENSE
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
All files in libev are Copyright (C)2007 Marc Alexander Lehmann.
|
1
|
+
All files in libev are Copyright (C)2007,2008 Marc Alexander Lehmann.
|
2
2
|
|
3
3
|
Redistribution and use in source and binary forms, with or without
|
4
4
|
modification, are permitted provided that the following conditions are
|
@@ -23,3 +23,14 @@ DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
23
23
|
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
24
24
|
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
25
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.
|
data/ext/libev/README
CHANGED
@@ -1,128 +1,56 @@
|
|
1
1
|
libev is a high-performance event loop/event model with lots of features.
|
2
2
|
(see benchmark at http://libev.schmorp.de/bench.html)
|
3
3
|
|
4
|
-
Homepage: http://software.schmorp.de/pkg/libev
|
5
|
-
E-Mail: libev@lists.schmorp.de
|
6
|
-
Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
|
7
|
-
|
8
|
-
It is modelled (very losely) after libevent and the Event perl module,
|
9
|
-
but aims to be faster and more correct, and also more featureful. And
|
10
|
-
also smaller. Yay.
|
11
4
|
|
12
|
-
ABOUT
|
5
|
+
ABOUT
|
13
6
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
libevent (they use the libevent emulation inside libev). Configure and
|
19
|
-
Makefile stuff is also a more or less direct copy of libevent, and are
|
20
|
-
maintained by the libevent authors.
|
21
|
-
|
22
|
-
If you downloaded the libev distribution (without libevent), then
|
23
|
-
you only get the core parts of the library, meaning http and dns
|
24
|
-
client/server code and similar things are missing. Only the core event
|
25
|
-
loop is included.
|
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
|
26
11
|
|
27
|
-
|
28
|
-
|
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.
|
29
39
|
|
30
40
|
Examples of programs that embed libev: the EV perl module,
|
31
|
-
rxvt-unicode, gvpe (GNU Virtual Private Ethernet)
|
32
|
-
(http://www.deliantra.net)
|
33
|
-
|
34
|
-
DIFFERENCES AND COMPARISON TO LIBEVENT
|
35
|
-
|
36
|
-
The comparisons below are relative to libevent-1.3e.
|
37
|
-
|
38
|
-
- multiple watchers can wait for the same event without deregistering others,
|
39
|
-
both for file descriptors as well as signals.
|
40
|
-
(registering two read events on fd 10 and unregistering one will not
|
41
|
-
break the other).
|
42
|
-
|
43
|
-
- fork() is supported and can be handled
|
44
|
-
(there is no way to recover from a fork with libevent).
|
45
|
-
|
46
|
-
- timers are handled as a priority queue (important operations are O(1))
|
47
|
-
(libevent uses a much less efficient but more complex red-black tree).
|
48
|
-
|
49
|
-
- supports absolute (wallclock-based) timers in addition to relative ones,
|
50
|
-
i.e. can schedule timers to occur after n seconds, or at a specific time.
|
51
|
-
|
52
|
-
- timers can be repeating (both absolute and relative ones).
|
53
|
-
|
54
|
-
- absolute timers can have customised rescheduling hooks (suitable for cron-like
|
55
|
-
applications).
|
56
|
-
|
57
|
-
- detects time jumps and adjusts timers
|
58
|
-
(works for both forward and backward time jumps and also for absolute timers).
|
59
|
-
|
60
|
-
- race-free signal processing
|
61
|
-
(libevent may delay processing signals till after the next event).
|
62
|
-
|
63
|
-
- more efficient epoll backend
|
64
|
-
(stopping and starting an io watcher between two loop iterations will not
|
65
|
-
result in spurious epoll_ctl calls).
|
66
|
-
|
67
|
-
- usually less calls to gettimeofday and clock_gettime
|
68
|
-
(libevent calls it on every timer event change, libev twice per iteration).
|
69
|
-
|
70
|
-
- watchers use less memory
|
71
|
-
(libevent watcher on amd64: 152 bytes, libev native: <= 56 bytes, libevent emulation: 144 bytes).
|
72
|
-
|
73
|
-
- library uses less memory
|
74
|
-
(libevent allocates large data structures wether used or not, libev
|
75
|
-
scales all its data structures dynamically).
|
76
|
-
|
77
|
-
- no hardcoded arbitrary limits
|
78
|
-
(libevent contains an off-by-one bug and sometimes hardcodes limits).
|
79
|
-
|
80
|
-
- libev separates timer, signal and io watchers from each other
|
81
|
-
(libevent combines them, but with libev you can combine them yourself
|
82
|
-
by reusing the same callback and still save memory).
|
83
|
-
|
84
|
-
- simpler design, backends are potentially much simpler
|
85
|
-
(in libevent, backends have to deal with watchers, thus the problems with
|
86
|
-
wildly different semantics between diferent backends)
|
87
|
-
(epoll backend in libevent: 366 lines no caching, libev: 90 lines full caching).
|
88
|
-
|
89
|
-
- libev handles EBADF gracefully by removing the offending fds.
|
90
|
-
|
91
|
-
- libev communicates errors to the callback, libevent to the
|
92
|
-
event adder or not at all.
|
93
|
-
|
94
|
-
- doesn't rely on nonportable BSD header files.
|
95
|
-
|
96
|
-
- an event.h compatibility header exists, and can be used to run a wide
|
97
|
-
range of libevent programs unchanged (such as evdns.c).
|
98
|
-
|
99
|
-
- win32 compatibility for the core parts.
|
100
|
-
(the backend is fd-based as documented and on other platforms,
|
101
|
-
not handle-based like libevent, and can be used for both winscoket environments
|
102
|
-
and unix-like ones).
|
103
|
-
|
104
|
-
- libev can be embedded easily with or without autoconf support into
|
105
|
-
other programs, with no changes to the source code necessary.
|
106
|
-
|
107
|
-
- the event core library (ev and event layer) compiles and works both as
|
108
|
-
C and C++.
|
109
|
-
|
110
|
-
- a simple C++ wrapper that supports methods as callbacks exists.
|
111
|
-
|
112
|
-
- a full featured and widely used perl module is available.
|
113
|
-
|
114
|
-
whats missing?
|
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.
|
115
44
|
|
116
|
-
- no event-like priority support at the moment (the ev priorities work
|
117
|
-
differently, but you can use idle watchers to get a similar effect).
|
118
45
|
|
119
|
-
|
46
|
+
CONTRIBUTORS
|
120
47
|
|
121
48
|
libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
|
122
49
|
|
123
50
|
The following people sent in patches or made other noteworthy
|
124
|
-
contributions to the design (
|
125
|
-
at me, it was an
|
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):
|
126
54
|
|
127
55
|
W.C.A. Wijngaards
|
128
56
|
Christopher Layne
|
data/ext/libev/ev.c
CHANGED
@@ -128,7 +128,7 @@ extern "C" {
|
|
128
128
|
# define EV_USE_EVENTFD 0
|
129
129
|
# endif
|
130
130
|
# endif
|
131
|
-
|
131
|
+
|
132
132
|
#endif
|
133
133
|
|
134
134
|
#include <math.h>
|
@@ -237,6 +237,24 @@ extern "C" {
|
|
237
237
|
# endif
|
238
238
|
#endif
|
239
239
|
|
240
|
+
#if 0 /* debugging */
|
241
|
+
# define EV_VERIFY 3
|
242
|
+
# define EV_USE_4HEAP 1
|
243
|
+
# define EV_HEAP_CACHE_AT 1
|
244
|
+
#endif
|
245
|
+
|
246
|
+
#ifndef EV_VERIFY
|
247
|
+
# define EV_VERIFY !EV_MINIMAL
|
248
|
+
#endif
|
249
|
+
|
250
|
+
#ifndef EV_USE_4HEAP
|
251
|
+
# define EV_USE_4HEAP !EV_MINIMAL
|
252
|
+
#endif
|
253
|
+
|
254
|
+
#ifndef EV_HEAP_CACHE_AT
|
255
|
+
# define EV_HEAP_CACHE_AT !EV_MINIMAL
|
256
|
+
#endif
|
257
|
+
|
240
258
|
/* this block fixes any misconfiguration where we know we run into trouble otherwise */
|
241
259
|
|
242
260
|
#ifndef CLOCK_MONOTONIC
|
@@ -282,6 +300,12 @@ int eventfd (unsigned int initval, int flags);
|
|
282
300
|
|
283
301
|
/**/
|
284
302
|
|
303
|
+
#if EV_VERIFY >= 3
|
304
|
+
# define EV_FREQUENT_CHECK ev_loop_verify (EV_A)
|
305
|
+
#else
|
306
|
+
# define EV_FREQUENT_CHECK do { } while (0)
|
307
|
+
#endif
|
308
|
+
|
285
309
|
/*
|
286
310
|
* This is used to avoid floating point rounding problems.
|
287
311
|
* It is added to ev_rt_now when scheduling periodics
|
@@ -327,6 +351,9 @@ typedef ev_watcher *W;
|
|
327
351
|
typedef ev_watcher_list *WL;
|
328
352
|
typedef ev_watcher_time *WT;
|
329
353
|
|
354
|
+
#define ev_active(w) ((W)(w))->active
|
355
|
+
#define ev_at(w) ((WT)(w))->at
|
356
|
+
|
330
357
|
#if EV_USE_MONOTONIC
|
331
358
|
/* sig_atomic_t is used to avoid per-thread variables or locking but still */
|
332
359
|
/* giving it a reasonably high chance of working on typical architetcures */
|
@@ -421,12 +448,31 @@ typedef struct
|
|
421
448
|
} ANPENDING;
|
422
449
|
|
423
450
|
#if EV_USE_INOTIFY
|
451
|
+
/* hash table entry per inotify-id */
|
424
452
|
typedef struct
|
425
453
|
{
|
426
454
|
WL head;
|
427
455
|
} ANFS;
|
428
456
|
#endif
|
429
457
|
|
458
|
+
/* Heap Entry */
|
459
|
+
#if EV_HEAP_CACHE_AT
|
460
|
+
typedef struct {
|
461
|
+
ev_tstamp at;
|
462
|
+
WT w;
|
463
|
+
} ANHE;
|
464
|
+
|
465
|
+
#define ANHE_w(he) (he).w /* access watcher, read-write */
|
466
|
+
#define ANHE_at(he) (he).at /* access cached at, read-only */
|
467
|
+
#define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */
|
468
|
+
#else
|
469
|
+
typedef WT ANHE;
|
470
|
+
|
471
|
+
#define ANHE_w(he) (he)
|
472
|
+
#define ANHE_at(he) (he)->at
|
473
|
+
#define ANHE_at_cache(he)
|
474
|
+
#endif
|
475
|
+
|
430
476
|
#if EV_MULTIPLICITY
|
431
477
|
|
432
478
|
struct ev_loop
|
@@ -519,6 +565,8 @@ ev_sleep (ev_tstamp delay)
|
|
519
565
|
|
520
566
|
/*****************************************************************************/
|
521
567
|
|
568
|
+
#define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
|
569
|
+
|
522
570
|
int inline_size
|
523
571
|
array_nextsize (int elem, int cur, int cnt)
|
524
572
|
{
|
@@ -528,11 +576,11 @@ array_nextsize (int elem, int cur, int cnt)
|
|
528
576
|
ncur <<= 1;
|
529
577
|
while (cnt > ncur);
|
530
578
|
|
531
|
-
/* if size
|
532
|
-
if (elem * ncur >
|
579
|
+
/* if size is large, round to MALLOC_ROUND - 4 * longs to accomodate malloc overhead */
|
580
|
+
if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
|
533
581
|
{
|
534
582
|
ncur *= elem;
|
535
|
-
ncur = (ncur + elem +
|
583
|
+
ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1);
|
536
584
|
ncur = ncur - sizeof (void *) * 4;
|
537
585
|
ncur /= elem;
|
538
586
|
}
|
@@ -756,60 +804,146 @@ fd_rearm_all (EV_P)
|
|
756
804
|
|
757
805
|
/*****************************************************************************/
|
758
806
|
|
807
|
+
/*
|
808
|
+
* the heap functions want a real array index. array index 0 uis guaranteed to not
|
809
|
+
* be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives
|
810
|
+
* the branching factor of the d-tree.
|
811
|
+
*/
|
812
|
+
|
813
|
+
/*
|
814
|
+
* at the moment we allow libev the luxury of two heaps,
|
815
|
+
* a small-code-size 2-heap one and a ~1.5kb larger 4-heap
|
816
|
+
* which is more cache-efficient.
|
817
|
+
* the difference is about 5% with 50000+ watchers.
|
818
|
+
*/
|
819
|
+
#if EV_USE_4HEAP
|
820
|
+
|
821
|
+
#define DHEAP 4
|
822
|
+
#define HEAP0 (DHEAP - 1) /* index of first element in heap */
|
823
|
+
#define HPARENT(k) ((((k) - HEAP0 - 1) / DHEAP) + HEAP0)
|
824
|
+
#define UPHEAP_DONE(p,k) ((p) == (k))
|
825
|
+
|
826
|
+
/* away from the root */
|
759
827
|
void inline_speed
|
760
|
-
|
828
|
+
downheap (ANHE *heap, int N, int k)
|
761
829
|
{
|
762
|
-
|
830
|
+
ANHE he = heap [k];
|
831
|
+
ANHE *E = heap + N + HEAP0;
|
763
832
|
|
764
|
-
|
833
|
+
for (;;)
|
765
834
|
{
|
766
|
-
|
835
|
+
ev_tstamp minat;
|
836
|
+
ANHE *minpos;
|
837
|
+
ANHE *pos = heap + DHEAP * (k - HEAP0) + HEAP0 + 1;
|
767
838
|
|
768
|
-
|
839
|
+
/* find minimum child */
|
840
|
+
if (expect_true (pos + DHEAP - 1 < E))
|
841
|
+
{
|
842
|
+
/* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
|
843
|
+
if ( ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
|
844
|
+
if ( ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
|
845
|
+
if ( ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
|
846
|
+
}
|
847
|
+
else if (pos < E)
|
848
|
+
{
|
849
|
+
/* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
|
850
|
+
if (pos + 1 < E && ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
|
851
|
+
if (pos + 2 < E && ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
|
852
|
+
if (pos + 3 < E && ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
|
853
|
+
}
|
854
|
+
else
|
769
855
|
break;
|
770
856
|
|
771
|
-
|
772
|
-
|
773
|
-
|
857
|
+
if (ANHE_at (he) <= minat)
|
858
|
+
break;
|
859
|
+
|
860
|
+
heap [k] = *minpos;
|
861
|
+
ev_active (ANHE_w (*minpos)) = k;
|
862
|
+
|
863
|
+
k = minpos - heap;
|
774
864
|
}
|
775
865
|
|
776
|
-
heap [k] =
|
777
|
-
((
|
866
|
+
heap [k] = he;
|
867
|
+
ev_active (ANHE_w (he)) = k;
|
778
868
|
}
|
779
869
|
|
870
|
+
#else /* 4HEAP */
|
871
|
+
|
872
|
+
#define HEAP0 1
|
873
|
+
#define HPARENT(k) ((k) >> 1)
|
874
|
+
#define UPHEAP_DONE(p,k) (!(p))
|
875
|
+
|
876
|
+
/* away from the root */
|
780
877
|
void inline_speed
|
781
|
-
downheap (
|
878
|
+
downheap (ANHE *heap, int N, int k)
|
782
879
|
{
|
783
|
-
|
880
|
+
ANHE he = heap [k];
|
784
881
|
|
785
882
|
for (;;)
|
786
883
|
{
|
787
|
-
int c =
|
884
|
+
int c = k << 1;
|
788
885
|
|
789
|
-
if (c
|
886
|
+
if (c > N + HEAP0 - 1)
|
790
887
|
break;
|
791
888
|
|
792
|
-
c += c + 1 < N && heap [c]
|
889
|
+
c += c + 1 < N + HEAP0 && ANHE_at (heap [c]) > ANHE_at (heap [c + 1])
|
793
890
|
? 1 : 0;
|
794
891
|
|
795
|
-
if (
|
892
|
+
if (ANHE_at (he) <= ANHE_at (heap [c]))
|
796
893
|
break;
|
797
894
|
|
798
895
|
heap [k] = heap [c];
|
799
|
-
((
|
800
|
-
|
896
|
+
ev_active (ANHE_w (heap [k])) = k;
|
897
|
+
|
801
898
|
k = c;
|
802
899
|
}
|
803
900
|
|
804
|
-
heap [k] =
|
805
|
-
((
|
901
|
+
heap [k] = he;
|
902
|
+
ev_active (ANHE_w (he)) = k;
|
903
|
+
}
|
904
|
+
#endif
|
905
|
+
|
906
|
+
/* towards the root */
|
907
|
+
void inline_speed
|
908
|
+
upheap (ANHE *heap, int k)
|
909
|
+
{
|
910
|
+
ANHE he = heap [k];
|
911
|
+
|
912
|
+
for (;;)
|
913
|
+
{
|
914
|
+
int p = HPARENT (k);
|
915
|
+
|
916
|
+
if (UPHEAP_DONE (p, k) || ANHE_at (heap [p]) <= ANHE_at (he))
|
917
|
+
break;
|
918
|
+
|
919
|
+
heap [k] = heap [p];
|
920
|
+
ev_active (ANHE_w (heap [k])) = k;
|
921
|
+
k = p;
|
922
|
+
}
|
923
|
+
|
924
|
+
heap [k] = he;
|
925
|
+
ev_active (ANHE_w (he)) = k;
|
926
|
+
}
|
927
|
+
|
928
|
+
void inline_size
|
929
|
+
adjustheap (ANHE *heap, int N, int k)
|
930
|
+
{
|
931
|
+
if (k > HEAP0 && ANHE_at (heap [HPARENT (k)]) >= ANHE_at (heap [k]))
|
932
|
+
upheap (heap, k);
|
933
|
+
else
|
934
|
+
downheap (heap, N, k);
|
806
935
|
}
|
807
936
|
|
937
|
+
/* rebuild the heap: this function is used only once and executed rarely */
|
808
938
|
void inline_size
|
809
|
-
|
939
|
+
reheap (ANHE *heap, int N)
|
810
940
|
{
|
811
|
-
|
812
|
-
|
941
|
+
int i;
|
942
|
+
|
943
|
+
/* we don't use floyds algorithm, upheap is simpler and is more cache-efficient */
|
944
|
+
/* also, this is easy to implement and correct for both 2-heaps and 4-heaps */
|
945
|
+
for (i = 0; i < N; ++i)
|
946
|
+
upheap (heap, i + HEAP0);
|
813
947
|
}
|
814
948
|
|
815
949
|
/*****************************************************************************/
|
@@ -908,7 +1042,7 @@ pipecb (EV_P_ ev_io *iow, int revents)
|
|
908
1042
|
#if EV_USE_EVENTFD
|
909
1043
|
if (evfd >= 0)
|
910
1044
|
{
|
911
|
-
uint64_t counter
|
1045
|
+
uint64_t counter;
|
912
1046
|
read (evfd, &counter, sizeof (uint64_t));
|
913
1047
|
}
|
914
1048
|
else
|
@@ -1285,7 +1419,9 @@ loop_destroy (EV_P)
|
|
1285
1419
|
backend = 0;
|
1286
1420
|
}
|
1287
1421
|
|
1422
|
+
#if EV_USE_INOTIFY
|
1288
1423
|
void inline_size infy_fork (EV_P);
|
1424
|
+
#endif
|
1289
1425
|
|
1290
1426
|
void inline_size
|
1291
1427
|
loop_fork (EV_P)
|
@@ -1335,6 +1471,7 @@ loop_fork (EV_P)
|
|
1335
1471
|
}
|
1336
1472
|
|
1337
1473
|
#if EV_MULTIPLICITY
|
1474
|
+
|
1338
1475
|
struct ev_loop *
|
1339
1476
|
ev_loop_new (unsigned int flags)
|
1340
1477
|
{
|
@@ -1363,7 +1500,106 @@ ev_loop_fork (EV_P)
|
|
1363
1500
|
postfork = 1; /* must be in line with ev_default_fork */
|
1364
1501
|
}
|
1365
1502
|
|
1503
|
+
#if EV_VERIFY
|
1504
|
+
void noinline
|
1505
|
+
verify_watcher (EV_P_ W w)
|
1506
|
+
{
|
1507
|
+
assert (("watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
|
1508
|
+
|
1509
|
+
if (w->pending)
|
1510
|
+
assert (("pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
|
1511
|
+
}
|
1512
|
+
|
1513
|
+
static void noinline
|
1514
|
+
verify_heap (EV_P_ ANHE *heap, int N)
|
1515
|
+
{
|
1516
|
+
int i;
|
1517
|
+
|
1518
|
+
for (i = HEAP0; i < N + HEAP0; ++i)
|
1519
|
+
{
|
1520
|
+
assert (("active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i));
|
1521
|
+
assert (("heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i])));
|
1522
|
+
assert (("heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i]))));
|
1523
|
+
|
1524
|
+
verify_watcher (EV_A_ (W)ANHE_w (heap [i]));
|
1525
|
+
}
|
1526
|
+
}
|
1527
|
+
|
1528
|
+
static void noinline
|
1529
|
+
array_verify (EV_P_ W *ws, int cnt)
|
1530
|
+
{
|
1531
|
+
while (cnt--)
|
1532
|
+
{
|
1533
|
+
assert (("active index mismatch", ev_active (ws [cnt]) == cnt + 1));
|
1534
|
+
verify_watcher (EV_A_ ws [cnt]);
|
1535
|
+
}
|
1536
|
+
}
|
1537
|
+
#endif
|
1538
|
+
|
1539
|
+
void
|
1540
|
+
ev_loop_verify (EV_P)
|
1541
|
+
{
|
1542
|
+
#if EV_VERIFY
|
1543
|
+
int i;
|
1544
|
+
WL w;
|
1545
|
+
|
1546
|
+
assert (activecnt >= -1);
|
1547
|
+
|
1548
|
+
assert (fdchangemax >= fdchangecnt);
|
1549
|
+
for (i = 0; i < fdchangecnt; ++i)
|
1550
|
+
assert (("negative fd in fdchanges", fdchanges [i] >= 0));
|
1551
|
+
|
1552
|
+
assert (anfdmax >= 0);
|
1553
|
+
for (i = 0; i < anfdmax; ++i)
|
1554
|
+
for (w = anfds [i].head; w; w = w->next)
|
1555
|
+
{
|
1556
|
+
verify_watcher (EV_A_ (W)w);
|
1557
|
+
assert (("inactive fd watcher on anfd list", ev_active (w) == 1));
|
1558
|
+
assert (("fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
|
1559
|
+
}
|
1560
|
+
|
1561
|
+
assert (timermax >= timercnt);
|
1562
|
+
verify_heap (EV_A_ timers, timercnt);
|
1563
|
+
|
1564
|
+
#if EV_PERIODIC_ENABLE
|
1565
|
+
assert (periodicmax >= periodiccnt);
|
1566
|
+
verify_heap (EV_A_ periodics, periodiccnt);
|
1567
|
+
#endif
|
1568
|
+
|
1569
|
+
for (i = NUMPRI; i--; )
|
1570
|
+
{
|
1571
|
+
assert (pendingmax [i] >= pendingcnt [i]);
|
1572
|
+
#if EV_IDLE_ENABLE
|
1573
|
+
assert (idleall >= 0);
|
1574
|
+
assert (idlemax [i] >= idlecnt [i]);
|
1575
|
+
array_verify (EV_A_ (W *)idles [i], idlecnt [i]);
|
1576
|
+
#endif
|
1577
|
+
}
|
1578
|
+
|
1579
|
+
#if EV_FORK_ENABLE
|
1580
|
+
assert (forkmax >= forkcnt);
|
1581
|
+
array_verify (EV_A_ (W *)forks, forkcnt);
|
1582
|
+
#endif
|
1583
|
+
|
1584
|
+
#if EV_ASYNC_ENABLE
|
1585
|
+
assert (asyncmax >= asynccnt);
|
1586
|
+
array_verify (EV_A_ (W *)asyncs, asynccnt);
|
1587
|
+
#endif
|
1588
|
+
|
1589
|
+
assert (preparemax >= preparecnt);
|
1590
|
+
array_verify (EV_A_ (W *)prepares, preparecnt);
|
1591
|
+
|
1592
|
+
assert (checkmax >= checkcnt);
|
1593
|
+
array_verify (EV_A_ (W *)checks, checkcnt);
|
1594
|
+
|
1595
|
+
# if 0
|
1596
|
+
for (w = (ev_child *)childs [chain & (EV_PID_HASHSIZE - 1)]; w; w = (ev_child *)((WL)w)->next)
|
1597
|
+
for (signum = signalmax; signum--; ) if (signals [signum].gotsig)
|
1598
|
+
# endif
|
1366
1599
|
#endif
|
1600
|
+
}
|
1601
|
+
|
1602
|
+
#endif /* multiplicity */
|
1367
1603
|
|
1368
1604
|
#if EV_MULTIPLICITY
|
1369
1605
|
struct ev_loop *
|
@@ -1449,33 +1685,61 @@ call_pending (EV_P)
|
|
1449
1685
|
|
1450
1686
|
p->w->pending = 0;
|
1451
1687
|
EV_CB_INVOKE (p->w, p->events);
|
1688
|
+
EV_FREQUENT_CHECK;
|
1452
1689
|
}
|
1453
1690
|
}
|
1454
1691
|
}
|
1455
1692
|
|
1693
|
+
#if EV_IDLE_ENABLE
|
1694
|
+
void inline_size
|
1695
|
+
idle_reify (EV_P)
|
1696
|
+
{
|
1697
|
+
if (expect_false (idleall))
|
1698
|
+
{
|
1699
|
+
int pri;
|
1700
|
+
|
1701
|
+
for (pri = NUMPRI; pri--; )
|
1702
|
+
{
|
1703
|
+
if (pendingcnt [pri])
|
1704
|
+
break;
|
1705
|
+
|
1706
|
+
if (idlecnt [pri])
|
1707
|
+
{
|
1708
|
+
queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE);
|
1709
|
+
break;
|
1710
|
+
}
|
1711
|
+
}
|
1712
|
+
}
|
1713
|
+
}
|
1714
|
+
#endif
|
1715
|
+
|
1456
1716
|
void inline_size
|
1457
1717
|
timers_reify (EV_P)
|
1458
1718
|
{
|
1459
|
-
|
1719
|
+
EV_FREQUENT_CHECK;
|
1720
|
+
|
1721
|
+
while (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
|
1460
1722
|
{
|
1461
|
-
ev_timer *w = (ev_timer *)timers [
|
1723
|
+
ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
|
1462
1724
|
|
1463
1725
|
/*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/
|
1464
1726
|
|
1465
1727
|
/* first reschedule or stop timer */
|
1466
1728
|
if (w->repeat)
|
1467
1729
|
{
|
1468
|
-
|
1730
|
+
ev_at (w) += w->repeat;
|
1731
|
+
if (ev_at (w) < mn_now)
|
1732
|
+
ev_at (w) = mn_now;
|
1469
1733
|
|
1470
|
-
((
|
1471
|
-
if (((WT)w)->at < mn_now)
|
1472
|
-
((WT)w)->at = mn_now;
|
1734
|
+
assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
|
1473
1735
|
|
1474
|
-
|
1736
|
+
ANHE_at_cache (timers [HEAP0]);
|
1737
|
+
downheap (timers, timercnt, HEAP0);
|
1475
1738
|
}
|
1476
1739
|
else
|
1477
1740
|
ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
|
1478
1741
|
|
1742
|
+
EV_FREQUENT_CHECK;
|
1479
1743
|
ev_feed_event (EV_A_ (W)w, EV_TIMEOUT);
|
1480
1744
|
}
|
1481
1745
|
}
|
@@ -1484,29 +1748,47 @@ timers_reify (EV_P)
|
|
1484
1748
|
void inline_size
|
1485
1749
|
periodics_reify (EV_P)
|
1486
1750
|
{
|
1487
|
-
|
1751
|
+
EV_FREQUENT_CHECK;
|
1752
|
+
|
1753
|
+
while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
|
1488
1754
|
{
|
1489
|
-
ev_periodic *w = (ev_periodic *)periodics [
|
1755
|
+
ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
|
1490
1756
|
|
1491
1757
|
/*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/
|
1492
1758
|
|
1493
1759
|
/* first reschedule or stop timer */
|
1494
1760
|
if (w->reschedule_cb)
|
1495
1761
|
{
|
1496
|
-
(
|
1497
|
-
|
1498
|
-
|
1762
|
+
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
|
1763
|
+
|
1764
|
+
assert (("ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
|
1765
|
+
|
1766
|
+
ANHE_at_cache (periodics [HEAP0]);
|
1767
|
+
downheap (periodics, periodiccnt, HEAP0);
|
1499
1768
|
}
|
1500
1769
|
else if (w->interval)
|
1501
1770
|
{
|
1502
|
-
(
|
1503
|
-
if
|
1504
|
-
|
1505
|
-
|
1771
|
+
ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
|
1772
|
+
/* if next trigger time is not sufficiently in the future, put it there */
|
1773
|
+
/* this might happen because of floating point inexactness */
|
1774
|
+
if (ev_at (w) - ev_rt_now < TIME_EPSILON)
|
1775
|
+
{
|
1776
|
+
ev_at (w) += w->interval;
|
1777
|
+
|
1778
|
+
/* if interval is unreasonably low we might still have a time in the past */
|
1779
|
+
/* so correct this. this will make the periodic very inexact, but the user */
|
1780
|
+
/* has effectively asked to get triggered more often than possible */
|
1781
|
+
if (ev_at (w) < ev_rt_now)
|
1782
|
+
ev_at (w) = ev_rt_now;
|
1783
|
+
}
|
1784
|
+
|
1785
|
+
ANHE_at_cache (periodics [HEAP0]);
|
1786
|
+
downheap (periodics, periodiccnt, HEAP0);
|
1506
1787
|
}
|
1507
1788
|
else
|
1508
1789
|
ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
|
1509
1790
|
|
1791
|
+
EV_FREQUENT_CHECK;
|
1510
1792
|
ev_feed_event (EV_A_ (W)w, EV_PERIODIC);
|
1511
1793
|
}
|
1512
1794
|
}
|
@@ -1517,42 +1799,19 @@ periodics_reschedule (EV_P)
|
|
1517
1799
|
int i;
|
1518
1800
|
|
1519
1801
|
/* adjust periodics after time jump */
|
1520
|
-
for (i =
|
1802
|
+
for (i = HEAP0; i < periodiccnt + HEAP0; ++i)
|
1521
1803
|
{
|
1522
|
-
ev_periodic *w = (ev_periodic *)periodics [i];
|
1804
|
+
ev_periodic *w = (ev_periodic *)ANHE_w (periodics [i]);
|
1523
1805
|
|
1524
1806
|
if (w->reschedule_cb)
|
1525
|
-
(
|
1807
|
+
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
|
1526
1808
|
else if (w->interval)
|
1527
|
-
(
|
1528
|
-
}
|
1809
|
+
ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
|
1529
1810
|
|
1530
|
-
|
1531
|
-
for (i = periodiccnt >> 1; i--; )
|
1532
|
-
downheap (periodics, periodiccnt, i);
|
1533
|
-
}
|
1534
|
-
#endif
|
1535
|
-
|
1536
|
-
#if EV_IDLE_ENABLE
|
1537
|
-
void inline_size
|
1538
|
-
idle_reify (EV_P)
|
1539
|
-
{
|
1540
|
-
if (expect_false (idleall))
|
1541
|
-
{
|
1542
|
-
int pri;
|
1543
|
-
|
1544
|
-
for (pri = NUMPRI; pri--; )
|
1545
|
-
{
|
1546
|
-
if (pendingcnt [pri])
|
1547
|
-
break;
|
1548
|
-
|
1549
|
-
if (idlecnt [pri])
|
1550
|
-
{
|
1551
|
-
queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE);
|
1552
|
-
break;
|
1553
|
-
}
|
1554
|
-
}
|
1811
|
+
ANHE_at_cache (periodics [i]);
|
1555
1812
|
}
|
1813
|
+
|
1814
|
+
reheap (periodics, periodiccnt);
|
1556
1815
|
}
|
1557
1816
|
#endif
|
1558
1817
|
|
@@ -1591,7 +1850,7 @@ time_update (EV_P_ ev_tstamp max_block)
|
|
1591
1850
|
{
|
1592
1851
|
rtmn_diff = ev_rt_now - mn_now;
|
1593
1852
|
|
1594
|
-
if (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP)
|
1853
|
+
if (expect_true (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP))
|
1595
1854
|
return; /* all is well */
|
1596
1855
|
|
1597
1856
|
ev_rt_now = ev_time ();
|
@@ -1617,7 +1876,11 @@ time_update (EV_P_ ev_tstamp max_block)
|
|
1617
1876
|
#endif
|
1618
1877
|
/* adjust timers. this is easy, as the offset is the same for all of them */
|
1619
1878
|
for (i = 0; i < timercnt; ++i)
|
1620
|
-
|
1879
|
+
{
|
1880
|
+
ANHE *he = timers + i + HEAP0;
|
1881
|
+
ANHE_w (*he)->at += ev_rt_now - mn_now;
|
1882
|
+
ANHE_at_cache (*he);
|
1883
|
+
}
|
1621
1884
|
}
|
1622
1885
|
|
1623
1886
|
mn_now = ev_rt_now;
|
@@ -1647,6 +1910,10 @@ ev_loop (EV_P_ int flags)
|
|
1647
1910
|
|
1648
1911
|
do
|
1649
1912
|
{
|
1913
|
+
#if EV_VERIFY >= 2
|
1914
|
+
ev_loop_verify (EV_A);
|
1915
|
+
#endif
|
1916
|
+
|
1650
1917
|
#ifndef _WIN32
|
1651
1918
|
if (expect_false (curpid)) /* penalise the forking check even more */
|
1652
1919
|
if (expect_false (getpid () != curpid))
|
@@ -1697,14 +1964,14 @@ ev_loop (EV_P_ int flags)
|
|
1697
1964
|
|
1698
1965
|
if (timercnt)
|
1699
1966
|
{
|
1700
|
-
ev_tstamp to = (
|
1967
|
+
ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now + backend_fudge;
|
1701
1968
|
if (waittime > to) waittime = to;
|
1702
1969
|
}
|
1703
1970
|
|
1704
1971
|
#if EV_PERIODIC_ENABLE
|
1705
1972
|
if (periodiccnt)
|
1706
1973
|
{
|
1707
|
-
ev_tstamp to = (
|
1974
|
+
ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now + backend_fudge;
|
1708
1975
|
if (waittime > to) waittime = to;
|
1709
1976
|
}
|
1710
1977
|
#endif
|
@@ -1851,12 +2118,16 @@ ev_io_start (EV_P_ ev_io *w)
|
|
1851
2118
|
|
1852
2119
|
assert (("ev_io_start called with negative fd", fd >= 0));
|
1853
2120
|
|
2121
|
+
EV_FREQUENT_CHECK;
|
2122
|
+
|
1854
2123
|
ev_start (EV_A_ (W)w, 1);
|
1855
2124
|
array_needsize (ANFD, anfds, anfdmax, fd + 1, anfds_init);
|
1856
2125
|
wlist_add (&anfds[fd].head, (WL)w);
|
1857
2126
|
|
1858
2127
|
fd_change (EV_A_ fd, w->events & EV_IOFDSET | 1);
|
1859
2128
|
w->events &= ~EV_IOFDSET;
|
2129
|
+
|
2130
|
+
EV_FREQUENT_CHECK;
|
1860
2131
|
}
|
1861
2132
|
|
1862
2133
|
void noinline
|
@@ -1866,12 +2137,16 @@ ev_io_stop (EV_P_ ev_io *w)
|
|
1866
2137
|
if (expect_false (!ev_is_active (w)))
|
1867
2138
|
return;
|
1868
2139
|
|
1869
|
-
assert (("
|
2140
|
+
assert (("ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
|
2141
|
+
|
2142
|
+
EV_FREQUENT_CHECK;
|
1870
2143
|
|
1871
2144
|
wlist_del (&anfds[w->fd].head, (WL)w);
|
1872
2145
|
ev_stop (EV_A_ (W)w);
|
1873
2146
|
|
1874
2147
|
fd_change (EV_A_ w->fd, 1);
|
2148
|
+
|
2149
|
+
EV_FREQUENT_CHECK;
|
1875
2150
|
}
|
1876
2151
|
|
1877
2152
|
void noinline
|
@@ -1880,16 +2155,22 @@ ev_timer_start (EV_P_ ev_timer *w)
|
|
1880
2155
|
if (expect_false (ev_is_active (w)))
|
1881
2156
|
return;
|
1882
2157
|
|
1883
|
-
(
|
2158
|
+
ev_at (w) += mn_now;
|
1884
2159
|
|
1885
2160
|
assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
|
1886
2161
|
|
1887
|
-
|
1888
|
-
array_needsize (WT, timers, timermax, timercnt, EMPTY2);
|
1889
|
-
timers [timercnt - 1] = (WT)w;
|
1890
|
-
upheap (timers, timercnt - 1);
|
2162
|
+
EV_FREQUENT_CHECK;
|
1891
2163
|
|
1892
|
-
|
2164
|
+
++timercnt;
|
2165
|
+
ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
|
2166
|
+
array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2);
|
2167
|
+
ANHE_w (timers [ev_active (w)]) = (WT)w;
|
2168
|
+
ANHE_at_cache (timers [ev_active (w)]);
|
2169
|
+
upheap (timers, ev_active (w));
|
2170
|
+
|
2171
|
+
EV_FREQUENT_CHECK;
|
2172
|
+
|
2173
|
+
/*assert (("internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
|
1893
2174
|
}
|
1894
2175
|
|
1895
2176
|
void noinline
|
@@ -1899,19 +2180,25 @@ ev_timer_stop (EV_P_ ev_timer *w)
|
|
1899
2180
|
if (expect_false (!ev_is_active (w)))
|
1900
2181
|
return;
|
1901
2182
|
|
1902
|
-
|
2183
|
+
EV_FREQUENT_CHECK;
|
1903
2184
|
|
1904
2185
|
{
|
1905
|
-
int active = (
|
2186
|
+
int active = ev_active (w);
|
2187
|
+
|
2188
|
+
assert (("internal timer heap corruption", ANHE_w (timers [active]) == (WT)w));
|
2189
|
+
|
2190
|
+
--timercnt;
|
1906
2191
|
|
1907
|
-
if (expect_true (
|
2192
|
+
if (expect_true (active < timercnt + HEAP0))
|
1908
2193
|
{
|
1909
|
-
timers [active] = timers [timercnt];
|
2194
|
+
timers [active] = timers [timercnt + HEAP0];
|
1910
2195
|
adjustheap (timers, timercnt, active);
|
1911
2196
|
}
|
1912
2197
|
}
|
1913
2198
|
|
1914
|
-
|
2199
|
+
EV_FREQUENT_CHECK;
|
2200
|
+
|
2201
|
+
ev_at (w) -= mn_now;
|
1915
2202
|
|
1916
2203
|
ev_stop (EV_A_ (W)w);
|
1917
2204
|
}
|
@@ -1919,21 +2206,26 @@ ev_timer_stop (EV_P_ ev_timer *w)
|
|
1919
2206
|
void noinline
|
1920
2207
|
ev_timer_again (EV_P_ ev_timer *w)
|
1921
2208
|
{
|
2209
|
+
EV_FREQUENT_CHECK;
|
2210
|
+
|
1922
2211
|
if (ev_is_active (w))
|
1923
2212
|
{
|
1924
2213
|
if (w->repeat)
|
1925
2214
|
{
|
1926
|
-
(
|
1927
|
-
|
2215
|
+
ev_at (w) = mn_now + w->repeat;
|
2216
|
+
ANHE_at_cache (timers [ev_active (w)]);
|
2217
|
+
adjustheap (timers, timercnt, ev_active (w));
|
1928
2218
|
}
|
1929
2219
|
else
|
1930
2220
|
ev_timer_stop (EV_A_ w);
|
1931
2221
|
}
|
1932
2222
|
else if (w->repeat)
|
1933
2223
|
{
|
1934
|
-
w
|
2224
|
+
ev_at (w) = w->repeat;
|
1935
2225
|
ev_timer_start (EV_A_ w);
|
1936
2226
|
}
|
2227
|
+
|
2228
|
+
EV_FREQUENT_CHECK;
|
1937
2229
|
}
|
1938
2230
|
|
1939
2231
|
#if EV_PERIODIC_ENABLE
|
@@ -1944,22 +2236,28 @@ ev_periodic_start (EV_P_ ev_periodic *w)
|
|
1944
2236
|
return;
|
1945
2237
|
|
1946
2238
|
if (w->reschedule_cb)
|
1947
|
-
(
|
2239
|
+
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
|
1948
2240
|
else if (w->interval)
|
1949
2241
|
{
|
1950
2242
|
assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
|
1951
2243
|
/* this formula differs from the one in periodic_reify because we do not always round up */
|
1952
|
-
(
|
2244
|
+
ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
|
1953
2245
|
}
|
1954
2246
|
else
|
1955
|
-
(
|
2247
|
+
ev_at (w) = w->offset;
|
1956
2248
|
|
1957
|
-
|
1958
|
-
array_needsize (WT, periodics, periodicmax, periodiccnt, EMPTY2);
|
1959
|
-
periodics [periodiccnt - 1] = (WT)w;
|
1960
|
-
upheap (periodics, periodiccnt - 1);
|
2249
|
+
EV_FREQUENT_CHECK;
|
1961
2250
|
|
1962
|
-
|
2251
|
+
++periodiccnt;
|
2252
|
+
ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
|
2253
|
+
array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
|
2254
|
+
ANHE_w (periodics [ev_active (w)]) = (WT)w;
|
2255
|
+
ANHE_at_cache (periodics [ev_active (w)]);
|
2256
|
+
upheap (periodics, ev_active (w));
|
2257
|
+
|
2258
|
+
EV_FREQUENT_CHECK;
|
2259
|
+
|
2260
|
+
/*assert (("internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
|
1963
2261
|
}
|
1964
2262
|
|
1965
2263
|
void noinline
|
@@ -1969,18 +2267,24 @@ ev_periodic_stop (EV_P_ ev_periodic *w)
|
|
1969
2267
|
if (expect_false (!ev_is_active (w)))
|
1970
2268
|
return;
|
1971
2269
|
|
1972
|
-
|
2270
|
+
EV_FREQUENT_CHECK;
|
1973
2271
|
|
1974
2272
|
{
|
1975
|
-
int active = (
|
2273
|
+
int active = ev_active (w);
|
2274
|
+
|
2275
|
+
assert (("internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w));
|
2276
|
+
|
2277
|
+
--periodiccnt;
|
1976
2278
|
|
1977
|
-
if (expect_true (
|
2279
|
+
if (expect_true (active < periodiccnt + HEAP0))
|
1978
2280
|
{
|
1979
|
-
periodics [active] = periodics [periodiccnt];
|
2281
|
+
periodics [active] = periodics [periodiccnt + HEAP0];
|
1980
2282
|
adjustheap (periodics, periodiccnt, active);
|
1981
2283
|
}
|
1982
2284
|
}
|
1983
2285
|
|
2286
|
+
EV_FREQUENT_CHECK;
|
2287
|
+
|
1984
2288
|
ev_stop (EV_A_ (W)w);
|
1985
2289
|
}
|
1986
2290
|
|
@@ -2010,6 +2314,8 @@ ev_signal_start (EV_P_ ev_signal *w)
|
|
2010
2314
|
|
2011
2315
|
evpipe_init (EV_A);
|
2012
2316
|
|
2317
|
+
EV_FREQUENT_CHECK;
|
2318
|
+
|
2013
2319
|
{
|
2014
2320
|
#ifndef _WIN32
|
2015
2321
|
sigset_t full, prev;
|
@@ -2039,6 +2345,8 @@ ev_signal_start (EV_P_ ev_signal *w)
|
|
2039
2345
|
sigaction (w->signum, &sa, 0);
|
2040
2346
|
#endif
|
2041
2347
|
}
|
2348
|
+
|
2349
|
+
EV_FREQUENT_CHECK;
|
2042
2350
|
}
|
2043
2351
|
|
2044
2352
|
void noinline
|
@@ -2048,11 +2356,15 @@ ev_signal_stop (EV_P_ ev_signal *w)
|
|
2048
2356
|
if (expect_false (!ev_is_active (w)))
|
2049
2357
|
return;
|
2050
2358
|
|
2359
|
+
EV_FREQUENT_CHECK;
|
2360
|
+
|
2051
2361
|
wlist_del (&signals [w->signum - 1].head, (WL)w);
|
2052
2362
|
ev_stop (EV_A_ (W)w);
|
2053
2363
|
|
2054
2364
|
if (!signals [w->signum - 1].head)
|
2055
2365
|
signal (w->signum, SIG_DFL);
|
2366
|
+
|
2367
|
+
EV_FREQUENT_CHECK;
|
2056
2368
|
}
|
2057
2369
|
|
2058
2370
|
void
|
@@ -2064,8 +2376,12 @@ ev_child_start (EV_P_ ev_child *w)
|
|
2064
2376
|
if (expect_false (ev_is_active (w)))
|
2065
2377
|
return;
|
2066
2378
|
|
2379
|
+
EV_FREQUENT_CHECK;
|
2380
|
+
|
2067
2381
|
ev_start (EV_A_ (W)w, 1);
|
2068
2382
|
wlist_add (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
|
2383
|
+
|
2384
|
+
EV_FREQUENT_CHECK;
|
2069
2385
|
}
|
2070
2386
|
|
2071
2387
|
void
|
@@ -2075,8 +2391,12 @@ ev_child_stop (EV_P_ ev_child *w)
|
|
2075
2391
|
if (expect_false (!ev_is_active (w)))
|
2076
2392
|
return;
|
2077
2393
|
|
2394
|
+
EV_FREQUENT_CHECK;
|
2395
|
+
|
2078
2396
|
wlist_del (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
|
2079
2397
|
ev_stop (EV_A_ (W)w);
|
2398
|
+
|
2399
|
+
EV_FREQUENT_CHECK;
|
2080
2400
|
}
|
2081
2401
|
|
2082
2402
|
#if EV_STAT_ENABLE
|
@@ -2104,6 +2424,8 @@ infy_add (EV_P_ ev_stat *w)
|
|
2104
2424
|
ev_timer_start (EV_A_ &w->timer); /* this is not race-free, so we still need to recheck periodically */
|
2105
2425
|
|
2106
2426
|
/* monitor some parent directory for speedup hints */
|
2427
|
+
/* note that exceeding the hardcoded limit is not a correctness issue, */
|
2428
|
+
/* but an efficiency issue only */
|
2107
2429
|
if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096)
|
2108
2430
|
{
|
2109
2431
|
char path [4096];
|
@@ -2312,6 +2634,8 @@ ev_stat_start (EV_P_ ev_stat *w)
|
|
2312
2634
|
ev_timer_start (EV_A_ &w->timer);
|
2313
2635
|
|
2314
2636
|
ev_start (EV_A_ (W)w, 1);
|
2637
|
+
|
2638
|
+
EV_FREQUENT_CHECK;
|
2315
2639
|
}
|
2316
2640
|
|
2317
2641
|
void
|
@@ -2321,12 +2645,16 @@ ev_stat_stop (EV_P_ ev_stat *w)
|
|
2321
2645
|
if (expect_false (!ev_is_active (w)))
|
2322
2646
|
return;
|
2323
2647
|
|
2648
|
+
EV_FREQUENT_CHECK;
|
2649
|
+
|
2324
2650
|
#if EV_USE_INOTIFY
|
2325
2651
|
infy_del (EV_A_ w);
|
2326
2652
|
#endif
|
2327
2653
|
ev_timer_stop (EV_A_ &w->timer);
|
2328
2654
|
|
2329
2655
|
ev_stop (EV_A_ (W)w);
|
2656
|
+
|
2657
|
+
EV_FREQUENT_CHECK;
|
2330
2658
|
}
|
2331
2659
|
#endif
|
2332
2660
|
|
@@ -2339,6 +2667,8 @@ ev_idle_start (EV_P_ ev_idle *w)
|
|
2339
2667
|
|
2340
2668
|
pri_adjust (EV_A_ (W)w);
|
2341
2669
|
|
2670
|
+
EV_FREQUENT_CHECK;
|
2671
|
+
|
2342
2672
|
{
|
2343
2673
|
int active = ++idlecnt [ABSPRI (w)];
|
2344
2674
|
|
@@ -2348,6 +2678,8 @@ ev_idle_start (EV_P_ ev_idle *w)
|
|
2348
2678
|
array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2);
|
2349
2679
|
idles [ABSPRI (w)][active - 1] = w;
|
2350
2680
|
}
|
2681
|
+
|
2682
|
+
EV_FREQUENT_CHECK;
|
2351
2683
|
}
|
2352
2684
|
|
2353
2685
|
void
|
@@ -2357,15 +2689,19 @@ ev_idle_stop (EV_P_ ev_idle *w)
|
|
2357
2689
|
if (expect_false (!ev_is_active (w)))
|
2358
2690
|
return;
|
2359
2691
|
|
2692
|
+
EV_FREQUENT_CHECK;
|
2693
|
+
|
2360
2694
|
{
|
2361
|
-
int active = (
|
2695
|
+
int active = ev_active (w);
|
2362
2696
|
|
2363
2697
|
idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]];
|
2364
|
-
(
|
2698
|
+
ev_active (idles [ABSPRI (w)][active - 1]) = active;
|
2365
2699
|
|
2366
2700
|
ev_stop (EV_A_ (W)w);
|
2367
2701
|
--idleall;
|
2368
2702
|
}
|
2703
|
+
|
2704
|
+
EV_FREQUENT_CHECK;
|
2369
2705
|
}
|
2370
2706
|
#endif
|
2371
2707
|
|
@@ -2375,9 +2711,13 @@ ev_prepare_start (EV_P_ ev_prepare *w)
|
|
2375
2711
|
if (expect_false (ev_is_active (w)))
|
2376
2712
|
return;
|
2377
2713
|
|
2714
|
+
EV_FREQUENT_CHECK;
|
2715
|
+
|
2378
2716
|
ev_start (EV_A_ (W)w, ++preparecnt);
|
2379
2717
|
array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
|
2380
2718
|
prepares [preparecnt - 1] = w;
|
2719
|
+
|
2720
|
+
EV_FREQUENT_CHECK;
|
2381
2721
|
}
|
2382
2722
|
|
2383
2723
|
void
|
@@ -2387,13 +2727,18 @@ ev_prepare_stop (EV_P_ ev_prepare *w)
|
|
2387
2727
|
if (expect_false (!ev_is_active (w)))
|
2388
2728
|
return;
|
2389
2729
|
|
2730
|
+
EV_FREQUENT_CHECK;
|
2731
|
+
|
2390
2732
|
{
|
2391
|
-
int active = (
|
2733
|
+
int active = ev_active (w);
|
2734
|
+
|
2392
2735
|
prepares [active - 1] = prepares [--preparecnt];
|
2393
|
-
(
|
2736
|
+
ev_active (prepares [active - 1]) = active;
|
2394
2737
|
}
|
2395
2738
|
|
2396
2739
|
ev_stop (EV_A_ (W)w);
|
2740
|
+
|
2741
|
+
EV_FREQUENT_CHECK;
|
2397
2742
|
}
|
2398
2743
|
|
2399
2744
|
void
|
@@ -2402,9 +2747,13 @@ ev_check_start (EV_P_ ev_check *w)
|
|
2402
2747
|
if (expect_false (ev_is_active (w)))
|
2403
2748
|
return;
|
2404
2749
|
|
2750
|
+
EV_FREQUENT_CHECK;
|
2751
|
+
|
2405
2752
|
ev_start (EV_A_ (W)w, ++checkcnt);
|
2406
2753
|
array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
|
2407
2754
|
checks [checkcnt - 1] = w;
|
2755
|
+
|
2756
|
+
EV_FREQUENT_CHECK;
|
2408
2757
|
}
|
2409
2758
|
|
2410
2759
|
void
|
@@ -2414,13 +2763,18 @@ ev_check_stop (EV_P_ ev_check *w)
|
|
2414
2763
|
if (expect_false (!ev_is_active (w)))
|
2415
2764
|
return;
|
2416
2765
|
|
2766
|
+
EV_FREQUENT_CHECK;
|
2767
|
+
|
2417
2768
|
{
|
2418
|
-
int active = (
|
2769
|
+
int active = ev_active (w);
|
2770
|
+
|
2419
2771
|
checks [active - 1] = checks [--checkcnt];
|
2420
|
-
(
|
2772
|
+
ev_active (checks [active - 1]) = active;
|
2421
2773
|
}
|
2422
2774
|
|
2423
2775
|
ev_stop (EV_A_ (W)w);
|
2776
|
+
|
2777
|
+
EV_FREQUENT_CHECK;
|
2424
2778
|
}
|
2425
2779
|
|
2426
2780
|
#if EV_EMBED_ENABLE
|
@@ -2477,6 +2831,8 @@ ev_embed_start (EV_P_ ev_embed *w)
|
|
2477
2831
|
ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ);
|
2478
2832
|
}
|
2479
2833
|
|
2834
|
+
EV_FREQUENT_CHECK;
|
2835
|
+
|
2480
2836
|
ev_set_priority (&w->io, ev_priority (w));
|
2481
2837
|
ev_io_start (EV_A_ &w->io);
|
2482
2838
|
|
@@ -2487,6 +2843,8 @@ ev_embed_start (EV_P_ ev_embed *w)
|
|
2487
2843
|
/*ev_idle_init (&w->idle, e,bed_idle_cb);*/
|
2488
2844
|
|
2489
2845
|
ev_start (EV_A_ (W)w, 1);
|
2846
|
+
|
2847
|
+
EV_FREQUENT_CHECK;
|
2490
2848
|
}
|
2491
2849
|
|
2492
2850
|
void
|
@@ -2496,10 +2854,14 @@ ev_embed_stop (EV_P_ ev_embed *w)
|
|
2496
2854
|
if (expect_false (!ev_is_active (w)))
|
2497
2855
|
return;
|
2498
2856
|
|
2857
|
+
EV_FREQUENT_CHECK;
|
2858
|
+
|
2499
2859
|
ev_io_stop (EV_A_ &w->io);
|
2500
2860
|
ev_prepare_stop (EV_A_ &w->prepare);
|
2501
2861
|
|
2502
2862
|
ev_stop (EV_A_ (W)w);
|
2863
|
+
|
2864
|
+
EV_FREQUENT_CHECK;
|
2503
2865
|
}
|
2504
2866
|
#endif
|
2505
2867
|
|
@@ -2510,9 +2872,13 @@ ev_fork_start (EV_P_ ev_fork *w)
|
|
2510
2872
|
if (expect_false (ev_is_active (w)))
|
2511
2873
|
return;
|
2512
2874
|
|
2875
|
+
EV_FREQUENT_CHECK;
|
2876
|
+
|
2513
2877
|
ev_start (EV_A_ (W)w, ++forkcnt);
|
2514
2878
|
array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
|
2515
2879
|
forks [forkcnt - 1] = w;
|
2880
|
+
|
2881
|
+
EV_FREQUENT_CHECK;
|
2516
2882
|
}
|
2517
2883
|
|
2518
2884
|
void
|
@@ -2522,13 +2888,18 @@ ev_fork_stop (EV_P_ ev_fork *w)
|
|
2522
2888
|
if (expect_false (!ev_is_active (w)))
|
2523
2889
|
return;
|
2524
2890
|
|
2891
|
+
EV_FREQUENT_CHECK;
|
2892
|
+
|
2525
2893
|
{
|
2526
|
-
int active = (
|
2894
|
+
int active = ev_active (w);
|
2895
|
+
|
2527
2896
|
forks [active - 1] = forks [--forkcnt];
|
2528
|
-
(
|
2897
|
+
ev_active (forks [active - 1]) = active;
|
2529
2898
|
}
|
2530
2899
|
|
2531
2900
|
ev_stop (EV_A_ (W)w);
|
2901
|
+
|
2902
|
+
EV_FREQUENT_CHECK;
|
2532
2903
|
}
|
2533
2904
|
#endif
|
2534
2905
|
|
@@ -2541,9 +2912,13 @@ ev_async_start (EV_P_ ev_async *w)
|
|
2541
2912
|
|
2542
2913
|
evpipe_init (EV_A);
|
2543
2914
|
|
2915
|
+
EV_FREQUENT_CHECK;
|
2916
|
+
|
2544
2917
|
ev_start (EV_A_ (W)w, ++asynccnt);
|
2545
2918
|
array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
|
2546
2919
|
asyncs [asynccnt - 1] = w;
|
2920
|
+
|
2921
|
+
EV_FREQUENT_CHECK;
|
2547
2922
|
}
|
2548
2923
|
|
2549
2924
|
void
|
@@ -2553,13 +2928,18 @@ ev_async_stop (EV_P_ ev_async *w)
|
|
2553
2928
|
if (expect_false (!ev_is_active (w)))
|
2554
2929
|
return;
|
2555
2930
|
|
2931
|
+
EV_FREQUENT_CHECK;
|
2932
|
+
|
2556
2933
|
{
|
2557
|
-
int active = (
|
2934
|
+
int active = ev_active (w);
|
2935
|
+
|
2558
2936
|
asyncs [active - 1] = asyncs [--asynccnt];
|
2559
|
-
(
|
2937
|
+
ev_active (asyncs [active - 1]) = active;
|
2560
2938
|
}
|
2561
2939
|
|
2562
2940
|
ev_stop (EV_A_ (W)w);
|
2941
|
+
|
2942
|
+
EV_FREQUENT_CHECK;
|
2563
2943
|
}
|
2564
2944
|
|
2565
2945
|
void
|