ebb 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -66,7 +66,6 @@ class SimpleApp
66
66
  input_body.length = #{input_body.length}"
67
67
  status = 500
68
68
  end
69
-
70
69
  else
71
70
  status = 404
72
71
  body = "Undefined url"
@@ -80,6 +79,14 @@ end
80
79
 
81
80
 
82
81
  if $0 == __FILE__
82
+ # Thread.new do
83
+ # i = 0
84
+ # loop {
85
+ # puts i += 1
86
+ # sleep 1
87
+ # }
88
+ # end
89
+
83
90
  require DIR + '/../ruby_lib/ebb'
84
91
  #server = Ebb::start_server(SimpleApp.new, :unix_socket => '/tmp/ebb.sock')
85
92
  server = Ebb::start_server(SimpleApp.new, :port => 4001)
data/libev/ev.c CHANGED
@@ -41,6 +41,7 @@
41
41
  extern "C" {
42
42
  #endif
43
43
 
44
+ /* this big block deduces configuration from config.h */
44
45
  #ifndef EV_STANDALONE
45
46
  # ifdef EV_CONFIG_H
46
47
  # include EV_CONFIG_H
@@ -120,6 +121,14 @@ extern "C" {
120
121
  # endif
121
122
  # endif
122
123
 
124
+ # ifndef EV_USE_EVENTFD
125
+ # if HAVE_EVENTFD
126
+ # define EV_USE_EVENTFD 1
127
+ # else
128
+ # define EV_USE_EVENTFD 0
129
+ # endif
130
+ # endif
131
+
123
132
  #endif
124
133
 
125
134
  #include <math.h>
@@ -154,7 +163,7 @@ extern "C" {
154
163
  # endif
155
164
  #endif
156
165
 
157
- /**/
166
+ /* this block tries to deduce configuration from header-defined symbols and defaults */
158
167
 
159
168
  #ifndef EV_USE_MONOTONIC
160
169
  # define EV_USE_MONOTONIC 0
@@ -181,7 +190,11 @@ extern "C" {
181
190
  #endif
182
191
 
183
192
  #ifndef EV_USE_EPOLL
184
- # define EV_USE_EPOLL 0
193
+ # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
194
+ # define EV_USE_EPOLL 1
195
+ # else
196
+ # define EV_USE_EPOLL 0
197
+ # endif
185
198
  #endif
186
199
 
187
200
  #ifndef EV_USE_KQUEUE
@@ -193,7 +206,11 @@ extern "C" {
193
206
  #endif
194
207
 
195
208
  #ifndef EV_USE_INOTIFY
196
- # define EV_USE_INOTIFY 0
209
+ # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
210
+ # define EV_USE_INOTIFY 1
211
+ # else
212
+ # define EV_USE_INOTIFY 0
213
+ # endif
197
214
  #endif
198
215
 
199
216
  #ifndef EV_PID_HASHSIZE
@@ -212,7 +229,33 @@ extern "C" {
212
229
  # endif
213
230
  #endif
214
231
 
215
- /**/
232
+ #ifndef EV_USE_EVENTFD
233
+ # if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
234
+ # define EV_USE_EVENTFD 1
235
+ # else
236
+ # define EV_USE_EVENTFD 0
237
+ # endif
238
+ #endif
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
+
258
+ /* this block fixes any misconfiguration where we know we run into trouble otherwise */
216
259
 
217
260
  #ifndef CLOCK_MONOTONIC
218
261
  # undef EV_USE_MONOTONIC
@@ -243,8 +286,26 @@ extern "C" {
243
286
  # include <winsock.h>
244
287
  #endif
245
288
 
289
+ #if EV_USE_EVENTFD
290
+ /* our minimum requirement is glibc 2.7 which has the stub, but not the header */
291
+ # include <stdint.h>
292
+ # ifdef __cplusplus
293
+ extern "C" {
294
+ # endif
295
+ int eventfd (unsigned int initval, int flags);
296
+ # ifdef __cplusplus
297
+ }
298
+ # endif
299
+ #endif
300
+
246
301
  /**/
247
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
+
248
309
  /*
249
310
  * This is used to avoid floating point rounding problems.
250
311
  * It is added to ev_rt_now when scheduling periodics
@@ -265,7 +326,7 @@ extern "C" {
265
326
  #else
266
327
  # define expect(expr,value) (expr)
267
328
  # define noinline
268
- # if __STDC_VERSION__ < 199901L
329
+ # if __STDC_VERSION__ < 199901L && __GNUC__ < 2
269
330
  # define inline
270
331
  # endif
271
332
  #endif
@@ -290,6 +351,9 @@ typedef ev_watcher *W;
290
351
  typedef ev_watcher_list *WL;
291
352
  typedef ev_watcher_time *WT;
292
353
 
354
+ #define ev_active(w) ((W)(w))->active
355
+ #define ev_at(w) ((WT)(w))->at
356
+
293
357
  #if EV_USE_MONOTONIC
294
358
  /* sig_atomic_t is used to avoid per-thread variables or locking but still */
295
359
  /* giving it a reasonably high chance of working on typical architetcures */
@@ -325,7 +389,22 @@ syserr (const char *msg)
325
389
  }
326
390
  }
327
391
 
328
- static void *(*alloc)(void *ptr, long size);
392
+ static void *
393
+ ev_realloc_emul (void *ptr, long size)
394
+ {
395
+ /* some systems, notably openbsd and darwin, fail to properly
396
+ * implement realloc (x, 0) (as required by both ansi c-98 and
397
+ * the single unix specification, so work around them here.
398
+ */
399
+
400
+ if (size)
401
+ return realloc (ptr, size);
402
+
403
+ free (ptr);
404
+ return 0;
405
+ }
406
+
407
+ static void *(*alloc)(void *ptr, long size) = ev_realloc_emul;
329
408
 
330
409
  void
331
410
  ev_set_allocator (void *(*cb)(void *ptr, long size))
@@ -336,7 +415,7 @@ ev_set_allocator (void *(*cb)(void *ptr, long size))
336
415
  inline_speed void *
337
416
  ev_realloc (void *ptr, long size)
338
417
  {
339
- ptr = alloc ? alloc (ptr, size) : realloc (ptr, size);
418
+ ptr = alloc (ptr, size);
340
419
 
341
420
  if (!ptr && size)
342
421
  {
@@ -369,12 +448,31 @@ typedef struct
369
448
  } ANPENDING;
370
449
 
371
450
  #if EV_USE_INOTIFY
451
+ /* hash table entry per inotify-id */
372
452
  typedef struct
373
453
  {
374
454
  WL head;
375
455
  } ANFS;
376
456
  #endif
377
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
+
378
476
  #if EV_MULTIPLICITY
379
477
 
380
478
  struct ev_loop
@@ -467,6 +565,8 @@ ev_sleep (ev_tstamp delay)
467
565
 
468
566
  /*****************************************************************************/
469
567
 
568
+ #define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
569
+
470
570
  int inline_size
471
571
  array_nextsize (int elem, int cur, int cnt)
472
572
  {
@@ -476,11 +576,11 @@ array_nextsize (int elem, int cur, int cnt)
476
576
  ncur <<= 1;
477
577
  while (cnt > ncur);
478
578
 
479
- /* if size > 4096, round to 4096 - 4 * longs to accomodate malloc overhead */
480
- if (elem * ncur > 4096)
579
+ /* if size is large, round to MALLOC_ROUND - 4 * longs to accomodate malloc overhead */
580
+ if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
481
581
  {
482
582
  ncur *= elem;
483
- ncur = (ncur + elem + 4095 + sizeof (void *) * 4) & ~4095;
583
+ ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1);
484
584
  ncur = ncur - sizeof (void *) * 4;
485
585
  ncur /= elem;
486
586
  }
@@ -704,60 +804,146 @@ fd_rearm_all (EV_P)
704
804
 
705
805
  /*****************************************************************************/
706
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 */
707
827
  void inline_speed
708
- upheap (WT *heap, int k)
828
+ downheap (ANHE *heap, int N, int k)
709
829
  {
710
- WT w = heap [k];
830
+ ANHE he = heap [k];
831
+ ANHE *E = heap + N + HEAP0;
711
832
 
712
- while (k)
833
+ for (;;)
713
834
  {
714
- int p = (k - 1) >> 1;
835
+ ev_tstamp minat;
836
+ ANHE *minpos;
837
+ ANHE *pos = heap + DHEAP * (k - HEAP0) + HEAP0 + 1;
838
+
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
855
+ break;
715
856
 
716
- if (heap [p]->at <= w->at)
857
+ if (ANHE_at (he) <= minat)
717
858
  break;
718
859
 
719
- heap [k] = heap [p];
720
- ((W)heap [k])->active = k + 1;
721
- k = p;
860
+ heap [k] = *minpos;
861
+ ev_active (ANHE_w (*minpos)) = k;
862
+
863
+ k = minpos - heap;
722
864
  }
723
865
 
724
- heap [k] = w;
725
- ((W)heap [k])->active = k + 1;
866
+ heap [k] = he;
867
+ ev_active (ANHE_w (he)) = k;
726
868
  }
727
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 */
728
877
  void inline_speed
729
- downheap (WT *heap, int N, int k)
878
+ downheap (ANHE *heap, int N, int k)
730
879
  {
731
- WT w = heap [k];
880
+ ANHE he = heap [k];
732
881
 
733
882
  for (;;)
734
883
  {
735
- int c = (k << 1) + 1;
884
+ int c = k << 1;
736
885
 
737
- if (c >= N)
886
+ if (c > N + HEAP0 - 1)
738
887
  break;
739
888
 
740
- c += c + 1 < N && heap [c]->at > heap [c + 1]->at
889
+ c += c + 1 < N + HEAP0 && ANHE_at (heap [c]) > ANHE_at (heap [c + 1])
741
890
  ? 1 : 0;
742
891
 
743
- if (w->at <= heap [c]->at)
892
+ if (ANHE_at (he) <= ANHE_at (heap [c]))
744
893
  break;
745
894
 
746
895
  heap [k] = heap [c];
747
- ((W)heap [k])->active = k + 1;
748
-
896
+ ev_active (ANHE_w (heap [k])) = k;
897
+
749
898
  k = c;
750
899
  }
751
900
 
752
- heap [k] = w;
753
- ((W)heap [k])->active = k + 1;
901
+ heap [k] = he;
902
+ ev_active (ANHE_w (he)) = k;
754
903
  }
904
+ #endif
905
+
906
+ /* towards the root */
907
+ void inline_speed
908
+ upheap (ANHE *heap, int k)
909
+ {
910
+ ANHE he = heap [k];
755
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);
935
+ }
936
+
937
+ /* rebuild the heap: this function is used only once and executed rarely */
756
938
  void inline_size
757
- adjustheap (WT *heap, int N, int k)
939
+ reheap (ANHE *heap, int N)
758
940
  {
759
- upheap (heap, k);
760
- downheap (heap, N, k);
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);
761
947
  }
762
948
 
763
949
  /*****************************************************************************/
@@ -804,13 +990,24 @@ evpipe_init (EV_P)
804
990
  {
805
991
  if (!ev_is_active (&pipeev))
806
992
  {
807
- while (pipe (evpipe))
808
- syserr ("(libev) error creating signal/async pipe");
993
+ #if EV_USE_EVENTFD
994
+ if ((evfd = eventfd (0, 0)) >= 0)
995
+ {
996
+ evpipe [0] = -1;
997
+ fd_intern (evfd);
998
+ ev_io_set (&pipeev, evfd, EV_READ);
999
+ }
1000
+ else
1001
+ #endif
1002
+ {
1003
+ while (pipe (evpipe))
1004
+ syserr ("(libev) error creating signal/async pipe");
809
1005
 
810
- fd_intern (evpipe [0]);
811
- fd_intern (evpipe [1]);
1006
+ fd_intern (evpipe [0]);
1007
+ fd_intern (evpipe [1]);
1008
+ ev_io_set (&pipeev, evpipe [0], EV_READ);
1009
+ }
812
1010
 
813
- ev_io_set (&pipeev, evpipe [0], EV_READ);
814
1011
  ev_io_start (EV_A_ &pipeev);
815
1012
  ev_unref (EV_A); /* watcher should not keep loop alive */
816
1013
  }
@@ -824,7 +1021,16 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
824
1021
  int old_errno = errno; /* save errno because write might clobber it */
825
1022
 
826
1023
  *flag = 1;
827
- write (evpipe [1], &old_errno, 1);
1024
+
1025
+ #if EV_USE_EVENTFD
1026
+ if (evfd >= 0)
1027
+ {
1028
+ uint64_t counter = 1;
1029
+ write (evfd, &counter, sizeof (uint64_t));
1030
+ }
1031
+ else
1032
+ #endif
1033
+ write (evpipe [1], &old_errno, 1);
828
1034
 
829
1035
  errno = old_errno;
830
1036
  }
@@ -833,10 +1039,18 @@ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
833
1039
  static void
834
1040
  pipecb (EV_P_ ev_io *iow, int revents)
835
1041
  {
836
- {
837
- int dummy;
838
- read (evpipe [0], &dummy, 1);
839
- }
1042
+ #if EV_USE_EVENTFD
1043
+ if (evfd >= 0)
1044
+ {
1045
+ uint64_t counter;
1046
+ read (evfd, &counter, sizeof (uint64_t));
1047
+ }
1048
+ else
1049
+ #endif
1050
+ {
1051
+ char dummy;
1052
+ read (evpipe [0], &dummy, 1);
1053
+ }
840
1054
 
841
1055
  if (gotsig && ev_is_default_loop (EV_A))
842
1056
  {
@@ -1107,7 +1321,7 @@ loop_init (EV_P_ unsigned int flags)
1107
1321
  && getenv ("LIBEV_FLAGS"))
1108
1322
  flags = atoi (getenv ("LIBEV_FLAGS"));
1109
1323
 
1110
- if (!(flags & 0x0000ffffUL))
1324
+ if (!(flags & 0x0000ffffU))
1111
1325
  flags |= ev_recommended_backends ();
1112
1326
 
1113
1327
  #if EV_USE_PORT
@@ -1141,8 +1355,16 @@ loop_destroy (EV_P)
1141
1355
  ev_ref (EV_A); /* signal watcher */
1142
1356
  ev_io_stop (EV_A_ &pipeev);
1143
1357
 
1144
- close (evpipe [0]); evpipe [0] = 0;
1145
- close (evpipe [1]); evpipe [1] = 0;
1358
+ #if EV_USE_EVENTFD
1359
+ if (evfd >= 0)
1360
+ close (evfd);
1361
+ #endif
1362
+
1363
+ if (evpipe [0] >= 0)
1364
+ {
1365
+ close (evpipe [0]);
1366
+ close (evpipe [1]);
1367
+ }
1146
1368
  }
1147
1369
 
1148
1370
  #if EV_USE_INOTIFY
@@ -1197,7 +1419,9 @@ loop_destroy (EV_P)
1197
1419
  backend = 0;
1198
1420
  }
1199
1421
 
1422
+ #if EV_USE_INOTIFY
1200
1423
  void inline_size infy_fork (EV_P);
1424
+ #endif
1201
1425
 
1202
1426
  void inline_size
1203
1427
  loop_fork (EV_P)
@@ -1226,8 +1450,17 @@ loop_fork (EV_P)
1226
1450
 
1227
1451
  ev_ref (EV_A);
1228
1452
  ev_io_stop (EV_A_ &pipeev);
1229
- close (evpipe [0]);
1230
- close (evpipe [1]);
1453
+
1454
+ #if EV_USE_EVENTFD
1455
+ if (evfd >= 0)
1456
+ close (evfd);
1457
+ #endif
1458
+
1459
+ if (evpipe [0] >= 0)
1460
+ {
1461
+ close (evpipe [0]);
1462
+ close (evpipe [1]);
1463
+ }
1231
1464
 
1232
1465
  evpipe_init (EV_A);
1233
1466
  /* now iterate over everything, in case we missed something */
@@ -1238,6 +1471,7 @@ loop_fork (EV_P)
1238
1471
  }
1239
1472
 
1240
1473
  #if EV_MULTIPLICITY
1474
+
1241
1475
  struct ev_loop *
1242
1476
  ev_loop_new (unsigned int flags)
1243
1477
  {
@@ -1266,8 +1500,107 @@ ev_loop_fork (EV_P)
1266
1500
  postfork = 1; /* must be in line with ev_default_fork */
1267
1501
  }
1268
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
+ }
1269
1537
  #endif
1270
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
1599
+ #endif
1600
+ }
1601
+
1602
+ #endif /* multiplicity */
1603
+
1271
1604
  #if EV_MULTIPLICITY
1272
1605
  struct ev_loop *
1273
1606
  ev_default_loop_init (unsigned int flags)
@@ -1352,33 +1685,61 @@ call_pending (EV_P)
1352
1685
 
1353
1686
  p->w->pending = 0;
1354
1687
  EV_CB_INVOKE (p->w, p->events);
1688
+ EV_FREQUENT_CHECK;
1355
1689
  }
1356
1690
  }
1357
1691
  }
1358
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
+
1359
1716
  void inline_size
1360
1717
  timers_reify (EV_P)
1361
1718
  {
1362
- while (timercnt && ((WT)timers [0])->at <= mn_now)
1719
+ EV_FREQUENT_CHECK;
1720
+
1721
+ while (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
1363
1722
  {
1364
- ev_timer *w = (ev_timer *)timers [0];
1723
+ ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
1365
1724
 
1366
1725
  /*assert (("inactive timer on timer heap detected", ev_is_active (w)));*/
1367
1726
 
1368
1727
  /* first reschedule or stop timer */
1369
1728
  if (w->repeat)
1370
1729
  {
1371
- assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
1730
+ ev_at (w) += w->repeat;
1731
+ if (ev_at (w) < mn_now)
1732
+ ev_at (w) = mn_now;
1372
1733
 
1373
- ((WT)w)->at += w->repeat;
1374
- if (((WT)w)->at < mn_now)
1375
- ((WT)w)->at = mn_now;
1734
+ assert (("negative ev_timer repeat value found while processing timers", w->repeat > 0.));
1376
1735
 
1377
- downheap (timers, timercnt, 0);
1736
+ ANHE_at_cache (timers [HEAP0]);
1737
+ downheap (timers, timercnt, HEAP0);
1378
1738
  }
1379
1739
  else
1380
1740
  ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
1381
1741
 
1742
+ EV_FREQUENT_CHECK;
1382
1743
  ev_feed_event (EV_A_ (W)w, EV_TIMEOUT);
1383
1744
  }
1384
1745
  }
@@ -1387,29 +1748,47 @@ timers_reify (EV_P)
1387
1748
  void inline_size
1388
1749
  periodics_reify (EV_P)
1389
1750
  {
1390
- while (periodiccnt && ((WT)periodics [0])->at <= ev_rt_now)
1751
+ EV_FREQUENT_CHECK;
1752
+
1753
+ while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
1391
1754
  {
1392
- ev_periodic *w = (ev_periodic *)periodics [0];
1755
+ ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
1393
1756
 
1394
1757
  /*assert (("inactive timer on periodic heap detected", ev_is_active (w)));*/
1395
1758
 
1396
1759
  /* first reschedule or stop timer */
1397
1760
  if (w->reschedule_cb)
1398
1761
  {
1399
- ((WT)w)->at = w->reschedule_cb (w, ev_rt_now + TIME_EPSILON);
1400
- assert (("ev_periodic reschedule callback returned time in the past", ((WT)w)->at > ev_rt_now));
1401
- downheap (periodics, periodiccnt, 0);
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);
1402
1768
  }
1403
1769
  else if (w->interval)
1404
1770
  {
1405
- ((WT)w)->at = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
1406
- if (((WT)w)->at - ev_rt_now <= TIME_EPSILON) ((WT)w)->at += w->interval;
1407
- assert (("ev_periodic timeout in the past detected while processing timers, negative interval?", ((WT)w)->at > ev_rt_now));
1408
- downheap (periodics, periodiccnt, 0);
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);
1409
1787
  }
1410
1788
  else
1411
1789
  ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
1412
1790
 
1791
+ EV_FREQUENT_CHECK;
1413
1792
  ev_feed_event (EV_A_ (W)w, EV_PERIODIC);
1414
1793
  }
1415
1794
  }
@@ -1420,42 +1799,19 @@ periodics_reschedule (EV_P)
1420
1799
  int i;
1421
1800
 
1422
1801
  /* adjust periodics after time jump */
1423
- for (i = 0; i < periodiccnt; ++i)
1802
+ for (i = HEAP0; i < periodiccnt + HEAP0; ++i)
1424
1803
  {
1425
- ev_periodic *w = (ev_periodic *)periodics [i];
1804
+ ev_periodic *w = (ev_periodic *)ANHE_w (periodics [i]);
1426
1805
 
1427
1806
  if (w->reschedule_cb)
1428
- ((WT)w)->at = w->reschedule_cb (w, ev_rt_now);
1807
+ ev_at (w) = w->reschedule_cb (w, ev_rt_now);
1429
1808
  else if (w->interval)
1430
- ((WT)w)->at = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
1431
- }
1432
-
1433
- /* now rebuild the heap */
1434
- for (i = periodiccnt >> 1; i--; )
1435
- downheap (periodics, periodiccnt, i);
1436
- }
1437
- #endif
1438
-
1439
- #if EV_IDLE_ENABLE
1440
- void inline_size
1441
- idle_reify (EV_P)
1442
- {
1443
- if (expect_false (idleall))
1444
- {
1445
- int pri;
1809
+ ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
1446
1810
 
1447
- for (pri = NUMPRI; pri--; )
1448
- {
1449
- if (pendingcnt [pri])
1450
- break;
1451
-
1452
- if (idlecnt [pri])
1453
- {
1454
- queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE);
1455
- break;
1456
- }
1457
- }
1811
+ ANHE_at_cache (periodics [i]);
1458
1812
  }
1813
+
1814
+ reheap (periodics, periodiccnt);
1459
1815
  }
1460
1816
  #endif
1461
1817
 
@@ -1494,7 +1850,7 @@ time_update (EV_P_ ev_tstamp max_block)
1494
1850
  {
1495
1851
  rtmn_diff = ev_rt_now - mn_now;
1496
1852
 
1497
- if (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP)
1853
+ if (expect_true (fabs (odiff - rtmn_diff) < MIN_TIMEJUMP))
1498
1854
  return; /* all is well */
1499
1855
 
1500
1856
  ev_rt_now = ev_time ();
@@ -1520,7 +1876,11 @@ time_update (EV_P_ ev_tstamp max_block)
1520
1876
  #endif
1521
1877
  /* adjust timers. this is easy, as the offset is the same for all of them */
1522
1878
  for (i = 0; i < timercnt; ++i)
1523
- ((WT)timers [i])->at += ev_rt_now - mn_now;
1879
+ {
1880
+ ANHE *he = timers + i + HEAP0;
1881
+ ANHE_w (*he)->at += ev_rt_now - mn_now;
1882
+ ANHE_at_cache (*he);
1883
+ }
1524
1884
  }
1525
1885
 
1526
1886
  mn_now = ev_rt_now;
@@ -1550,6 +1910,10 @@ ev_loop (EV_P_ int flags)
1550
1910
 
1551
1911
  do
1552
1912
  {
1913
+ #if EV_VERIFY >= 2
1914
+ ev_loop_verify (EV_A);
1915
+ #endif
1916
+
1553
1917
  #ifndef _WIN32
1554
1918
  if (expect_false (curpid)) /* penalise the forking check even more */
1555
1919
  if (expect_false (getpid () != curpid))
@@ -1600,14 +1964,14 @@ ev_loop (EV_P_ int flags)
1600
1964
 
1601
1965
  if (timercnt)
1602
1966
  {
1603
- ev_tstamp to = ((WT)timers [0])->at - mn_now + backend_fudge;
1967
+ ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now + backend_fudge;
1604
1968
  if (waittime > to) waittime = to;
1605
1969
  }
1606
1970
 
1607
1971
  #if EV_PERIODIC_ENABLE
1608
1972
  if (periodiccnt)
1609
1973
  {
1610
- ev_tstamp to = ((WT)periodics [0])->at - ev_rt_now + backend_fudge;
1974
+ ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now + backend_fudge;
1611
1975
  if (waittime > to) waittime = to;
1612
1976
  }
1613
1977
  #endif
@@ -1754,12 +2118,16 @@ ev_io_start (EV_P_ ev_io *w)
1754
2118
 
1755
2119
  assert (("ev_io_start called with negative fd", fd >= 0));
1756
2120
 
2121
+ EV_FREQUENT_CHECK;
2122
+
1757
2123
  ev_start (EV_A_ (W)w, 1);
1758
2124
  array_needsize (ANFD, anfds, anfdmax, fd + 1, anfds_init);
1759
2125
  wlist_add (&anfds[fd].head, (WL)w);
1760
2126
 
1761
2127
  fd_change (EV_A_ fd, w->events & EV_IOFDSET | 1);
1762
2128
  w->events &= ~EV_IOFDSET;
2129
+
2130
+ EV_FREQUENT_CHECK;
1763
2131
  }
1764
2132
 
1765
2133
  void noinline
@@ -1769,12 +2137,16 @@ ev_io_stop (EV_P_ ev_io *w)
1769
2137
  if (expect_false (!ev_is_active (w)))
1770
2138
  return;
1771
2139
 
1772
- assert (("ev_io_start called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
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;
1773
2143
 
1774
2144
  wlist_del (&anfds[w->fd].head, (WL)w);
1775
2145
  ev_stop (EV_A_ (W)w);
1776
2146
 
1777
2147
  fd_change (EV_A_ w->fd, 1);
2148
+
2149
+ EV_FREQUENT_CHECK;
1778
2150
  }
1779
2151
 
1780
2152
  void noinline
@@ -1783,16 +2155,22 @@ ev_timer_start (EV_P_ ev_timer *w)
1783
2155
  if (expect_false (ev_is_active (w)))
1784
2156
  return;
1785
2157
 
1786
- ((WT)w)->at += mn_now;
2158
+ ev_at (w) += mn_now;
1787
2159
 
1788
2160
  assert (("ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
1789
2161
 
1790
- ev_start (EV_A_ (W)w, ++timercnt);
1791
- array_needsize (WT, timers, timermax, timercnt, EMPTY2);
1792
- timers [timercnt - 1] = (WT)w;
1793
- upheap (timers, timercnt - 1);
2162
+ EV_FREQUENT_CHECK;
2163
+
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;
1794
2172
 
1795
- /*assert (("internal timer heap corruption", timers [((W)w)->active - 1] == w));*/
2173
+ /*assert (("internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
1796
2174
  }
1797
2175
 
1798
2176
  void noinline
@@ -1802,19 +2180,25 @@ ev_timer_stop (EV_P_ ev_timer *w)
1802
2180
  if (expect_false (!ev_is_active (w)))
1803
2181
  return;
1804
2182
 
1805
- assert (("internal timer heap corruption", timers [((W)w)->active - 1] == (WT)w));
2183
+ EV_FREQUENT_CHECK;
1806
2184
 
1807
2185
  {
1808
- int active = ((W)w)->active;
2186
+ int active = ev_active (w);
1809
2187
 
1810
- if (expect_true (--active < --timercnt))
2188
+ assert (("internal timer heap corruption", ANHE_w (timers [active]) == (WT)w));
2189
+
2190
+ --timercnt;
2191
+
2192
+ if (expect_true (active < timercnt + HEAP0))
1811
2193
  {
1812
- timers [active] = timers [timercnt];
2194
+ timers [active] = timers [timercnt + HEAP0];
1813
2195
  adjustheap (timers, timercnt, active);
1814
2196
  }
1815
2197
  }
1816
2198
 
1817
- ((WT)w)->at -= mn_now;
2199
+ EV_FREQUENT_CHECK;
2200
+
2201
+ ev_at (w) -= mn_now;
1818
2202
 
1819
2203
  ev_stop (EV_A_ (W)w);
1820
2204
  }
@@ -1822,21 +2206,26 @@ ev_timer_stop (EV_P_ ev_timer *w)
1822
2206
  void noinline
1823
2207
  ev_timer_again (EV_P_ ev_timer *w)
1824
2208
  {
2209
+ EV_FREQUENT_CHECK;
2210
+
1825
2211
  if (ev_is_active (w))
1826
2212
  {
1827
2213
  if (w->repeat)
1828
2214
  {
1829
- ((WT)w)->at = mn_now + w->repeat;
1830
- adjustheap (timers, timercnt, ((W)w)->active - 1);
2215
+ ev_at (w) = mn_now + w->repeat;
2216
+ ANHE_at_cache (timers [ev_active (w)]);
2217
+ adjustheap (timers, timercnt, ev_active (w));
1831
2218
  }
1832
2219
  else
1833
2220
  ev_timer_stop (EV_A_ w);
1834
2221
  }
1835
2222
  else if (w->repeat)
1836
2223
  {
1837
- w->at = w->repeat;
2224
+ ev_at (w) = w->repeat;
1838
2225
  ev_timer_start (EV_A_ w);
1839
2226
  }
2227
+
2228
+ EV_FREQUENT_CHECK;
1840
2229
  }
1841
2230
 
1842
2231
  #if EV_PERIODIC_ENABLE
@@ -1847,22 +2236,28 @@ ev_periodic_start (EV_P_ ev_periodic *w)
1847
2236
  return;
1848
2237
 
1849
2238
  if (w->reschedule_cb)
1850
- ((WT)w)->at = w->reschedule_cb (w, ev_rt_now);
2239
+ ev_at (w) = w->reschedule_cb (w, ev_rt_now);
1851
2240
  else if (w->interval)
1852
2241
  {
1853
2242
  assert (("ev_periodic_start called with negative interval value", w->interval >= 0.));
1854
2243
  /* this formula differs from the one in periodic_reify because we do not always round up */
1855
- ((WT)w)->at = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
2244
+ ev_at (w) = w->offset + ceil ((ev_rt_now - w->offset) / w->interval) * w->interval;
1856
2245
  }
1857
2246
  else
1858
- ((WT)w)->at = w->offset;
2247
+ ev_at (w) = w->offset;
2248
+
2249
+ EV_FREQUENT_CHECK;
2250
+
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));
1859
2257
 
1860
- ev_start (EV_A_ (W)w, ++periodiccnt);
1861
- array_needsize (WT, periodics, periodicmax, periodiccnt, EMPTY2);
1862
- periodics [periodiccnt - 1] = (WT)w;
1863
- upheap (periodics, periodiccnt - 1);
2258
+ EV_FREQUENT_CHECK;
1864
2259
 
1865
- /*assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == w));*/
2260
+ /*assert (("internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
1866
2261
  }
1867
2262
 
1868
2263
  void noinline
@@ -1872,18 +2267,24 @@ ev_periodic_stop (EV_P_ ev_periodic *w)
1872
2267
  if (expect_false (!ev_is_active (w)))
1873
2268
  return;
1874
2269
 
1875
- assert (("internal periodic heap corruption", periodics [((W)w)->active - 1] == (WT)w));
2270
+ EV_FREQUENT_CHECK;
1876
2271
 
1877
2272
  {
1878
- int active = ((W)w)->active;
2273
+ int active = ev_active (w);
2274
+
2275
+ assert (("internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w));
2276
+
2277
+ --periodiccnt;
1879
2278
 
1880
- if (expect_true (--active < --periodiccnt))
2279
+ if (expect_true (active < periodiccnt + HEAP0))
1881
2280
  {
1882
- periodics [active] = periodics [periodiccnt];
2281
+ periodics [active] = periodics [periodiccnt + HEAP0];
1883
2282
  adjustheap (periodics, periodiccnt, active);
1884
2283
  }
1885
2284
  }
1886
2285
 
2286
+ EV_FREQUENT_CHECK;
2287
+
1887
2288
  ev_stop (EV_A_ (W)w);
1888
2289
  }
1889
2290
 
@@ -1913,6 +2314,8 @@ ev_signal_start (EV_P_ ev_signal *w)
1913
2314
 
1914
2315
  evpipe_init (EV_A);
1915
2316
 
2317
+ EV_FREQUENT_CHECK;
2318
+
1916
2319
  {
1917
2320
  #ifndef _WIN32
1918
2321
  sigset_t full, prev;
@@ -1942,6 +2345,8 @@ ev_signal_start (EV_P_ ev_signal *w)
1942
2345
  sigaction (w->signum, &sa, 0);
1943
2346
  #endif
1944
2347
  }
2348
+
2349
+ EV_FREQUENT_CHECK;
1945
2350
  }
1946
2351
 
1947
2352
  void noinline
@@ -1951,11 +2356,15 @@ ev_signal_stop (EV_P_ ev_signal *w)
1951
2356
  if (expect_false (!ev_is_active (w)))
1952
2357
  return;
1953
2358
 
2359
+ EV_FREQUENT_CHECK;
2360
+
1954
2361
  wlist_del (&signals [w->signum - 1].head, (WL)w);
1955
2362
  ev_stop (EV_A_ (W)w);
1956
2363
 
1957
2364
  if (!signals [w->signum - 1].head)
1958
2365
  signal (w->signum, SIG_DFL);
2366
+
2367
+ EV_FREQUENT_CHECK;
1959
2368
  }
1960
2369
 
1961
2370
  void
@@ -1967,8 +2376,12 @@ ev_child_start (EV_P_ ev_child *w)
1967
2376
  if (expect_false (ev_is_active (w)))
1968
2377
  return;
1969
2378
 
2379
+ EV_FREQUENT_CHECK;
2380
+
1970
2381
  ev_start (EV_A_ (W)w, 1);
1971
2382
  wlist_add (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
2383
+
2384
+ EV_FREQUENT_CHECK;
1972
2385
  }
1973
2386
 
1974
2387
  void
@@ -1978,8 +2391,12 @@ ev_child_stop (EV_P_ ev_child *w)
1978
2391
  if (expect_false (!ev_is_active (w)))
1979
2392
  return;
1980
2393
 
2394
+ EV_FREQUENT_CHECK;
2395
+
1981
2396
  wlist_del (&childs [w->pid & (EV_PID_HASHSIZE - 1)], (WL)w);
1982
2397
  ev_stop (EV_A_ (W)w);
2398
+
2399
+ EV_FREQUENT_CHECK;
1983
2400
  }
1984
2401
 
1985
2402
  #if EV_STAT_ENABLE
@@ -2007,6 +2424,8 @@ infy_add (EV_P_ ev_stat *w)
2007
2424
  ev_timer_start (EV_A_ &w->timer); /* this is not race-free, so we still need to recheck periodically */
2008
2425
 
2009
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 */
2010
2429
  if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096)
2011
2430
  {
2012
2431
  char path [4096];
@@ -2215,6 +2634,8 @@ ev_stat_start (EV_P_ ev_stat *w)
2215
2634
  ev_timer_start (EV_A_ &w->timer);
2216
2635
 
2217
2636
  ev_start (EV_A_ (W)w, 1);
2637
+
2638
+ EV_FREQUENT_CHECK;
2218
2639
  }
2219
2640
 
2220
2641
  void
@@ -2224,12 +2645,16 @@ ev_stat_stop (EV_P_ ev_stat *w)
2224
2645
  if (expect_false (!ev_is_active (w)))
2225
2646
  return;
2226
2647
 
2648
+ EV_FREQUENT_CHECK;
2649
+
2227
2650
  #if EV_USE_INOTIFY
2228
2651
  infy_del (EV_A_ w);
2229
2652
  #endif
2230
2653
  ev_timer_stop (EV_A_ &w->timer);
2231
2654
 
2232
2655
  ev_stop (EV_A_ (W)w);
2656
+
2657
+ EV_FREQUENT_CHECK;
2233
2658
  }
2234
2659
  #endif
2235
2660
 
@@ -2242,6 +2667,8 @@ ev_idle_start (EV_P_ ev_idle *w)
2242
2667
 
2243
2668
  pri_adjust (EV_A_ (W)w);
2244
2669
 
2670
+ EV_FREQUENT_CHECK;
2671
+
2245
2672
  {
2246
2673
  int active = ++idlecnt [ABSPRI (w)];
2247
2674
 
@@ -2251,6 +2678,8 @@ ev_idle_start (EV_P_ ev_idle *w)
2251
2678
  array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2);
2252
2679
  idles [ABSPRI (w)][active - 1] = w;
2253
2680
  }
2681
+
2682
+ EV_FREQUENT_CHECK;
2254
2683
  }
2255
2684
 
2256
2685
  void
@@ -2260,15 +2689,19 @@ ev_idle_stop (EV_P_ ev_idle *w)
2260
2689
  if (expect_false (!ev_is_active (w)))
2261
2690
  return;
2262
2691
 
2692
+ EV_FREQUENT_CHECK;
2693
+
2263
2694
  {
2264
- int active = ((W)w)->active;
2695
+ int active = ev_active (w);
2265
2696
 
2266
2697
  idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]];
2267
- ((W)idles [ABSPRI (w)][active - 1])->active = active;
2698
+ ev_active (idles [ABSPRI (w)][active - 1]) = active;
2268
2699
 
2269
2700
  ev_stop (EV_A_ (W)w);
2270
2701
  --idleall;
2271
2702
  }
2703
+
2704
+ EV_FREQUENT_CHECK;
2272
2705
  }
2273
2706
  #endif
2274
2707
 
@@ -2278,9 +2711,13 @@ ev_prepare_start (EV_P_ ev_prepare *w)
2278
2711
  if (expect_false (ev_is_active (w)))
2279
2712
  return;
2280
2713
 
2714
+ EV_FREQUENT_CHECK;
2715
+
2281
2716
  ev_start (EV_A_ (W)w, ++preparecnt);
2282
2717
  array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
2283
2718
  prepares [preparecnt - 1] = w;
2719
+
2720
+ EV_FREQUENT_CHECK;
2284
2721
  }
2285
2722
 
2286
2723
  void
@@ -2290,13 +2727,18 @@ ev_prepare_stop (EV_P_ ev_prepare *w)
2290
2727
  if (expect_false (!ev_is_active (w)))
2291
2728
  return;
2292
2729
 
2730
+ EV_FREQUENT_CHECK;
2731
+
2293
2732
  {
2294
- int active = ((W)w)->active;
2733
+ int active = ev_active (w);
2734
+
2295
2735
  prepares [active - 1] = prepares [--preparecnt];
2296
- ((W)prepares [active - 1])->active = active;
2736
+ ev_active (prepares [active - 1]) = active;
2297
2737
  }
2298
2738
 
2299
2739
  ev_stop (EV_A_ (W)w);
2740
+
2741
+ EV_FREQUENT_CHECK;
2300
2742
  }
2301
2743
 
2302
2744
  void
@@ -2305,9 +2747,13 @@ ev_check_start (EV_P_ ev_check *w)
2305
2747
  if (expect_false (ev_is_active (w)))
2306
2748
  return;
2307
2749
 
2750
+ EV_FREQUENT_CHECK;
2751
+
2308
2752
  ev_start (EV_A_ (W)w, ++checkcnt);
2309
2753
  array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
2310
2754
  checks [checkcnt - 1] = w;
2755
+
2756
+ EV_FREQUENT_CHECK;
2311
2757
  }
2312
2758
 
2313
2759
  void
@@ -2317,13 +2763,18 @@ ev_check_stop (EV_P_ ev_check *w)
2317
2763
  if (expect_false (!ev_is_active (w)))
2318
2764
  return;
2319
2765
 
2766
+ EV_FREQUENT_CHECK;
2767
+
2320
2768
  {
2321
- int active = ((W)w)->active;
2769
+ int active = ev_active (w);
2770
+
2322
2771
  checks [active - 1] = checks [--checkcnt];
2323
- ((W)checks [active - 1])->active = active;
2772
+ ev_active (checks [active - 1]) = active;
2324
2773
  }
2325
2774
 
2326
2775
  ev_stop (EV_A_ (W)w);
2776
+
2777
+ EV_FREQUENT_CHECK;
2327
2778
  }
2328
2779
 
2329
2780
  #if EV_EMBED_ENABLE
@@ -2380,6 +2831,8 @@ ev_embed_start (EV_P_ ev_embed *w)
2380
2831
  ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ);
2381
2832
  }
2382
2833
 
2834
+ EV_FREQUENT_CHECK;
2835
+
2383
2836
  ev_set_priority (&w->io, ev_priority (w));
2384
2837
  ev_io_start (EV_A_ &w->io);
2385
2838
 
@@ -2390,6 +2843,8 @@ ev_embed_start (EV_P_ ev_embed *w)
2390
2843
  /*ev_idle_init (&w->idle, e,bed_idle_cb);*/
2391
2844
 
2392
2845
  ev_start (EV_A_ (W)w, 1);
2846
+
2847
+ EV_FREQUENT_CHECK;
2393
2848
  }
2394
2849
 
2395
2850
  void
@@ -2399,10 +2854,14 @@ ev_embed_stop (EV_P_ ev_embed *w)
2399
2854
  if (expect_false (!ev_is_active (w)))
2400
2855
  return;
2401
2856
 
2857
+ EV_FREQUENT_CHECK;
2858
+
2402
2859
  ev_io_stop (EV_A_ &w->io);
2403
2860
  ev_prepare_stop (EV_A_ &w->prepare);
2404
2861
 
2405
2862
  ev_stop (EV_A_ (W)w);
2863
+
2864
+ EV_FREQUENT_CHECK;
2406
2865
  }
2407
2866
  #endif
2408
2867
 
@@ -2413,9 +2872,13 @@ ev_fork_start (EV_P_ ev_fork *w)
2413
2872
  if (expect_false (ev_is_active (w)))
2414
2873
  return;
2415
2874
 
2875
+ EV_FREQUENT_CHECK;
2876
+
2416
2877
  ev_start (EV_A_ (W)w, ++forkcnt);
2417
2878
  array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
2418
2879
  forks [forkcnt - 1] = w;
2880
+
2881
+ EV_FREQUENT_CHECK;
2419
2882
  }
2420
2883
 
2421
2884
  void
@@ -2425,13 +2888,18 @@ ev_fork_stop (EV_P_ ev_fork *w)
2425
2888
  if (expect_false (!ev_is_active (w)))
2426
2889
  return;
2427
2890
 
2891
+ EV_FREQUENT_CHECK;
2892
+
2428
2893
  {
2429
- int active = ((W)w)->active;
2894
+ int active = ev_active (w);
2895
+
2430
2896
  forks [active - 1] = forks [--forkcnt];
2431
- ((W)forks [active - 1])->active = active;
2897
+ ev_active (forks [active - 1]) = active;
2432
2898
  }
2433
2899
 
2434
2900
  ev_stop (EV_A_ (W)w);
2901
+
2902
+ EV_FREQUENT_CHECK;
2435
2903
  }
2436
2904
  #endif
2437
2905
 
@@ -2444,9 +2912,13 @@ ev_async_start (EV_P_ ev_async *w)
2444
2912
 
2445
2913
  evpipe_init (EV_A);
2446
2914
 
2915
+ EV_FREQUENT_CHECK;
2916
+
2447
2917
  ev_start (EV_A_ (W)w, ++asynccnt);
2448
2918
  array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
2449
2919
  asyncs [asynccnt - 1] = w;
2920
+
2921
+ EV_FREQUENT_CHECK;
2450
2922
  }
2451
2923
 
2452
2924
  void
@@ -2456,13 +2928,18 @@ ev_async_stop (EV_P_ ev_async *w)
2456
2928
  if (expect_false (!ev_is_active (w)))
2457
2929
  return;
2458
2930
 
2931
+ EV_FREQUENT_CHECK;
2932
+
2459
2933
  {
2460
- int active = ((W)w)->active;
2934
+ int active = ev_active (w);
2935
+
2461
2936
  asyncs [active - 1] = asyncs [--asynccnt];
2462
- ((W)asyncs [active - 1])->active = active;
2937
+ ev_active (asyncs [active - 1]) = active;
2463
2938
  }
2464
2939
 
2465
2940
  ev_stop (EV_A_ (W)w);
2941
+
2942
+ EV_FREQUENT_CHECK;
2466
2943
  }
2467
2944
 
2468
2945
  void