ebb 0.2.0 → 0.2.1

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.
@@ -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