rev 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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