rev 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.
@@ -88,7 +88,7 @@
88
88
  chunk_extension = (";" chunk_ext_name >start_field %write_field %start_value ("=" chunk_ext_val >start_value)? %write_value )*;
89
89
  last_chunk = "0"? chunk_extension :> (CRLF @last_chunk @done);
90
90
  chunk_size = xdigit+;
91
- chunk = chunk_size >mark %chunk_size chunk_extension :> (CRLF @done);
91
+ chunk = chunk_size >mark %chunk_size chunk_extension space* :> (CRLF @done);
92
92
  Chunked_Header = (chunk | last_chunk);
93
93
 
94
94
  main := Response | Chunked_Header;
@@ -1,4 +1,42 @@
1
- Revision history for libev, a high-performance and full-featured event loop
1
+ Revision history for libev, a high-performance and full-featured event loop.
2
+
3
+ 3.31 Wed Apr 16 20:45:04 CEST 2008
4
+ - added last minute fix for ev_poll.c by Brandon Black.
5
+
6
+ 3.3 Wed Apr 16 19:04:10 CEST 2008
7
+ - event_base_loopexit should return 0 on success
8
+ (W.C.A. Wijngaards).
9
+ - added linux eventfd support.
10
+ - try to autodetect epoll and inotify support
11
+ by libc header version if not using autoconf.
12
+ - new symbols: EV_DEFAULT_UC and EV_DEFAULT_UC_.
13
+ - declare functions defined in ev.h as inline if
14
+ C99 or gcc are available.
15
+ - enable inlining with gcc versions 2 and 3.
16
+ - work around broken poll implementations potentially
17
+ not clearing revents field in ev_poll (Brandon Black)
18
+ (no such systems are known at this time).
19
+ - work around a bug in realloc on openbsd and darwin,
20
+ also makes the errornous valgrind complaints
21
+ go away (noted by various people).
22
+ - fix ev_async_pending, add c++ wrapper for ev_async
23
+ (based on patch sent by Johannes Deisenhofer.
24
+ - add sensible set method to ev::embed.
25
+ - made integer constants type int in ev.h.
26
+
27
+ 3.2 Wed Apr 2 17:11:19 CEST 2008
28
+ - fix a 64 bit overflow issue in the select backend,
29
+ by using fd_mask instead of int for the mask.
30
+ - rename internal sighandler to avoid clash with very old perls.
31
+ - entering ev_loop will not clear the ONESHOT or NONBLOCKING
32
+ flags of any outer loops anymore.
33
+ - add ev_async_pending.
34
+
35
+ 3.1 Thu Mar 13 13:45:22 CET 2008
36
+ - implement ev_async watchers.
37
+ - only initialise signal pipe on demand.
38
+ - make use of sig_atomic_t configurable.
39
+ - improved documentation.
2
40
 
3
41
  3.0 Mon Jan 28 13:14:47 CET 2008
4
42
  - API/ABI bump to version 3.0.
@@ -1,7 +1,7 @@
1
1
  /*
2
2
  * libev event processing core, watcher management
3
3
  *
4
- * Copyright (c) 2007 Marc Alexander Lehmann <libev@schmorp.de>
4
+ * Copyright (c) 2007,2008 Marc Alexander Lehmann <libev@schmorp.de>
5
5
  * All rights reserved.
6
6
  *
7
7
  * Redistribution and use in source and binary forms, with or without modifica-
@@ -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,15 @@ 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
+ /* this block fixes any misconfiguration where we know we run into trouble otherwise */
216
241
 
217
242
  #ifndef CLOCK_MONOTONIC
218
243
  # undef EV_USE_MONOTONIC
@@ -243,6 +268,18 @@ extern "C" {
243
268
  # include <winsock.h>
244
269
  #endif
245
270
 
271
+ #if EV_USE_EVENTFD
272
+ /* our minimum requirement is glibc 2.7 which has the stub, but not the header */
273
+ # include <stdint.h>
274
+ # ifdef __cplusplus
275
+ extern "C" {
276
+ # endif
277
+ int eventfd (unsigned int initval, int flags);
278
+ # ifdef __cplusplus
279
+ }
280
+ # endif
281
+ #endif
282
+
246
283
  /**/
247
284
 
248
285
  /*
@@ -265,7 +302,7 @@ extern "C" {
265
302
  #else
266
303
  # define expect(expr,value) (expr)
267
304
  # define noinline
268
- # if __STDC_VERSION__ < 199901L
305
+ # if __STDC_VERSION__ < 199901L && __GNUC__ < 2
269
306
  # define inline
270
307
  # endif
271
308
  #endif
@@ -293,7 +330,7 @@ typedef ev_watcher_time *WT;
293
330
  #if EV_USE_MONOTONIC
294
331
  /* sig_atomic_t is used to avoid per-thread variables or locking but still */
295
332
  /* giving it a reasonably high chance of working on typical architetcures */
296
- static sig_atomic_t have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
333
+ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
297
334
  #endif
298
335
 
299
336
  #ifdef _WIN32
@@ -325,7 +362,22 @@ syserr (const char *msg)
325
362
  }
326
363
  }
327
364
 
328
- static void *(*alloc)(void *ptr, long size);
365
+ static void *
366
+ ev_realloc_emul (void *ptr, long size)
367
+ {
368
+ /* some systems, notably openbsd and darwin, fail to properly
369
+ * implement realloc (x, 0) (as required by both ansi c-98 and
370
+ * the single unix specification, so work around them here.
371
+ */
372
+
373
+ if (size)
374
+ return realloc (ptr, size);
375
+
376
+ free (ptr);
377
+ return 0;
378
+ }
379
+
380
+ static void *(*alloc)(void *ptr, long size) = ev_realloc_emul;
329
381
 
330
382
  void
331
383
  ev_set_allocator (void *(*cb)(void *ptr, long size))
@@ -336,7 +388,7 @@ ev_set_allocator (void *(*cb)(void *ptr, long size))
336
388
  inline_speed void *
337
389
  ev_realloc (void *ptr, long size)
338
390
  {
339
- ptr = alloc ? alloc (ptr, size) : realloc (ptr, size);
391
+ ptr = alloc (ptr, size);
340
392
 
341
393
  if (!ptr && size)
342
394
  {
@@ -453,7 +505,7 @@ ev_sleep (ev_tstamp delay)
453
505
 
454
506
  nanosleep (&ts, 0);
455
507
  #elif defined(_WIN32)
456
- Sleep (delay * 1e3);
508
+ Sleep ((unsigned long)(delay * 1e3));
457
509
  #else
458
510
  struct timeval tv;
459
511
 
@@ -765,15 +817,13 @@ adjustheap (WT *heap, int N, int k)
765
817
  typedef struct
766
818
  {
767
819
  WL head;
768
- sig_atomic_t volatile gotsig;
820
+ EV_ATOMIC_T gotsig;
769
821
  } ANSIG;
770
822
 
771
823
  static ANSIG *signals;
772
824
  static int signalmax;
773
825
 
774
- static int sigpipe [2];
775
- static sig_atomic_t volatile gotsig;
776
- static ev_io sigev;
826
+ static EV_ATOMIC_T gotsig;
777
827
 
778
828
  void inline_size
779
829
  signals_init (ANSIG *base, int count)
@@ -787,78 +837,148 @@ signals_init (ANSIG *base, int count)
787
837
  }
788
838
  }
789
839
 
790
- static void
791
- sighandler (int signum)
840
+ /*****************************************************************************/
841
+
842
+ void inline_speed
843
+ fd_intern (int fd)
792
844
  {
793
- #if _WIN32
794
- signal (signum, sighandler);
845
+ #ifdef _WIN32
846
+ int arg = 1;
847
+ ioctlsocket (_get_osfhandle (fd), FIONBIO, &arg);
848
+ #else
849
+ fcntl (fd, F_SETFD, FD_CLOEXEC);
850
+ fcntl (fd, F_SETFL, O_NONBLOCK);
795
851
  #endif
852
+ }
796
853
 
797
- signals [signum - 1].gotsig = 1;
854
+ static void noinline
855
+ evpipe_init (EV_P)
856
+ {
857
+ if (!ev_is_active (&pipeev))
858
+ {
859
+ #if EV_USE_EVENTFD
860
+ if ((evfd = eventfd (0, 0)) >= 0)
861
+ {
862
+ evpipe [0] = -1;
863
+ fd_intern (evfd);
864
+ ev_io_set (&pipeev, evfd, EV_READ);
865
+ }
866
+ else
867
+ #endif
868
+ {
869
+ while (pipe (evpipe))
870
+ syserr ("(libev) error creating signal/async pipe");
798
871
 
799
- if (!gotsig)
872
+ fd_intern (evpipe [0]);
873
+ fd_intern (evpipe [1]);
874
+ ev_io_set (&pipeev, evpipe [0], EV_READ);
875
+ }
876
+
877
+ ev_io_start (EV_A_ &pipeev);
878
+ ev_unref (EV_A); /* watcher should not keep loop alive */
879
+ }
880
+ }
881
+
882
+ void inline_size
883
+ evpipe_write (EV_P_ EV_ATOMIC_T *flag)
884
+ {
885
+ if (!*flag)
800
886
  {
801
- int old_errno = errno;
802
- gotsig = 1;
803
- write (sigpipe [1], &signum, 1);
887
+ int old_errno = errno; /* save errno because write might clobber it */
888
+
889
+ *flag = 1;
890
+
891
+ #if EV_USE_EVENTFD
892
+ if (evfd >= 0)
893
+ {
894
+ uint64_t counter = 1;
895
+ write (evfd, &counter, sizeof (uint64_t));
896
+ }
897
+ else
898
+ #endif
899
+ write (evpipe [1], &old_errno, 1);
900
+
804
901
  errno = old_errno;
805
902
  }
806
903
  }
807
904
 
808
- void noinline
809
- ev_feed_signal_event (EV_P_ int signum)
905
+ static void
906
+ pipecb (EV_P_ ev_io *iow, int revents)
810
907
  {
811
- WL w;
812
-
813
- #if EV_MULTIPLICITY
814
- assert (("feeding signal events is only supported in the default loop", loop == ev_default_loop_ptr));
908
+ #if EV_USE_EVENTFD
909
+ if (evfd >= 0)
910
+ {
911
+ uint64_t counter = 1;
912
+ read (evfd, &counter, sizeof (uint64_t));
913
+ }
914
+ else
815
915
  #endif
916
+ {
917
+ char dummy;
918
+ read (evpipe [0], &dummy, 1);
919
+ }
816
920
 
817
- --signum;
921
+ if (gotsig && ev_is_default_loop (EV_A))
922
+ {
923
+ int signum;
924
+ gotsig = 0;
818
925
 
819
- if (signum < 0 || signum >= signalmax)
820
- return;
926
+ for (signum = signalmax; signum--; )
927
+ if (signals [signum].gotsig)
928
+ ev_feed_signal_event (EV_A_ signum + 1);
929
+ }
821
930
 
822
- signals [signum].gotsig = 0;
931
+ #if EV_ASYNC_ENABLE
932
+ if (gotasync)
933
+ {
934
+ int i;
935
+ gotasync = 0;
823
936
 
824
- for (w = signals [signum].head; w; w = w->next)
825
- ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
937
+ for (i = asynccnt; i--; )
938
+ if (asyncs [i]->sent)
939
+ {
940
+ asyncs [i]->sent = 0;
941
+ ev_feed_event (EV_A_ asyncs [i], EV_ASYNC);
942
+ }
943
+ }
944
+ #endif
826
945
  }
827
946
 
947
+ /*****************************************************************************/
948
+
828
949
  static void
829
- sigcb (EV_P_ ev_io *iow, int revents)
950
+ ev_sighandler (int signum)
830
951
  {
831
- int signum;
952
+ #if EV_MULTIPLICITY
953
+ struct ev_loop *loop = &default_loop_struct;
954
+ #endif
832
955
 
833
- read (sigpipe [0], &revents, 1);
834
- gotsig = 0;
956
+ #if _WIN32
957
+ signal (signum, ev_sighandler);
958
+ #endif
835
959
 
836
- for (signum = signalmax; signum--; )
837
- if (signals [signum].gotsig)
838
- ev_feed_signal_event (EV_A_ signum + 1);
960
+ signals [signum - 1].gotsig = 1;
961
+ evpipe_write (EV_A_ &gotsig);
839
962
  }
840
963
 
841
- void inline_speed
842
- fd_intern (int fd)
964
+ void noinline
965
+ ev_feed_signal_event (EV_P_ int signum)
843
966
  {
844
- #ifdef _WIN32
845
- int arg = 1;
846
- ioctlsocket (_get_osfhandle (fd), FIONBIO, &arg);
847
- #else
848
- fcntl (fd, F_SETFD, FD_CLOEXEC);
849
- fcntl (fd, F_SETFL, O_NONBLOCK);
967
+ WL w;
968
+
969
+ #if EV_MULTIPLICITY
970
+ assert (("feeding signal events is only supported in the default loop", loop == ev_default_loop_ptr));
850
971
  #endif
851
- }
852
972
 
853
- static void noinline
854
- siginit (EV_P)
855
- {
856
- fd_intern (sigpipe [0]);
857
- fd_intern (sigpipe [1]);
973
+ --signum;
858
974
 
859
- ev_io_set (&sigev, sigpipe [0], EV_READ);
860
- ev_io_start (EV_A_ &sigev);
861
- ev_unref (EV_A); /* child watcher should not keep loop alive */
975
+ if (signum < 0 || signum >= signalmax)
976
+ return;
977
+
978
+ signals [signum].gotsig = 0;
979
+
980
+ for (w = signals [signum].head; w; w = w->next)
981
+ ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
862
982
  }
863
983
 
864
984
  /*****************************************************************************/
@@ -874,7 +994,7 @@ static ev_signal childev;
874
994
  #endif
875
995
 
876
996
  void inline_speed
877
- child_reap (EV_P_ ev_signal *sw, int chain, int pid, int status)
997
+ child_reap (EV_P_ int chain, int pid, int status)
878
998
  {
879
999
  ev_child *w;
880
1000
  int traced = WIFSTOPPED (status) || WIFCONTINUED (status);
@@ -884,7 +1004,7 @@ child_reap (EV_P_ ev_signal *sw, int chain, int pid, int status)
884
1004
  if ((w->pid == pid || !w->pid)
885
1005
  && (!traced || (w->flags & 1)))
886
1006
  {
887
- ev_set_priority (w, ev_priority (sw)); /* need to do it *now* */
1007
+ ev_set_priority (w, EV_MAXPRI); /* need to do it *now*, this *must* be the same prio as the signal watcher itself */
888
1008
  w->rpid = pid;
889
1009
  w->rstatus = status;
890
1010
  ev_feed_event (EV_A_ (W)w, EV_CHILD);
@@ -908,13 +1028,13 @@ childcb (EV_P_ ev_signal *sw, int revents)
908
1028
  || 0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED)))
909
1029
  return;
910
1030
 
911
- /* make sure we are called again until all childs have been reaped */
1031
+ /* make sure we are called again until all children have been reaped */
912
1032
  /* we need to do it this way so that the callback gets called before we continue */
913
1033
  ev_feed_event (EV_A_ (W)sw, EV_SIGNAL);
914
1034
 
915
- child_reap (EV_A_ sw, pid, pid, status);
1035
+ child_reap (EV_A_ pid, pid, status);
916
1036
  if (EV_PID_HASHSIZE > 1)
917
- child_reap (EV_A_ sw, 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
1037
+ child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
918
1038
  }
919
1039
 
920
1040
  #endif
@@ -1042,13 +1162,19 @@ loop_init (EV_P_ unsigned int flags)
1042
1162
  }
1043
1163
  #endif
1044
1164
 
1045
- ev_rt_now = ev_time ();
1046
- mn_now = get_clock ();
1047
- now_floor = mn_now;
1048
- rtmn_diff = ev_rt_now - mn_now;
1165
+ ev_rt_now = ev_time ();
1166
+ mn_now = get_clock ();
1167
+ now_floor = mn_now;
1168
+ rtmn_diff = ev_rt_now - mn_now;
1049
1169
 
1050
1170
  io_blocktime = 0.;
1051
1171
  timeout_blocktime = 0.;
1172
+ backend = 0;
1173
+ backend_fd = -1;
1174
+ gotasync = 0;
1175
+ #if EV_USE_INOTIFY
1176
+ fs_fd = -2;
1177
+ #endif
1052
1178
 
1053
1179
  /* pid check not overridable via env */
1054
1180
  #ifndef _WIN32
@@ -1061,15 +1187,9 @@ loop_init (EV_P_ unsigned int flags)
1061
1187
  && getenv ("LIBEV_FLAGS"))
1062
1188
  flags = atoi (getenv ("LIBEV_FLAGS"));
1063
1189
 
1064
- if (!(flags & 0x0000ffffUL))
1190
+ if (!(flags & 0x0000ffffU))
1065
1191
  flags |= ev_recommended_backends ();
1066
1192
 
1067
- backend = 0;
1068
- backend_fd = -1;
1069
- #if EV_USE_INOTIFY
1070
- fs_fd = -2;
1071
- #endif
1072
-
1073
1193
  #if EV_USE_PORT
1074
1194
  if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
1075
1195
  #endif
@@ -1086,8 +1206,8 @@ loop_init (EV_P_ unsigned int flags)
1086
1206
  if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
1087
1207
  #endif
1088
1208
 
1089
- ev_init (&sigev, sigcb);
1090
- ev_set_priority (&sigev, EV_MAXPRI);
1209
+ ev_init (&pipeev, pipecb);
1210
+ ev_set_priority (&pipeev, EV_MAXPRI);
1091
1211
  }
1092
1212
  }
1093
1213
 
@@ -1096,6 +1216,23 @@ loop_destroy (EV_P)
1096
1216
  {
1097
1217
  int i;
1098
1218
 
1219
+ if (ev_is_active (&pipeev))
1220
+ {
1221
+ ev_ref (EV_A); /* signal watcher */
1222
+ ev_io_stop (EV_A_ &pipeev);
1223
+
1224
+ #if EV_USE_EVENTFD
1225
+ if (evfd >= 0)
1226
+ close (evfd);
1227
+ #endif
1228
+
1229
+ if (evpipe [0] >= 0)
1230
+ {
1231
+ close (evpipe [0]);
1232
+ close (evpipe [1]);
1233
+ }
1234
+ }
1235
+
1099
1236
  #if EV_USE_INOTIFY
1100
1237
  if (fs_fd >= 0)
1101
1238
  close (fs_fd);
@@ -1141,6 +1278,9 @@ loop_destroy (EV_P)
1141
1278
  #endif
1142
1279
  array_free (prepare, EMPTY);
1143
1280
  array_free (check, EMPTY);
1281
+ #if EV_ASYNC_ENABLE
1282
+ array_free (async, EMPTY);
1283
+ #endif
1144
1284
 
1145
1285
  backend = 0;
1146
1286
  }
@@ -1163,20 +1303,32 @@ loop_fork (EV_P)
1163
1303
  infy_fork (EV_A);
1164
1304
  #endif
1165
1305
 
1166
- if (ev_is_active (&sigev))
1306
+ if (ev_is_active (&pipeev))
1167
1307
  {
1168
- /* default loop */
1308
+ /* this "locks" the handlers against writing to the pipe */
1309
+ /* while we modify the fd vars */
1310
+ gotsig = 1;
1311
+ #if EV_ASYNC_ENABLE
1312
+ gotasync = 1;
1313
+ #endif
1169
1314
 
1170
1315
  ev_ref (EV_A);
1171
- ev_io_stop (EV_A_ &sigev);
1172
- close (sigpipe [0]);
1173
- close (sigpipe [1]);
1316
+ ev_io_stop (EV_A_ &pipeev);
1317
+
1318
+ #if EV_USE_EVENTFD
1319
+ if (evfd >= 0)
1320
+ close (evfd);
1321
+ #endif
1174
1322
 
1175
- while (pipe (sigpipe))
1176
- syserr ("(libev) error creating pipe");
1323
+ if (evpipe [0] >= 0)
1324
+ {
1325
+ close (evpipe [0]);
1326
+ close (evpipe [1]);
1327
+ }
1177
1328
 
1178
- siginit (EV_A);
1179
- sigcb (EV_A_ &sigev, EV_READ);
1329
+ evpipe_init (EV_A);
1330
+ /* now iterate over everything, in case we missed something */
1331
+ pipecb (EV_A_ &pipeev, EV_READ);
1180
1332
  }
1181
1333
 
1182
1334
  postfork = 0;
@@ -1221,10 +1373,6 @@ int
1221
1373
  ev_default_loop (unsigned int flags)
1222
1374
  #endif
1223
1375
  {
1224
- if (sigpipe [0] == sigpipe [1])
1225
- if (pipe (sigpipe))
1226
- return 0;
1227
-
1228
1376
  if (!ev_default_loop_ptr)
1229
1377
  {
1230
1378
  #if EV_MULTIPLICITY
@@ -1237,8 +1385,6 @@ ev_default_loop (unsigned int flags)
1237
1385
 
1238
1386
  if (ev_backend (EV_A))
1239
1387
  {
1240
- siginit (EV_A);
1241
-
1242
1388
  #ifndef _WIN32
1243
1389
  ev_signal_init (&childev, childcb, SIGCHLD);
1244
1390
  ev_set_priority (&childev, EV_MAXPRI);
@@ -1265,12 +1411,6 @@ ev_default_destroy (void)
1265
1411
  ev_signal_stop (EV_A_ &childev);
1266
1412
  #endif
1267
1413
 
1268
- ev_ref (EV_A); /* signal watcher */
1269
- ev_io_stop (EV_A_ &sigev);
1270
-
1271
- close (sigpipe [0]); sigpipe [0] = 0;
1272
- close (sigpipe [1]); sigpipe [1] = 0;
1273
-
1274
1414
  loop_destroy (EV_A);
1275
1415
  }
1276
1416
 
@@ -1501,9 +1641,7 @@ static int loop_done;
1501
1641
  void
1502
1642
  ev_loop (EV_P_ int flags)
1503
1643
  {
1504
- loop_done = flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK)
1505
- ? EVUNLOOP_ONE
1506
- : EVUNLOOP_CANCEL;
1644
+ loop_done = EVUNLOOP_CANCEL;
1507
1645
 
1508
1646
  call_pending (EV_A); /* in case we recurse, ensure ordering stays nice and clean */
1509
1647
 
@@ -1609,9 +1747,12 @@ ev_loop (EV_P_ int flags)
1609
1747
  queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);
1610
1748
 
1611
1749
  call_pending (EV_A);
1612
-
1613
1750
  }
1614
- while (expect_true (activecnt && !loop_done));
1751
+ while (expect_true (
1752
+ activecnt
1753
+ && !loop_done
1754
+ && !(flags & (EVLOOP_ONESHOT | EVLOOP_NONBLOCK))
1755
+ ));
1615
1756
 
1616
1757
  if (loop_done == EVUNLOOP_ONE)
1617
1758
  loop_done = EVUNLOOP_CANCEL;
@@ -1867,6 +2008,8 @@ ev_signal_start (EV_P_ ev_signal *w)
1867
2008
 
1868
2009
  assert (("ev_signal_start called with illegal signal number", w->signum > 0));
1869
2010
 
2011
+ evpipe_init (EV_A);
2012
+
1870
2013
  {
1871
2014
  #ifndef _WIN32
1872
2015
  sigset_t full, prev;
@@ -1887,10 +2030,10 @@ ev_signal_start (EV_P_ ev_signal *w)
1887
2030
  if (!((WL)w)->next)
1888
2031
  {
1889
2032
  #if _WIN32
1890
- signal (w->signum, sighandler);
2033
+ signal (w->signum, ev_sighandler);
1891
2034
  #else
1892
2035
  struct sigaction sa;
1893
- sa.sa_handler = sighandler;
2036
+ sa.sa_handler = ev_sighandler;
1894
2037
  sigfillset (&sa.sa_mask);
1895
2038
  sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
1896
2039
  sigaction (w->signum, &sa, 0);
@@ -2389,6 +2532,44 @@ ev_fork_stop (EV_P_ ev_fork *w)
2389
2532
  }
2390
2533
  #endif
2391
2534
 
2535
+ #if EV_ASYNC_ENABLE
2536
+ void
2537
+ ev_async_start (EV_P_ ev_async *w)
2538
+ {
2539
+ if (expect_false (ev_is_active (w)))
2540
+ return;
2541
+
2542
+ evpipe_init (EV_A);
2543
+
2544
+ ev_start (EV_A_ (W)w, ++asynccnt);
2545
+ array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
2546
+ asyncs [asynccnt - 1] = w;
2547
+ }
2548
+
2549
+ void
2550
+ ev_async_stop (EV_P_ ev_async *w)
2551
+ {
2552
+ clear_pending (EV_A_ (W)w);
2553
+ if (expect_false (!ev_is_active (w)))
2554
+ return;
2555
+
2556
+ {
2557
+ int active = ((W)w)->active;
2558
+ asyncs [active - 1] = asyncs [--asynccnt];
2559
+ ((W)asyncs [active - 1])->active = active;
2560
+ }
2561
+
2562
+ ev_stop (EV_A_ (W)w);
2563
+ }
2564
+
2565
+ void
2566
+ ev_async_send (EV_P_ ev_async *w)
2567
+ {
2568
+ w->sent = 1;
2569
+ evpipe_write (EV_A_ &gotasync);
2570
+ }
2571
+ #endif
2572
+
2392
2573
  /*****************************************************************************/
2393
2574
 
2394
2575
  struct ev_once