cool.io 1.1.1 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +1 -1
- data/CHANGES.md +4 -2
- data/Gemfile +1 -1
- data/README.md +2 -1
- data/Rakefile +22 -3
- data/cool.io.gemspec +6 -8
- data/ext/cool.io/extconf.rb +2 -1
- data/ext/cool.io/stat_watcher.c +2 -0
- data/ext/iobuffer/extconf.rb +9 -0
- data/ext/iobuffer/iobuffer.c +765 -0
- data/ext/libev/ev.c +1186 -296
- data/ext/libev/ev.h +123 -107
- data/ext/libev/ev_epoll.c +23 -10
- data/ext/libev/ev_kqueue.c +23 -7
- data/ext/libev/ev_poll.c +4 -4
- data/ext/libev/ev_port.c +9 -3
- data/ext/libev/ev_select.c +10 -6
- data/ext/libev/ev_vars.h +18 -18
- data/ext/libev/ev_win32.c +12 -2
- data/ext/libev/ev_wrap.h +164 -160
- data/lib/cool.io.rb +4 -4
- data/lib/cool.io/custom_require.rb +9 -0
- data/lib/cool.io/dns_resolver.rb +8 -5
- data/lib/cool.io/http_client.rb +4 -3
- data/lib/cool.io/listener.rb +3 -9
- data/lib/cool.io/server.rb +1 -2
- data/lib/cool.io/version.rb +1 -1
- data/spec/async_watcher_spec.rb +1 -1
- data/spec/spec_helper.rb +8 -1
- data/spec/unix_listener_spec.rb +1 -1
- data/spec/unix_server_spec.rb +2 -4
- metadata +35 -29
- checksums.yaml +0 -7
data/ext/libev/ev.c
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
/*
|
2
2
|
* libev event processing core, watcher management
|
3
3
|
*
|
4
|
-
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
|
4
|
+
* Copyright (c) 2007,2008,2009,2010,2011,2012 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-
|
@@ -45,6 +45,12 @@
|
|
45
45
|
# include "config.h"
|
46
46
|
# endif
|
47
47
|
|
48
|
+
#if HAVE_FLOOR
|
49
|
+
# ifndef EV_USE_FLOOR
|
50
|
+
# define EV_USE_FLOOR 1
|
51
|
+
# endif
|
52
|
+
#endif
|
53
|
+
|
48
54
|
# if HAVE_CLOCK_SYSCALL
|
49
55
|
# ifndef EV_USE_CLOCK_SYSCALL
|
50
56
|
# define EV_USE_CLOCK_SYSCALL 1
|
@@ -55,7 +61,7 @@
|
|
55
61
|
# define EV_USE_MONOTONIC 1
|
56
62
|
# endif
|
57
63
|
# endif
|
58
|
-
# elif !defined
|
64
|
+
# elif !defined EV_USE_CLOCK_SYSCALL
|
59
65
|
# define EV_USE_CLOCK_SYSCALL 0
|
60
66
|
# endif
|
61
67
|
|
@@ -158,7 +164,6 @@
|
|
158
164
|
|
159
165
|
#endif
|
160
166
|
|
161
|
-
#include <math.h>
|
162
167
|
#include <stdlib.h>
|
163
168
|
#include <string.h>
|
164
169
|
#include <fcntl.h>
|
@@ -180,7 +185,16 @@
|
|
180
185
|
# include "ev.h"
|
181
186
|
#endif
|
182
187
|
|
183
|
-
|
188
|
+
#if EV_NO_THREADS
|
189
|
+
# undef EV_NO_SMP
|
190
|
+
# define EV_NO_SMP 1
|
191
|
+
# undef ECB_NO_THREADS
|
192
|
+
# define ECB_NO_THREADS 1
|
193
|
+
#endif
|
194
|
+
#if EV_NO_SMP
|
195
|
+
# undef EV_NO_SMP
|
196
|
+
# define ECB_NO_SMP 1
|
197
|
+
#endif
|
184
198
|
|
185
199
|
#ifndef _WIN32
|
186
200
|
# include <sys/time.h>
|
@@ -189,6 +203,7 @@ EV_CPP(extern "C" {)
|
|
189
203
|
#else
|
190
204
|
# include <io.h>
|
191
205
|
# define WIN32_LEAN_AND_MEAN
|
206
|
+
# include <winsock2.h>
|
192
207
|
# include <windows.h>
|
193
208
|
# ifndef EV_SELECT_IS_WINSOCKET
|
194
209
|
# define EV_SELECT_IS_WINSOCKET 1
|
@@ -207,25 +222,25 @@ EV_CPP(extern "C" {)
|
|
207
222
|
/* this block tries to deduce configuration from header-defined symbols and defaults */
|
208
223
|
|
209
224
|
/* try to deduce the maximum number of signals on this platform */
|
210
|
-
#if defined
|
225
|
+
#if defined EV_NSIG
|
211
226
|
/* use what's provided */
|
212
|
-
#elif defined
|
227
|
+
#elif defined NSIG
|
213
228
|
# define EV_NSIG (NSIG)
|
214
|
-
#elif defined
|
229
|
+
#elif defined _NSIG
|
215
230
|
# define EV_NSIG (_NSIG)
|
216
|
-
#elif defined
|
231
|
+
#elif defined SIGMAX
|
217
232
|
# define EV_NSIG (SIGMAX+1)
|
218
|
-
#elif defined
|
233
|
+
#elif defined SIG_MAX
|
219
234
|
# define EV_NSIG (SIG_MAX+1)
|
220
|
-
#elif defined
|
235
|
+
#elif defined _SIG_MAX
|
221
236
|
# define EV_NSIG (_SIG_MAX+1)
|
222
|
-
#elif defined
|
237
|
+
#elif defined MAXSIG
|
223
238
|
# define EV_NSIG (MAXSIG+1)
|
224
|
-
#elif defined
|
239
|
+
#elif defined MAX_SIG
|
225
240
|
# define EV_NSIG (MAX_SIG+1)
|
226
|
-
#elif defined
|
241
|
+
#elif defined SIGARRAYSIZE
|
227
242
|
# define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */
|
228
|
-
#elif defined
|
243
|
+
#elif defined _sys_nsig
|
229
244
|
# define EV_NSIG (_sys_nsig) /* Solaris 2.5 */
|
230
245
|
#else
|
231
246
|
# error "unable to find value for NSIG, please report"
|
@@ -234,6 +249,10 @@ EV_CPP(extern "C" {)
|
|
234
249
|
# define EV_NSIG 65
|
235
250
|
#endif
|
236
251
|
|
252
|
+
#ifndef EV_USE_FLOOR
|
253
|
+
# define EV_USE_FLOOR 0
|
254
|
+
#endif
|
255
|
+
|
237
256
|
#ifndef EV_USE_CLOCK_SYSCALL
|
238
257
|
# if __linux && __GLIBC__ >= 2
|
239
258
|
# define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS
|
@@ -243,7 +262,7 @@ EV_CPP(extern "C" {)
|
|
243
262
|
#endif
|
244
263
|
|
245
264
|
#ifndef EV_USE_MONOTONIC
|
246
|
-
# if defined
|
265
|
+
# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
|
247
266
|
# define EV_USE_MONOTONIC EV_FEATURE_OS
|
248
267
|
# else
|
249
268
|
# define EV_USE_MONOTONIC 0
|
@@ -340,10 +359,26 @@ EV_CPP(extern "C" {)
|
|
340
359
|
# define EV_HEAP_CACHE_AT EV_FEATURE_DATA
|
341
360
|
#endif
|
342
361
|
|
362
|
+
#ifdef ANDROID
|
363
|
+
/* supposedly, android doesn't typedef fd_mask */
|
364
|
+
# undef EV_USE_SELECT
|
365
|
+
# define EV_USE_SELECT 0
|
366
|
+
/* supposedly, we need to include syscall.h, not sys/syscall.h, so just disable */
|
367
|
+
# undef EV_USE_CLOCK_SYSCALL
|
368
|
+
# define EV_USE_CLOCK_SYSCALL 0
|
369
|
+
#endif
|
370
|
+
|
371
|
+
/* aix's poll.h seems to cause lots of trouble */
|
372
|
+
#ifdef _AIX
|
373
|
+
/* AIX has a completely broken poll.h header */
|
374
|
+
# undef EV_USE_POLL
|
375
|
+
# define EV_USE_POLL 0
|
376
|
+
#endif
|
377
|
+
|
343
378
|
/* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */
|
344
379
|
/* which makes programs even slower. might work on other unices, too. */
|
345
380
|
#if EV_USE_CLOCK_SYSCALL
|
346
|
-
# include <syscall.h>
|
381
|
+
# include <sys/syscall.h>
|
347
382
|
# ifdef SYS_clock_gettime
|
348
383
|
# define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts))
|
349
384
|
# undef EV_USE_MONOTONIC
|
@@ -356,12 +391,6 @@ EV_CPP(extern "C" {)
|
|
356
391
|
|
357
392
|
/* this block fixes any misconfiguration where we know we run into trouble otherwise */
|
358
393
|
|
359
|
-
#ifdef _AIX
|
360
|
-
/* AIX has a completely broken poll.h header */
|
361
|
-
# undef EV_USE_POLL
|
362
|
-
# define EV_USE_POLL 0
|
363
|
-
#endif
|
364
|
-
|
365
394
|
#ifndef CLOCK_MONOTONIC
|
366
395
|
# undef EV_USE_MONOTONIC
|
367
396
|
# define EV_USE_MONOTONIC 0
|
@@ -379,7 +408,7 @@ EV_CPP(extern "C" {)
|
|
379
408
|
|
380
409
|
#if !EV_USE_NANOSLEEP
|
381
410
|
/* hp-ux has it in sys/time.h, which we unconditionally include above */
|
382
|
-
# if !defined
|
411
|
+
# if !defined _WIN32 && !defined __hpux
|
383
412
|
# include <sys/select.h>
|
384
413
|
# endif
|
385
414
|
#endif
|
@@ -394,10 +423,6 @@ EV_CPP(extern "C" {)
|
|
394
423
|
# endif
|
395
424
|
#endif
|
396
425
|
|
397
|
-
#if EV_SELECT_IS_WINSOCKET
|
398
|
-
# include <winsock.h>
|
399
|
-
#endif
|
400
|
-
|
401
426
|
#if EV_USE_EVENTFD
|
402
427
|
/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
|
403
428
|
# include <stdint.h>
|
@@ -445,14 +470,11 @@ struct signalfd_siginfo
|
|
445
470
|
#endif
|
446
471
|
|
447
472
|
/*
|
448
|
-
* This is used to
|
449
|
-
* It is added to ev_rt_now when scheduling periodics
|
450
|
-
* to ensure progress, time-wise, even when rounding
|
451
|
-
* errors are against us.
|
473
|
+
* This is used to work around floating point rounding problems.
|
452
474
|
* This value is good at least till the year 4000.
|
453
|
-
* Better solutions welcome.
|
454
475
|
*/
|
455
|
-
#define
|
476
|
+
#define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */
|
477
|
+
/*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */
|
456
478
|
|
457
479
|
#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
|
458
480
|
#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
|
@@ -460,23 +482,758 @@ struct signalfd_siginfo
|
|
460
482
|
#define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0)
|
461
483
|
#define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0)
|
462
484
|
|
463
|
-
|
464
|
-
|
465
|
-
|
485
|
+
/* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */
|
486
|
+
/* ECB.H BEGIN */
|
487
|
+
/*
|
488
|
+
* libecb - http://software.schmorp.de/pkg/libecb
|
489
|
+
*
|
490
|
+
* Copyright (©) 2009-2012 Marc Alexander Lehmann <libecb@schmorp.de>
|
491
|
+
* Copyright (©) 2011 Emanuele Giaquinta
|
492
|
+
* All rights reserved.
|
493
|
+
*
|
494
|
+
* Redistribution and use in source and binary forms, with or without modifica-
|
495
|
+
* tion, are permitted provided that the following conditions are met:
|
496
|
+
*
|
497
|
+
* 1. Redistributions of source code must retain the above copyright notice,
|
498
|
+
* this list of conditions and the following disclaimer.
|
499
|
+
*
|
500
|
+
* 2. Redistributions in binary form must reproduce the above copyright
|
501
|
+
* notice, this list of conditions and the following disclaimer in the
|
502
|
+
* documentation and/or other materials provided with the distribution.
|
503
|
+
*
|
504
|
+
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
|
505
|
+
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
|
506
|
+
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
507
|
+
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
|
508
|
+
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
509
|
+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
510
|
+
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
511
|
+
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
|
512
|
+
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
513
|
+
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
514
|
+
*/
|
515
|
+
|
516
|
+
#ifndef ECB_H
|
517
|
+
#define ECB_H
|
518
|
+
|
519
|
+
/* 16 bits major, 16 bits minor */
|
520
|
+
#define ECB_VERSION 0x00010003
|
521
|
+
|
522
|
+
#ifdef _WIN32
|
523
|
+
typedef signed char int8_t;
|
524
|
+
typedef unsigned char uint8_t;
|
525
|
+
typedef signed short int16_t;
|
526
|
+
typedef unsigned short uint16_t;
|
527
|
+
typedef signed int int32_t;
|
528
|
+
typedef unsigned int uint32_t;
|
529
|
+
#if __GNUC__
|
530
|
+
typedef signed long long int64_t;
|
531
|
+
typedef unsigned long long uint64_t;
|
532
|
+
#else /* _MSC_VER || __BORLANDC__ */
|
533
|
+
typedef signed __int64 int64_t;
|
534
|
+
typedef unsigned __int64 uint64_t;
|
535
|
+
#endif
|
536
|
+
#ifdef _WIN64
|
537
|
+
#define ECB_PTRSIZE 8
|
538
|
+
typedef uint64_t uintptr_t;
|
539
|
+
typedef int64_t intptr_t;
|
540
|
+
#else
|
541
|
+
#define ECB_PTRSIZE 4
|
542
|
+
typedef uint32_t uintptr_t;
|
543
|
+
typedef int32_t intptr_t;
|
544
|
+
#endif
|
466
545
|
#else
|
467
|
-
#
|
468
|
-
#
|
469
|
-
#
|
470
|
-
#
|
471
|
-
#
|
546
|
+
#include <inttypes.h>
|
547
|
+
#if UINTMAX_MAX > 0xffffffffU
|
548
|
+
#define ECB_PTRSIZE 8
|
549
|
+
#else
|
550
|
+
#define ECB_PTRSIZE 4
|
551
|
+
#endif
|
552
|
+
#endif
|
553
|
+
|
554
|
+
/* work around x32 idiocy by defining proper macros */
|
555
|
+
#if __x86_64 || _M_AMD64
|
556
|
+
#if __ILP32
|
557
|
+
#define ECB_AMD64_X32 1
|
558
|
+
#else
|
559
|
+
#define ECB_AMD64 1
|
560
|
+
#endif
|
561
|
+
#endif
|
562
|
+
|
563
|
+
/* many compilers define _GNUC_ to some versions but then only implement
|
564
|
+
* what their idiot authors think are the "more important" extensions,
|
565
|
+
* causing enormous grief in return for some better fake benchmark numbers.
|
566
|
+
* or so.
|
567
|
+
* we try to detect these and simply assume they are not gcc - if they have
|
568
|
+
* an issue with that they should have done it right in the first place.
|
569
|
+
*/
|
570
|
+
#ifndef ECB_GCC_VERSION
|
571
|
+
#if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
|
572
|
+
#define ECB_GCC_VERSION(major,minor) 0
|
573
|
+
#else
|
574
|
+
#define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
|
575
|
+
#endif
|
576
|
+
#endif
|
577
|
+
|
578
|
+
#define ECB_C (__STDC__+0) /* this assumes that __STDC__ is either empty or a number */
|
579
|
+
#define ECB_C99 (__STDC_VERSION__ >= 199901L)
|
580
|
+
#define ECB_C11 (__STDC_VERSION__ >= 201112L)
|
581
|
+
#define ECB_CPP (__cplusplus+0)
|
582
|
+
#define ECB_CPP11 (__cplusplus >= 201103L)
|
583
|
+
|
584
|
+
#if ECB_CPP
|
585
|
+
#define ECB_EXTERN_C extern "C"
|
586
|
+
#define ECB_EXTERN_C_BEG ECB_EXTERN_C {
|
587
|
+
#define ECB_EXTERN_C_END }
|
588
|
+
#else
|
589
|
+
#define ECB_EXTERN_C extern
|
590
|
+
#define ECB_EXTERN_C_BEG
|
591
|
+
#define ECB_EXTERN_C_END
|
592
|
+
#endif
|
593
|
+
|
594
|
+
/*****************************************************************************/
|
595
|
+
|
596
|
+
/* ECB_NO_THREADS - ecb is not used by multiple threads, ever */
|
597
|
+
/* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */
|
598
|
+
|
599
|
+
#if ECB_NO_THREADS
|
600
|
+
#define ECB_NO_SMP 1
|
601
|
+
#endif
|
602
|
+
|
603
|
+
#if ECB_NO_SMP
|
604
|
+
#define ECB_MEMORY_FENCE do { } while (0)
|
605
|
+
#endif
|
606
|
+
|
607
|
+
#ifndef ECB_MEMORY_FENCE
|
608
|
+
#if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
|
609
|
+
#if __i386 || __i386__
|
610
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
|
611
|
+
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
|
612
|
+
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
|
613
|
+
#elif __amd64 || __amd64__ || __x86_64 || __x86_64__
|
614
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
|
615
|
+
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
|
616
|
+
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
|
617
|
+
#elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
|
618
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
|
619
|
+
#elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \
|
620
|
+
|| defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__
|
621
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory")
|
622
|
+
#elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \
|
623
|
+
|| defined __ARM_ARCH_7M__ || defined __ARM_ARCH_7R__
|
624
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
|
625
|
+
#elif __sparc || __sparc__
|
626
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
|
627
|
+
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
|
628
|
+
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
|
629
|
+
#elif defined __s390__ || defined __s390x__
|
630
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory")
|
631
|
+
#elif defined __mips__
|
632
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
|
633
|
+
#elif defined __alpha__
|
634
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory")
|
635
|
+
#elif defined __hppa__
|
636
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
|
637
|
+
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
|
638
|
+
#elif defined __ia64__
|
639
|
+
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory")
|
640
|
+
#endif
|
641
|
+
#endif
|
642
|
+
#endif
|
643
|
+
|
644
|
+
#ifndef ECB_MEMORY_FENCE
|
645
|
+
#if ECB_GCC_VERSION(4,7)
|
646
|
+
/* see comment below (stdatomic.h) about the C11 memory model. */
|
647
|
+
#define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
|
648
|
+
|
649
|
+
/* The __has_feature syntax from clang is so misdesigned that we cannot use it
|
650
|
+
* without risking compile time errors with other compilers. We *could*
|
651
|
+
* define our own ecb_clang_has_feature, but I just can't be bothered to work
|
652
|
+
* around this shit time and again.
|
653
|
+
* #elif defined __clang && __has_feature (cxx_atomic)
|
654
|
+
* // see comment below (stdatomic.h) about the C11 memory model.
|
655
|
+
* #define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
|
656
|
+
*/
|
657
|
+
|
658
|
+
#elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
|
659
|
+
#define ECB_MEMORY_FENCE __sync_synchronize ()
|
660
|
+
#elif _MSC_VER >= 1400 /* VC++ 2005 */
|
661
|
+
#pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
|
662
|
+
#define ECB_MEMORY_FENCE _ReadWriteBarrier ()
|
663
|
+
#define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
|
664
|
+
#define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
|
665
|
+
#elif defined _WIN32
|
666
|
+
#include <WinNT.h>
|
667
|
+
#define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
|
668
|
+
#elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
|
669
|
+
#include <mbarrier.h>
|
670
|
+
#define ECB_MEMORY_FENCE __machine_rw_barrier ()
|
671
|
+
#define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier ()
|
672
|
+
#define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier ()
|
673
|
+
#elif __xlC__
|
674
|
+
#define ECB_MEMORY_FENCE __sync ()
|
675
|
+
#endif
|
676
|
+
#endif
|
677
|
+
|
678
|
+
#ifndef ECB_MEMORY_FENCE
|
679
|
+
#if ECB_C11 && !defined __STDC_NO_ATOMICS__
|
680
|
+
/* we assume that these memory fences work on all variables/all memory accesses, */
|
681
|
+
/* not just C11 atomics and atomic accesses */
|
682
|
+
#include <stdatomic.h>
|
683
|
+
/* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
|
684
|
+
/* any fence other than seq_cst, which isn't very efficient for us. */
|
685
|
+
/* Why that is, we don't know - either the C11 memory model is quite useless */
|
686
|
+
/* for most usages, or gcc and clang have a bug */
|
687
|
+
/* I *currently* lean towards the latter, and inefficiently implement */
|
688
|
+
/* all three of ecb's fences as a seq_cst fence */
|
689
|
+
#define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
|
690
|
+
#endif
|
691
|
+
#endif
|
692
|
+
|
693
|
+
#ifndef ECB_MEMORY_FENCE
|
694
|
+
#if !ECB_AVOID_PTHREADS
|
695
|
+
/*
|
696
|
+
* if you get undefined symbol references to pthread_mutex_lock,
|
697
|
+
* or failure to find pthread.h, then you should implement
|
698
|
+
* the ECB_MEMORY_FENCE operations for your cpu/compiler
|
699
|
+
* OR provide pthread.h and link against the posix thread library
|
700
|
+
* of your system.
|
701
|
+
*/
|
702
|
+
#include <pthread.h>
|
703
|
+
#define ECB_NEEDS_PTHREADS 1
|
704
|
+
#define ECB_MEMORY_FENCE_NEEDS_PTHREADS 1
|
705
|
+
|
706
|
+
static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
|
707
|
+
#define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
|
708
|
+
#endif
|
709
|
+
#endif
|
710
|
+
|
711
|
+
#if !defined ECB_MEMORY_FENCE_ACQUIRE && defined ECB_MEMORY_FENCE
|
712
|
+
#define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
|
713
|
+
#endif
|
714
|
+
|
715
|
+
#if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE
|
716
|
+
#define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
|
717
|
+
#endif
|
718
|
+
|
719
|
+
/*****************************************************************************/
|
720
|
+
|
721
|
+
#if __cplusplus
|
722
|
+
#define ecb_inline static inline
|
723
|
+
#elif ECB_GCC_VERSION(2,5)
|
724
|
+
#define ecb_inline static __inline__
|
725
|
+
#elif ECB_C99
|
726
|
+
#define ecb_inline static inline
|
727
|
+
#else
|
728
|
+
#define ecb_inline static
|
729
|
+
#endif
|
730
|
+
|
731
|
+
#if ECB_GCC_VERSION(3,3)
|
732
|
+
#define ecb_restrict __restrict__
|
733
|
+
#elif ECB_C99
|
734
|
+
#define ecb_restrict restrict
|
735
|
+
#else
|
736
|
+
#define ecb_restrict
|
737
|
+
#endif
|
738
|
+
|
739
|
+
typedef int ecb_bool;
|
740
|
+
|
741
|
+
#define ECB_CONCAT_(a, b) a ## b
|
742
|
+
#define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)
|
743
|
+
#define ECB_STRINGIFY_(a) # a
|
744
|
+
#define ECB_STRINGIFY(a) ECB_STRINGIFY_(a)
|
745
|
+
|
746
|
+
#define ecb_function_ ecb_inline
|
747
|
+
|
748
|
+
#if ECB_GCC_VERSION(3,1)
|
749
|
+
#define ecb_attribute(attrlist) __attribute__(attrlist)
|
750
|
+
#define ecb_is_constant(expr) __builtin_constant_p (expr)
|
751
|
+
#define ecb_expect(expr,value) __builtin_expect ((expr),(value))
|
752
|
+
#define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
|
753
|
+
#else
|
754
|
+
#define ecb_attribute(attrlist)
|
755
|
+
#define ecb_is_constant(expr) 0
|
756
|
+
#define ecb_expect(expr,value) (expr)
|
757
|
+
#define ecb_prefetch(addr,rw,locality)
|
758
|
+
#endif
|
759
|
+
|
760
|
+
/* no emulation for ecb_decltype */
|
761
|
+
#if ECB_GCC_VERSION(4,5)
|
762
|
+
#define ecb_decltype(x) __decltype(x)
|
763
|
+
#elif ECB_GCC_VERSION(3,0)
|
764
|
+
#define ecb_decltype(x) __typeof(x)
|
765
|
+
#endif
|
766
|
+
|
767
|
+
#define ecb_noinline ecb_attribute ((__noinline__))
|
768
|
+
#define ecb_unused ecb_attribute ((__unused__))
|
769
|
+
#define ecb_const ecb_attribute ((__const__))
|
770
|
+
#define ecb_pure ecb_attribute ((__pure__))
|
771
|
+
|
772
|
+
#if ECB_C11
|
773
|
+
#define ecb_noreturn _Noreturn
|
774
|
+
#else
|
775
|
+
#define ecb_noreturn ecb_attribute ((__noreturn__))
|
776
|
+
#endif
|
777
|
+
|
778
|
+
#if ECB_GCC_VERSION(4,3)
|
779
|
+
#define ecb_artificial ecb_attribute ((__artificial__))
|
780
|
+
#define ecb_hot ecb_attribute ((__hot__))
|
781
|
+
#define ecb_cold ecb_attribute ((__cold__))
|
782
|
+
#else
|
783
|
+
#define ecb_artificial
|
784
|
+
#define ecb_hot
|
785
|
+
#define ecb_cold
|
786
|
+
#endif
|
787
|
+
|
788
|
+
/* put around conditional expressions if you are very sure that the */
|
789
|
+
/* expression is mostly true or mostly false. note that these return */
|
790
|
+
/* booleans, not the expression. */
|
791
|
+
#define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
|
792
|
+
#define ecb_expect_true(expr) ecb_expect (!!(expr), 1)
|
793
|
+
/* for compatibility to the rest of the world */
|
794
|
+
#define ecb_likely(expr) ecb_expect_true (expr)
|
795
|
+
#define ecb_unlikely(expr) ecb_expect_false (expr)
|
796
|
+
|
797
|
+
/* count trailing zero bits and count # of one bits */
|
798
|
+
#if ECB_GCC_VERSION(3,4)
|
799
|
+
/* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
|
800
|
+
#define ecb_ld32(x) (__builtin_clz (x) ^ 31)
|
801
|
+
#define ecb_ld64(x) (__builtin_clzll (x) ^ 63)
|
802
|
+
#define ecb_ctz32(x) __builtin_ctz (x)
|
803
|
+
#define ecb_ctz64(x) __builtin_ctzll (x)
|
804
|
+
#define ecb_popcount32(x) __builtin_popcount (x)
|
805
|
+
/* no popcountll */
|
806
|
+
#else
|
807
|
+
ecb_function_ int ecb_ctz32 (uint32_t x) ecb_const;
|
808
|
+
ecb_function_ int
|
809
|
+
ecb_ctz32 (uint32_t x)
|
810
|
+
{
|
811
|
+
int r = 0;
|
812
|
+
|
813
|
+
x &= ~x + 1; /* this isolates the lowest bit */
|
814
|
+
|
815
|
+
#if ECB_branchless_on_i386
|
816
|
+
r += !!(x & 0xaaaaaaaa) << 0;
|
817
|
+
r += !!(x & 0xcccccccc) << 1;
|
818
|
+
r += !!(x & 0xf0f0f0f0) << 2;
|
819
|
+
r += !!(x & 0xff00ff00) << 3;
|
820
|
+
r += !!(x & 0xffff0000) << 4;
|
821
|
+
#else
|
822
|
+
if (x & 0xaaaaaaaa) r += 1;
|
823
|
+
if (x & 0xcccccccc) r += 2;
|
824
|
+
if (x & 0xf0f0f0f0) r += 4;
|
825
|
+
if (x & 0xff00ff00) r += 8;
|
826
|
+
if (x & 0xffff0000) r += 16;
|
827
|
+
#endif
|
828
|
+
|
829
|
+
return r;
|
830
|
+
}
|
831
|
+
|
832
|
+
ecb_function_ int ecb_ctz64 (uint64_t x) ecb_const;
|
833
|
+
ecb_function_ int
|
834
|
+
ecb_ctz64 (uint64_t x)
|
835
|
+
{
|
836
|
+
int shift = x & 0xffffffffU ? 0 : 32;
|
837
|
+
return ecb_ctz32 (x >> shift) + shift;
|
838
|
+
}
|
839
|
+
|
840
|
+
ecb_function_ int ecb_popcount32 (uint32_t x) ecb_const;
|
841
|
+
ecb_function_ int
|
842
|
+
ecb_popcount32 (uint32_t x)
|
843
|
+
{
|
844
|
+
x -= (x >> 1) & 0x55555555;
|
845
|
+
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
|
846
|
+
x = ((x >> 4) + x) & 0x0f0f0f0f;
|
847
|
+
x *= 0x01010101;
|
848
|
+
|
849
|
+
return x >> 24;
|
850
|
+
}
|
851
|
+
|
852
|
+
ecb_function_ int ecb_ld32 (uint32_t x) ecb_const;
|
853
|
+
ecb_function_ int ecb_ld32 (uint32_t x)
|
854
|
+
{
|
855
|
+
int r = 0;
|
856
|
+
|
857
|
+
if (x >> 16) { x >>= 16; r += 16; }
|
858
|
+
if (x >> 8) { x >>= 8; r += 8; }
|
859
|
+
if (x >> 4) { x >>= 4; r += 4; }
|
860
|
+
if (x >> 2) { x >>= 2; r += 2; }
|
861
|
+
if (x >> 1) { r += 1; }
|
862
|
+
|
863
|
+
return r;
|
864
|
+
}
|
865
|
+
|
866
|
+
ecb_function_ int ecb_ld64 (uint64_t x) ecb_const;
|
867
|
+
ecb_function_ int ecb_ld64 (uint64_t x)
|
868
|
+
{
|
869
|
+
int r = 0;
|
870
|
+
|
871
|
+
if (x >> 32) { x >>= 32; r += 32; }
|
872
|
+
|
873
|
+
return r + ecb_ld32 (x);
|
874
|
+
}
|
472
875
|
#endif
|
473
876
|
|
474
|
-
|
475
|
-
|
476
|
-
|
877
|
+
ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) ecb_const;
|
878
|
+
ecb_function_ ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
|
879
|
+
ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) ecb_const;
|
880
|
+
ecb_function_ ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
|
881
|
+
|
882
|
+
ecb_function_ uint8_t ecb_bitrev8 (uint8_t x) ecb_const;
|
883
|
+
ecb_function_ uint8_t ecb_bitrev8 (uint8_t x)
|
884
|
+
{
|
885
|
+
return ( (x * 0x0802U & 0x22110U)
|
886
|
+
| (x * 0x8020U & 0x88440U)) * 0x10101U >> 16;
|
887
|
+
}
|
888
|
+
|
889
|
+
ecb_function_ uint16_t ecb_bitrev16 (uint16_t x) ecb_const;
|
890
|
+
ecb_function_ uint16_t ecb_bitrev16 (uint16_t x)
|
891
|
+
{
|
892
|
+
x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1);
|
893
|
+
x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);
|
894
|
+
x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4);
|
895
|
+
x = ( x >> 8 ) | ( x << 8);
|
896
|
+
|
897
|
+
return x;
|
898
|
+
}
|
899
|
+
|
900
|
+
ecb_function_ uint32_t ecb_bitrev32 (uint32_t x) ecb_const;
|
901
|
+
ecb_function_ uint32_t ecb_bitrev32 (uint32_t x)
|
902
|
+
{
|
903
|
+
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
|
904
|
+
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
|
905
|
+
x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
|
906
|
+
x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
|
907
|
+
x = ( x >> 16 ) | ( x << 16);
|
908
|
+
|
909
|
+
return x;
|
910
|
+
}
|
911
|
+
|
912
|
+
/* popcount64 is only available on 64 bit cpus as gcc builtin */
|
913
|
+
/* so for this version we are lazy */
|
914
|
+
ecb_function_ int ecb_popcount64 (uint64_t x) ecb_const;
|
915
|
+
ecb_function_ int
|
916
|
+
ecb_popcount64 (uint64_t x)
|
917
|
+
{
|
918
|
+
return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
|
919
|
+
}
|
920
|
+
|
921
|
+
ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) ecb_const;
|
922
|
+
ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) ecb_const;
|
923
|
+
ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) ecb_const;
|
924
|
+
ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) ecb_const;
|
925
|
+
ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) ecb_const;
|
926
|
+
ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) ecb_const;
|
927
|
+
ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) ecb_const;
|
928
|
+
ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) ecb_const;
|
929
|
+
|
930
|
+
ecb_inline uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
|
931
|
+
ecb_inline uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
|
932
|
+
ecb_inline uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
|
933
|
+
ecb_inline uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
|
934
|
+
ecb_inline uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
|
935
|
+
ecb_inline uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
|
936
|
+
ecb_inline uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
|
937
|
+
ecb_inline uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
|
938
|
+
|
939
|
+
#if ECB_GCC_VERSION(4,3)
|
940
|
+
#define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
|
941
|
+
#define ecb_bswap32(x) __builtin_bswap32 (x)
|
942
|
+
#define ecb_bswap64(x) __builtin_bswap64 (x)
|
943
|
+
#else
|
944
|
+
ecb_function_ uint16_t ecb_bswap16 (uint16_t x) ecb_const;
|
945
|
+
ecb_function_ uint16_t
|
946
|
+
ecb_bswap16 (uint16_t x)
|
947
|
+
{
|
948
|
+
return ecb_rotl16 (x, 8);
|
949
|
+
}
|
950
|
+
|
951
|
+
ecb_function_ uint32_t ecb_bswap32 (uint32_t x) ecb_const;
|
952
|
+
ecb_function_ uint32_t
|
953
|
+
ecb_bswap32 (uint32_t x)
|
954
|
+
{
|
955
|
+
return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
|
956
|
+
}
|
957
|
+
|
958
|
+
ecb_function_ uint64_t ecb_bswap64 (uint64_t x) ecb_const;
|
959
|
+
ecb_function_ uint64_t
|
960
|
+
ecb_bswap64 (uint64_t x)
|
961
|
+
{
|
962
|
+
return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
|
963
|
+
}
|
964
|
+
#endif
|
965
|
+
|
966
|
+
#if ECB_GCC_VERSION(4,5)
|
967
|
+
#define ecb_unreachable() __builtin_unreachable ()
|
968
|
+
#else
|
969
|
+
/* this seems to work fine, but gcc always emits a warning for it :/ */
|
970
|
+
ecb_inline void ecb_unreachable (void) ecb_noreturn;
|
971
|
+
ecb_inline void ecb_unreachable (void) { }
|
972
|
+
#endif
|
973
|
+
|
974
|
+
/* try to tell the compiler that some condition is definitely true */
|
975
|
+
#define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0
|
976
|
+
|
977
|
+
ecb_inline unsigned char ecb_byteorder_helper (void) ecb_const;
|
978
|
+
ecb_inline unsigned char
|
979
|
+
ecb_byteorder_helper (void)
|
980
|
+
{
|
981
|
+
/* the union code still generates code under pressure in gcc, */
|
982
|
+
/* but less than using pointers, and always seems to */
|
983
|
+
/* successfully return a constant. */
|
984
|
+
/* the reason why we have this horrible preprocessor mess */
|
985
|
+
/* is to avoid it in all cases, at least on common architectures */
|
986
|
+
/* or when using a recent enough gcc version (>= 4.6) */
|
987
|
+
#if __i386 || __i386__ || _M_X86 || __amd64 || __amd64__ || _M_X64
|
988
|
+
return 0x44;
|
989
|
+
#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
|
990
|
+
return 0x44;
|
991
|
+
#elif __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
|
992
|
+
return 0x11;
|
993
|
+
#else
|
994
|
+
union
|
995
|
+
{
|
996
|
+
uint32_t i;
|
997
|
+
uint8_t c;
|
998
|
+
} u = { 0x11223344 };
|
999
|
+
return u.c;
|
1000
|
+
#endif
|
1001
|
+
}
|
1002
|
+
|
1003
|
+
ecb_inline ecb_bool ecb_big_endian (void) ecb_const;
|
1004
|
+
ecb_inline ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11; }
|
1005
|
+
ecb_inline ecb_bool ecb_little_endian (void) ecb_const;
|
1006
|
+
ecb_inline ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44; }
|
1007
|
+
|
1008
|
+
#if ECB_GCC_VERSION(3,0) || ECB_C99
|
1009
|
+
#define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
|
1010
|
+
#else
|
1011
|
+
#define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
|
1012
|
+
#endif
|
1013
|
+
|
1014
|
+
#if __cplusplus
|
1015
|
+
template<typename T>
|
1016
|
+
static inline T ecb_div_rd (T val, T div)
|
1017
|
+
{
|
1018
|
+
return val < 0 ? - ((-val + div - 1) / div) : (val ) / div;
|
1019
|
+
}
|
1020
|
+
template<typename T>
|
1021
|
+
static inline T ecb_div_ru (T val, T div)
|
1022
|
+
{
|
1023
|
+
return val < 0 ? - ((-val ) / div) : (val + div - 1) / div;
|
1024
|
+
}
|
1025
|
+
#else
|
1026
|
+
#define ecb_div_rd(val,div) ((val) < 0 ? - ((-(val) + (div) - 1) / (div)) : ((val) ) / (div))
|
1027
|
+
#define ecb_div_ru(val,div) ((val) < 0 ? - ((-(val) ) / (div)) : ((val) + (div) - 1) / (div))
|
1028
|
+
#endif
|
1029
|
+
|
1030
|
+
#if ecb_cplusplus_does_not_suck
|
1031
|
+
/* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */
|
1032
|
+
template<typename T, int N>
|
1033
|
+
static inline int ecb_array_length (const T (&arr)[N])
|
1034
|
+
{
|
1035
|
+
return N;
|
1036
|
+
}
|
1037
|
+
#else
|
1038
|
+
#define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
|
1039
|
+
#endif
|
1040
|
+
|
1041
|
+
/*******************************************************************************/
|
1042
|
+
/* floating point stuff, can be disabled by defining ECB_NO_LIBM */
|
1043
|
+
|
1044
|
+
/* basically, everything uses "ieee pure-endian" floating point numbers */
|
1045
|
+
/* the only noteworthy exception is ancient armle, which uses order 43218765 */
|
1046
|
+
#if 0 \
|
1047
|
+
|| __i386 || __i386__ \
|
1048
|
+
|| __amd64 || __amd64__ || __x86_64 || __x86_64__ \
|
1049
|
+
|| __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \
|
1050
|
+
|| defined __arm__ && defined __ARM_EABI__ \
|
1051
|
+
|| defined __s390__ || defined __s390x__ \
|
1052
|
+
|| defined __mips__ \
|
1053
|
+
|| defined __alpha__ \
|
1054
|
+
|| defined __hppa__ \
|
1055
|
+
|| defined __ia64__ \
|
1056
|
+
|| defined _M_IX86 || defined _M_AMD64 || defined _M_IA64
|
1057
|
+
#define ECB_STDFP 1
|
1058
|
+
#include <string.h> /* for memcpy */
|
1059
|
+
#else
|
1060
|
+
#define ECB_STDFP 0
|
1061
|
+
#include <math.h> /* for frexp*, ldexp* */
|
1062
|
+
#endif
|
1063
|
+
|
1064
|
+
#ifndef ECB_NO_LIBM
|
1065
|
+
|
1066
|
+
/* convert a float to ieee single/binary32 */
|
1067
|
+
ecb_function_ uint32_t ecb_float_to_binary32 (float x) ecb_const;
|
1068
|
+
ecb_function_ uint32_t
|
1069
|
+
ecb_float_to_binary32 (float x)
|
1070
|
+
{
|
1071
|
+
uint32_t r;
|
1072
|
+
|
1073
|
+
#if ECB_STDFP
|
1074
|
+
memcpy (&r, &x, 4);
|
1075
|
+
#else
|
1076
|
+
/* slow emulation, works for anything but -0 */
|
1077
|
+
uint32_t m;
|
1078
|
+
int e;
|
1079
|
+
|
1080
|
+
if (x == 0e0f ) return 0x00000000U;
|
1081
|
+
if (x > +3.40282346638528860e+38f) return 0x7f800000U;
|
1082
|
+
if (x < -3.40282346638528860e+38f) return 0xff800000U;
|
1083
|
+
if (x != x ) return 0x7fbfffffU;
|
1084
|
+
|
1085
|
+
m = frexpf (x, &e) * 0x1000000U;
|
1086
|
+
|
1087
|
+
r = m & 0x80000000U;
|
1088
|
+
|
1089
|
+
if (r)
|
1090
|
+
m = -m;
|
1091
|
+
|
1092
|
+
if (e <= -126)
|
1093
|
+
{
|
1094
|
+
m &= 0xffffffU;
|
1095
|
+
m >>= (-125 - e);
|
1096
|
+
e = -126;
|
1097
|
+
}
|
1098
|
+
|
1099
|
+
r |= (e + 126) << 23;
|
1100
|
+
r |= m & 0x7fffffU;
|
1101
|
+
#endif
|
1102
|
+
|
1103
|
+
return r;
|
1104
|
+
}
|
1105
|
+
|
1106
|
+
/* converts an ieee single/binary32 to a float */
|
1107
|
+
ecb_function_ float ecb_binary32_to_float (uint32_t x) ecb_const;
|
1108
|
+
ecb_function_ float
|
1109
|
+
ecb_binary32_to_float (uint32_t x)
|
1110
|
+
{
|
1111
|
+
float r;
|
1112
|
+
|
1113
|
+
#if ECB_STDFP
|
1114
|
+
memcpy (&r, &x, 4);
|
1115
|
+
#else
|
1116
|
+
/* emulation, only works for normals and subnormals and +0 */
|
1117
|
+
int neg = x >> 31;
|
1118
|
+
int e = (x >> 23) & 0xffU;
|
1119
|
+
|
1120
|
+
x &= 0x7fffffU;
|
1121
|
+
|
1122
|
+
if (e)
|
1123
|
+
x |= 0x800000U;
|
1124
|
+
else
|
1125
|
+
e = 1;
|
1126
|
+
|
1127
|
+
/* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */
|
1128
|
+
r = ldexpf (x * (0.5f / 0x800000U), e - 126);
|
1129
|
+
|
1130
|
+
r = neg ? -r : r;
|
1131
|
+
#endif
|
1132
|
+
|
1133
|
+
return r;
|
1134
|
+
}
|
1135
|
+
|
1136
|
+
/* convert a double to ieee double/binary64 */
|
1137
|
+
ecb_function_ uint64_t ecb_double_to_binary64 (double x) ecb_const;
|
1138
|
+
ecb_function_ uint64_t
|
1139
|
+
ecb_double_to_binary64 (double x)
|
1140
|
+
{
|
1141
|
+
uint64_t r;
|
1142
|
+
|
1143
|
+
#if ECB_STDFP
|
1144
|
+
memcpy (&r, &x, 8);
|
1145
|
+
#else
|
1146
|
+
/* slow emulation, works for anything but -0 */
|
1147
|
+
uint64_t m;
|
1148
|
+
int e;
|
1149
|
+
|
1150
|
+
if (x == 0e0 ) return 0x0000000000000000U;
|
1151
|
+
if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U;
|
1152
|
+
if (x < -1.79769313486231470e+308) return 0xfff0000000000000U;
|
1153
|
+
if (x != x ) return 0X7ff7ffffffffffffU;
|
1154
|
+
|
1155
|
+
m = frexp (x, &e) * 0x20000000000000U;
|
1156
|
+
|
1157
|
+
r = m & 0x8000000000000000;;
|
1158
|
+
|
1159
|
+
if (r)
|
1160
|
+
m = -m;
|
1161
|
+
|
1162
|
+
if (e <= -1022)
|
1163
|
+
{
|
1164
|
+
m &= 0x1fffffffffffffU;
|
1165
|
+
m >>= (-1021 - e);
|
1166
|
+
e = -1022;
|
1167
|
+
}
|
1168
|
+
|
1169
|
+
r |= ((uint64_t)(e + 1022)) << 52;
|
1170
|
+
r |= m & 0xfffffffffffffU;
|
1171
|
+
#endif
|
1172
|
+
|
1173
|
+
return r;
|
1174
|
+
}
|
1175
|
+
|
1176
|
+
/* converts an ieee double/binary64 to a double */
|
1177
|
+
ecb_function_ double ecb_binary64_to_double (uint64_t x) ecb_const;
|
1178
|
+
ecb_function_ double
|
1179
|
+
ecb_binary64_to_double (uint64_t x)
|
1180
|
+
{
|
1181
|
+
double r;
|
1182
|
+
|
1183
|
+
#if ECB_STDFP
|
1184
|
+
memcpy (&r, &x, 8);
|
1185
|
+
#else
|
1186
|
+
/* emulation, only works for normals and subnormals and +0 */
|
1187
|
+
int neg = x >> 63;
|
1188
|
+
int e = (x >> 52) & 0x7ffU;
|
1189
|
+
|
1190
|
+
x &= 0xfffffffffffffU;
|
1191
|
+
|
1192
|
+
if (e)
|
1193
|
+
x |= 0x10000000000000U;
|
1194
|
+
else
|
1195
|
+
e = 1;
|
1196
|
+
|
1197
|
+
/* we distrust ldexp a bit and do the 2**-53 scaling by an extra multiply */
|
1198
|
+
r = ldexp (x * (0.5 / 0x10000000000000U), e - 1022);
|
1199
|
+
|
1200
|
+
r = neg ? -r : r;
|
1201
|
+
#endif
|
1202
|
+
|
1203
|
+
return r;
|
1204
|
+
}
|
1205
|
+
|
1206
|
+
#endif
|
1207
|
+
|
1208
|
+
#endif
|
1209
|
+
|
1210
|
+
/* ECB.H END */
|
1211
|
+
|
1212
|
+
#if ECB_MEMORY_FENCE_NEEDS_PTHREADS
|
1213
|
+
/* if your architecture doesn't need memory fences, e.g. because it is
|
1214
|
+
* single-cpu/core, or if you use libev in a project that doesn't use libev
|
1215
|
+
* from multiple threads, then you can define ECB_AVOID_PTHREADS when compiling
|
1216
|
+
* libev, in which cases the memory fences become nops.
|
1217
|
+
* alternatively, you can remove this #error and link against libpthread,
|
1218
|
+
* which will then provide the memory fences.
|
1219
|
+
*/
|
1220
|
+
# error "memory fences not defined for your architecture, please report"
|
1221
|
+
#endif
|
1222
|
+
|
1223
|
+
#ifndef ECB_MEMORY_FENCE
|
1224
|
+
# define ECB_MEMORY_FENCE do { } while (0)
|
1225
|
+
# define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
|
1226
|
+
# define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
|
1227
|
+
#endif
|
1228
|
+
|
1229
|
+
#define expect_false(cond) ecb_expect_false (cond)
|
1230
|
+
#define expect_true(cond) ecb_expect_true (cond)
|
1231
|
+
#define noinline ecb_noinline
|
1232
|
+
|
1233
|
+
#define inline_size ecb_inline
|
477
1234
|
|
478
1235
|
#if EV_FEATURE_CODE
|
479
|
-
# define inline_speed
|
1236
|
+
# define inline_speed ecb_inline
|
480
1237
|
#else
|
481
1238
|
# define inline_speed static noinline
|
482
1239
|
#endif
|
@@ -525,11 +1282,59 @@ static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work?
|
|
525
1282
|
|
526
1283
|
/*****************************************************************************/
|
527
1284
|
|
1285
|
+
/* define a suitable floor function (only used by periodics atm) */
|
1286
|
+
|
1287
|
+
#if EV_USE_FLOOR
|
1288
|
+
# include <math.h>
|
1289
|
+
# define ev_floor(v) floor (v)
|
1290
|
+
#else
|
1291
|
+
|
1292
|
+
#include <float.h>
|
1293
|
+
|
1294
|
+
/* a floor() replacement function, should be independent of ev_tstamp type */
|
1295
|
+
static ev_tstamp noinline
|
1296
|
+
ev_floor (ev_tstamp v)
|
1297
|
+
{
|
1298
|
+
/* the choice of shift factor is not terribly important */
|
1299
|
+
#if FLT_RADIX != 2 /* assume FLT_RADIX == 10 */
|
1300
|
+
const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.;
|
1301
|
+
#else
|
1302
|
+
const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.;
|
1303
|
+
#endif
|
1304
|
+
|
1305
|
+
/* argument too large for an unsigned long? */
|
1306
|
+
if (expect_false (v >= shift))
|
1307
|
+
{
|
1308
|
+
ev_tstamp f;
|
1309
|
+
|
1310
|
+
if (v == v - 1.)
|
1311
|
+
return v; /* very large number */
|
1312
|
+
|
1313
|
+
f = shift * ev_floor (v * (1. / shift));
|
1314
|
+
return f + ev_floor (v - f);
|
1315
|
+
}
|
1316
|
+
|
1317
|
+
/* special treatment for negative args? */
|
1318
|
+
if (expect_false (v < 0.))
|
1319
|
+
{
|
1320
|
+
ev_tstamp f = -ev_floor (-v);
|
1321
|
+
|
1322
|
+
return f - (f == v ? 0 : 1);
|
1323
|
+
}
|
1324
|
+
|
1325
|
+
/* fits into an unsigned long */
|
1326
|
+
return (unsigned long)v;
|
1327
|
+
}
|
1328
|
+
|
1329
|
+
#endif
|
1330
|
+
|
1331
|
+
/*****************************************************************************/
|
1332
|
+
|
528
1333
|
#ifdef __linux
|
529
1334
|
# include <sys/utsname.h>
|
530
1335
|
#endif
|
531
1336
|
|
532
|
-
static unsigned int noinline
|
1337
|
+
static unsigned int noinline ecb_cold
|
533
1338
|
ev_linux_version (void)
|
534
1339
|
{
|
535
1340
|
#ifdef __linux
|
@@ -568,22 +1373,22 @@ ev_linux_version (void)
|
|
568
1373
|
/*****************************************************************************/
|
569
1374
|
|
570
1375
|
#if EV_AVOID_STDIO
|
571
|
-
static void noinline
|
1376
|
+
static void noinline ecb_cold
|
572
1377
|
ev_printerr (const char *msg)
|
573
1378
|
{
|
574
1379
|
write (STDERR_FILENO, msg, strlen (msg));
|
575
1380
|
}
|
576
1381
|
#endif
|
577
1382
|
|
578
|
-
static void (*syserr_cb)(const char *msg);
|
1383
|
+
static void (*syserr_cb)(const char *msg) EV_THROW;
|
579
1384
|
|
580
|
-
void
|
581
|
-
ev_set_syserr_cb (void (*cb)(const char *msg))
|
1385
|
+
void ecb_cold
|
1386
|
+
ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW
|
582
1387
|
{
|
583
1388
|
syserr_cb = cb;
|
584
1389
|
}
|
585
1390
|
|
586
|
-
static void noinline
|
1391
|
+
static void noinline ecb_cold
|
587
1392
|
ev_syserr (const char *msg)
|
588
1393
|
{
|
589
1394
|
if (!msg)
|
@@ -606,14 +1411,13 @@ ev_syserr (const char *msg)
|
|
606
1411
|
}
|
607
1412
|
|
608
1413
|
static void *
|
609
|
-
ev_realloc_emul (void *ptr, long size)
|
1414
|
+
ev_realloc_emul (void *ptr, long size) EV_THROW
|
610
1415
|
{
|
611
|
-
#if __GLIBC__
|
612
|
-
return realloc (ptr, size);
|
613
|
-
#else
|
614
1416
|
/* some systems, notably openbsd and darwin, fail to properly
|
615
1417
|
* implement realloc (x, 0) (as required by both ansi c-89 and
|
616
1418
|
* the single unix specification, so work around them here.
|
1419
|
+
* recently, also (at least) fedora and debian started breaking it,
|
1420
|
+
* despite documenting it otherwise.
|
617
1421
|
*/
|
618
1422
|
|
619
1423
|
if (size)
|
@@ -621,13 +1425,12 @@ ev_realloc_emul (void *ptr, long size)
|
|
621
1425
|
|
622
1426
|
free (ptr);
|
623
1427
|
return 0;
|
624
|
-
#endif
|
625
1428
|
}
|
626
1429
|
|
627
|
-
static void *(*alloc)(void *ptr, long size) = ev_realloc_emul;
|
1430
|
+
static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul;
|
628
1431
|
|
629
|
-
void
|
630
|
-
ev_set_allocator (void *(*cb)(void *ptr, long size))
|
1432
|
+
void ecb_cold
|
1433
|
+
ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW
|
631
1434
|
{
|
632
1435
|
alloc = cb;
|
633
1436
|
}
|
@@ -725,11 +1528,11 @@ typedef struct
|
|
725
1528
|
#include "ev_wrap.h"
|
726
1529
|
|
727
1530
|
static struct ev_loop default_loop_struct;
|
728
|
-
struct ev_loop *ev_default_loop_ptr;
|
1531
|
+
EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
|
729
1532
|
|
730
1533
|
#else
|
731
1534
|
|
732
|
-
ev_tstamp ev_rt_now;
|
1535
|
+
EV_API_DECL ev_tstamp ev_rt_now = 0; /* needs to be initialised to make it a definition despite extern */
|
733
1536
|
#define VAR(name,decl) static decl;
|
734
1537
|
#include "ev_vars.h"
|
735
1538
|
#undef VAR
|
@@ -754,7 +1557,7 @@ typedef struct
|
|
754
1557
|
|
755
1558
|
#ifndef EV_HAVE_EV_TIME
|
756
1559
|
ev_tstamp
|
757
|
-
ev_time (void)
|
1560
|
+
ev_time (void) EV_THROW
|
758
1561
|
{
|
759
1562
|
#if EV_USE_REALTIME
|
760
1563
|
if (expect_true (have_realtime))
|
@@ -788,14 +1591,14 @@ get_clock (void)
|
|
788
1591
|
|
789
1592
|
#if EV_MULTIPLICITY
|
790
1593
|
ev_tstamp
|
791
|
-
ev_now (EV_P)
|
1594
|
+
ev_now (EV_P) EV_THROW
|
792
1595
|
{
|
793
1596
|
return ev_rt_now;
|
794
1597
|
}
|
795
1598
|
#endif
|
796
1599
|
|
797
1600
|
void
|
798
|
-
ev_sleep (ev_tstamp delay)
|
1601
|
+
ev_sleep (ev_tstamp delay) EV_THROW
|
799
1602
|
{
|
800
1603
|
if (delay > 0.)
|
801
1604
|
{
|
@@ -804,7 +1607,7 @@ ev_sleep (ev_tstamp delay)
|
|
804
1607
|
|
805
1608
|
EV_TS_SET (ts, delay);
|
806
1609
|
nanosleep (&ts, 0);
|
807
|
-
#elif defined
|
1610
|
+
#elif defined _WIN32
|
808
1611
|
Sleep ((unsigned long)(delay * 1e3));
|
809
1612
|
#else
|
810
1613
|
struct timeval tv;
|
@@ -818,14 +1621,6 @@ ev_sleep (ev_tstamp delay)
|
|
818
1621
|
}
|
819
1622
|
}
|
820
1623
|
|
821
|
-
inline_speed int
|
822
|
-
ev_timeout_to_ms (ev_tstamp timeout)
|
823
|
-
{
|
824
|
-
int ms = timeout * 1000. + .999999;
|
825
|
-
|
826
|
-
return expect_true (ms) ? ms : timeout < 1e-6 ? 0 : 1;
|
827
|
-
}
|
828
|
-
|
829
1624
|
/*****************************************************************************/
|
830
1625
|
|
831
1626
|
#define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
|
@@ -841,7 +1636,7 @@ array_nextsize (int elem, int cur, int cnt)
|
|
841
1636
|
ncur <<= 1;
|
842
1637
|
while (cnt > ncur);
|
843
1638
|
|
844
|
-
/* if size is large, round to MALLOC_ROUND - 4 * longs to
|
1639
|
+
/* if size is large, round to MALLOC_ROUND - 4 * longs to accommodate malloc overhead */
|
845
1640
|
if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
|
846
1641
|
{
|
847
1642
|
ncur *= elem;
|
@@ -853,7 +1648,7 @@ array_nextsize (int elem, int cur, int cnt)
|
|
853
1648
|
return ncur;
|
854
1649
|
}
|
855
1650
|
|
856
|
-
static
|
1651
|
+
static void * noinline ecb_cold
|
857
1652
|
array_realloc (int elem, void *base, int *cur, int cnt)
|
858
1653
|
{
|
859
1654
|
*cur = array_nextsize (elem, *cur, cnt);
|
@@ -866,7 +1661,7 @@ array_realloc (int elem, void *base, int *cur, int cnt)
|
|
866
1661
|
#define array_needsize(type,base,cur,cnt,init) \
|
867
1662
|
if (expect_false ((cnt) > (cur))) \
|
868
1663
|
{ \
|
869
|
-
int ocur_ = (cur); \
|
1664
|
+
int ecb_unused ocur_ = (cur); \
|
870
1665
|
(base) = (type *)array_realloc \
|
871
1666
|
(sizeof (type), (base), &(cur), (cnt)); \
|
872
1667
|
init ((base) + (ocur_), (cur) - ocur_); \
|
@@ -894,7 +1689,7 @@ pendingcb (EV_P_ ev_prepare *w, int revents)
|
|
894
1689
|
}
|
895
1690
|
|
896
1691
|
void noinline
|
897
|
-
ev_feed_event (EV_P_ void *w, int revents)
|
1692
|
+
ev_feed_event (EV_P_ void *w, int revents) EV_THROW
|
898
1693
|
{
|
899
1694
|
W w_ = (W)w;
|
900
1695
|
int pri = ABSPRI (w_);
|
@@ -908,6 +1703,8 @@ ev_feed_event (EV_P_ void *w, int revents)
|
|
908
1703
|
pendings [pri][w_->pending - 1].w = w_;
|
909
1704
|
pendings [pri][w_->pending - 1].events = revents;
|
910
1705
|
}
|
1706
|
+
|
1707
|
+
pendingpri = NUMPRI - 1;
|
911
1708
|
}
|
912
1709
|
|
913
1710
|
inline_speed void
|
@@ -963,7 +1760,7 @@ fd_event (EV_P_ int fd, int revents)
|
|
963
1760
|
}
|
964
1761
|
|
965
1762
|
void
|
966
|
-
ev_feed_fd_event (EV_P_ int fd, int revents)
|
1763
|
+
ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW
|
967
1764
|
{
|
968
1765
|
if (fd >= 0 && fd < anfdmax)
|
969
1766
|
fd_event_nocheck (EV_A_ fd, revents);
|
@@ -982,7 +1779,7 @@ fd_reify (EV_P)
|
|
982
1779
|
int fd = fdchanges [i];
|
983
1780
|
ANFD *anfd = anfds + fd;
|
984
1781
|
|
985
|
-
if (anfd->reify & EV__IOFDSET)
|
1782
|
+
if (anfd->reify & EV__IOFDSET && anfd->head)
|
986
1783
|
{
|
987
1784
|
SOCKET handle = EV_FD_TO_WIN32_HANDLE (fd);
|
988
1785
|
|
@@ -1046,7 +1843,7 @@ fd_change (EV_P_ int fd, int flags)
|
|
1046
1843
|
}
|
1047
1844
|
|
1048
1845
|
/* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
|
1049
|
-
inline_speed void
|
1846
|
+
inline_speed void ecb_cold
|
1050
1847
|
fd_kill (EV_P_ int fd)
|
1051
1848
|
{
|
1052
1849
|
ev_io *w;
|
@@ -1059,7 +1856,7 @@ fd_kill (EV_P_ int fd)
|
|
1059
1856
|
}
|
1060
1857
|
|
1061
1858
|
/* check whether the given fd is actually valid, for error recovery */
|
1062
|
-
inline_size int
|
1859
|
+
inline_size int ecb_cold
|
1063
1860
|
fd_valid (int fd)
|
1064
1861
|
{
|
1065
1862
|
#ifdef _WIN32
|
@@ -1070,7 +1867,7 @@ fd_valid (int fd)
|
|
1070
1867
|
}
|
1071
1868
|
|
1072
1869
|
/* called on EBADF to verify fds */
|
1073
|
-
static void noinline
|
1870
|
+
static void noinline ecb_cold
|
1074
1871
|
fd_ebadf (EV_P)
|
1075
1872
|
{
|
1076
1873
|
int fd;
|
@@ -1082,7 +1879,7 @@ fd_ebadf (EV_P)
|
|
1082
1879
|
}
|
1083
1880
|
|
1084
1881
|
/* called on ENOMEM in select/poll to kill some fds and retry */
|
1085
|
-
static void noinline
|
1882
|
+
static void noinline ecb_cold
|
1086
1883
|
fd_enomem (EV_P)
|
1087
1884
|
{
|
1088
1885
|
int fd;
|
@@ -1287,62 +2084,94 @@ static ANSIG signals [EV_NSIG - 1];
|
|
1287
2084
|
|
1288
2085
|
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
|
1289
2086
|
|
1290
|
-
static void noinline
|
2087
|
+
static void noinline ecb_cold
|
1291
2088
|
evpipe_init (EV_P)
|
1292
2089
|
{
|
1293
2090
|
if (!ev_is_active (&pipe_w))
|
1294
2091
|
{
|
2092
|
+
int fds [2];
|
2093
|
+
|
1295
2094
|
# if EV_USE_EVENTFD
|
1296
|
-
|
1297
|
-
|
1298
|
-
|
2095
|
+
fds [0] = -1;
|
2096
|
+
fds [1] = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
|
2097
|
+
if (fds [1] < 0 && errno == EINVAL)
|
2098
|
+
fds [1] = eventfd (0, 0);
|
1299
2099
|
|
1300
|
-
if (
|
2100
|
+
if (fds [1] < 0)
|
2101
|
+
# endif
|
1301
2102
|
{
|
1302
|
-
|
1303
|
-
|
1304
|
-
|
2103
|
+
while (pipe (fds))
|
2104
|
+
ev_syserr ("(libev) error creating signal/async pipe");
|
2105
|
+
|
2106
|
+
fd_intern (fds [0]);
|
1305
2107
|
}
|
2108
|
+
|
2109
|
+
fd_intern (fds [1]);
|
2110
|
+
|
2111
|
+
evpipe [0] = fds [0];
|
2112
|
+
|
2113
|
+
if (evpipe [1] < 0)
|
2114
|
+
evpipe [1] = fds [1]; /* first call, set write fd */
|
1306
2115
|
else
|
1307
|
-
# endif
|
1308
2116
|
{
|
1309
|
-
|
1310
|
-
|
2117
|
+
/* on subsequent calls, do not change evpipe [1] */
|
2118
|
+
/* so that evpipe_write can always rely on its value. */
|
2119
|
+
/* this branch does not do anything sensible on windows, */
|
2120
|
+
/* so must not be executed on windows */
|
1311
2121
|
|
1312
|
-
|
1313
|
-
|
1314
|
-
ev_io_set (&pipe_w, evpipe [0], EV_READ);
|
2122
|
+
dup2 (fds [1], evpipe [1]);
|
2123
|
+
close (fds [1]);
|
1315
2124
|
}
|
1316
2125
|
|
2126
|
+
ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ);
|
1317
2127
|
ev_io_start (EV_A_ &pipe_w);
|
1318
2128
|
ev_unref (EV_A); /* watcher should not keep loop alive */
|
1319
2129
|
}
|
1320
2130
|
}
|
1321
2131
|
|
1322
|
-
|
2132
|
+
inline_speed void
|
1323
2133
|
evpipe_write (EV_P_ EV_ATOMIC_T *flag)
|
1324
2134
|
{
|
1325
|
-
|
2135
|
+
ECB_MEMORY_FENCE; /* push out the write before this function was called, acquire flag */
|
2136
|
+
|
2137
|
+
if (expect_true (*flag))
|
2138
|
+
return;
|
2139
|
+
|
2140
|
+
*flag = 1;
|
2141
|
+
ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */
|
2142
|
+
|
2143
|
+
pipe_write_skipped = 1;
|
2144
|
+
|
2145
|
+
ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */
|
2146
|
+
|
2147
|
+
if (pipe_write_wanted)
|
1326
2148
|
{
|
1327
|
-
int old_errno
|
1328
|
-
|
2149
|
+
int old_errno;
|
2150
|
+
|
2151
|
+
pipe_write_skipped = 0;
|
2152
|
+
ECB_MEMORY_FENCE_RELEASE;
|
1329
2153
|
|
1330
|
-
|
2154
|
+
old_errno = errno; /* save errno because write will clobber it */
|
1331
2155
|
|
1332
2156
|
#if EV_USE_EVENTFD
|
1333
|
-
if (
|
2157
|
+
if (evpipe [0] < 0)
|
1334
2158
|
{
|
1335
2159
|
uint64_t counter = 1;
|
1336
|
-
write (
|
2160
|
+
write (evpipe [1], &counter, sizeof (uint64_t));
|
1337
2161
|
}
|
1338
2162
|
else
|
1339
2163
|
#endif
|
1340
|
-
|
1341
|
-
|
1342
|
-
|
1343
|
-
|
1344
|
-
|
1345
|
-
|
2164
|
+
{
|
2165
|
+
#ifdef _WIN32
|
2166
|
+
WSABUF buf;
|
2167
|
+
DWORD sent;
|
2168
|
+
buf.buf = &buf;
|
2169
|
+
buf.len = 1;
|
2170
|
+
WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0);
|
2171
|
+
#else
|
2172
|
+
write (evpipe [1], &(evpipe [1]), 1);
|
2173
|
+
#endif
|
2174
|
+
}
|
1346
2175
|
|
1347
2176
|
errno = old_errno;
|
1348
2177
|
}
|
@@ -1355,25 +2184,42 @@ pipecb (EV_P_ ev_io *iow, int revents)
|
|
1355
2184
|
{
|
1356
2185
|
int i;
|
1357
2186
|
|
1358
|
-
|
1359
|
-
if (evfd >= 0)
|
2187
|
+
if (revents & EV_READ)
|
1360
2188
|
{
|
1361
|
-
|
1362
|
-
|
1363
|
-
|
1364
|
-
|
2189
|
+
#if EV_USE_EVENTFD
|
2190
|
+
if (evpipe [0] < 0)
|
2191
|
+
{
|
2192
|
+
uint64_t counter;
|
2193
|
+
read (evpipe [1], &counter, sizeof (uint64_t));
|
2194
|
+
}
|
2195
|
+
else
|
1365
2196
|
#endif
|
1366
|
-
|
1367
|
-
|
1368
|
-
|
1369
|
-
|
2197
|
+
{
|
2198
|
+
char dummy[4];
|
2199
|
+
#ifdef _WIN32
|
2200
|
+
WSABUF buf;
|
2201
|
+
DWORD recvd;
|
2202
|
+
DWORD flags = 0;
|
2203
|
+
buf.buf = dummy;
|
2204
|
+
buf.len = sizeof (dummy);
|
2205
|
+
WSARecv (EV_FD_TO_WIN32_HANDLE (evpipe [0]), &buf, 1, &recvd, &flags, 0, 0);
|
2206
|
+
#else
|
2207
|
+
read (evpipe [0], &dummy, sizeof (dummy));
|
2208
|
+
#endif
|
2209
|
+
}
|
1370
2210
|
}
|
1371
2211
|
|
2212
|
+
pipe_write_skipped = 0;
|
2213
|
+
|
2214
|
+
ECB_MEMORY_FENCE; /* push out skipped, acquire flags */
|
2215
|
+
|
1372
2216
|
#if EV_SIGNAL_ENABLE
|
1373
2217
|
if (sig_pending)
|
1374
2218
|
{
|
1375
2219
|
sig_pending = 0;
|
1376
2220
|
|
2221
|
+
ECB_MEMORY_FENCE;
|
2222
|
+
|
1377
2223
|
for (i = EV_NSIG - 1; i--; )
|
1378
2224
|
if (expect_false (signals [i].pending))
|
1379
2225
|
ev_feed_signal_event (EV_A_ i + 1);
|
@@ -1385,10 +2231,13 @@ pipecb (EV_P_ ev_io *iow, int revents)
|
|
1385
2231
|
{
|
1386
2232
|
async_pending = 0;
|
1387
2233
|
|
2234
|
+
ECB_MEMORY_FENCE;
|
2235
|
+
|
1388
2236
|
for (i = asynccnt; i--; )
|
1389
2237
|
if (asyncs [i]->sent)
|
1390
2238
|
{
|
1391
2239
|
asyncs [i]->sent = 0;
|
2240
|
+
ECB_MEMORY_FENCE_RELEASE;
|
1392
2241
|
ev_feed_event (EV_A_ asyncs [i], EV_ASYNC);
|
1393
2242
|
}
|
1394
2243
|
}
|
@@ -1398,10 +2247,12 @@ pipecb (EV_P_ ev_io *iow, int revents)
|
|
1398
2247
|
/*****************************************************************************/
|
1399
2248
|
|
1400
2249
|
void
|
1401
|
-
ev_feed_signal (int signum)
|
2250
|
+
ev_feed_signal (int signum) EV_THROW
|
1402
2251
|
{
|
1403
2252
|
#if EV_MULTIPLICITY
|
1404
|
-
EV_P
|
2253
|
+
EV_P;
|
2254
|
+
ECB_MEMORY_FENCE_ACQUIRE;
|
2255
|
+
EV_A = signals [signum - 1].loop;
|
1405
2256
|
|
1406
2257
|
if (!EV_A)
|
1407
2258
|
return;
|
@@ -1422,11 +2273,11 @@ ev_sighandler (int signum)
|
|
1422
2273
|
}
|
1423
2274
|
|
1424
2275
|
void noinline
|
1425
|
-
ev_feed_signal_event (EV_P_ int signum)
|
2276
|
+
ev_feed_signal_event (EV_P_ int signum) EV_THROW
|
1426
2277
|
{
|
1427
2278
|
WL w;
|
1428
2279
|
|
1429
|
-
if (expect_false (signum <= 0 || signum
|
2280
|
+
if (expect_false (signum <= 0 || signum >= EV_NSIG))
|
1430
2281
|
return;
|
1431
2282
|
|
1432
2283
|
--signum;
|
@@ -1440,6 +2291,7 @@ ev_feed_signal_event (EV_P_ int signum)
|
|
1440
2291
|
#endif
|
1441
2292
|
|
1442
2293
|
signals [signum].pending = 0;
|
2294
|
+
ECB_MEMORY_FENCE_RELEASE;
|
1443
2295
|
|
1444
2296
|
for (w = signals [signum].head; w; w = w->next)
|
1445
2297
|
ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
|
@@ -1547,20 +2399,20 @@ childcb (EV_P_ ev_signal *sw, int revents)
|
|
1547
2399
|
# include "ev_select.c"
|
1548
2400
|
#endif
|
1549
2401
|
|
1550
|
-
int
|
1551
|
-
ev_version_major (void)
|
2402
|
+
int ecb_cold
|
2403
|
+
ev_version_major (void) EV_THROW
|
1552
2404
|
{
|
1553
2405
|
return EV_VERSION_MAJOR;
|
1554
2406
|
}
|
1555
2407
|
|
1556
|
-
int
|
1557
|
-
ev_version_minor (void)
|
2408
|
+
int ecb_cold
|
2409
|
+
ev_version_minor (void) EV_THROW
|
1558
2410
|
{
|
1559
2411
|
return EV_VERSION_MINOR;
|
1560
2412
|
}
|
1561
2413
|
|
1562
2414
|
/* return true if we are running with elevated privileges and should ignore env variables */
|
1563
|
-
int inline_size
|
2415
|
+
int inline_size ecb_cold
|
1564
2416
|
enable_secure (void)
|
1565
2417
|
{
|
1566
2418
|
#ifdef _WIN32
|
@@ -1571,8 +2423,8 @@ enable_secure (void)
|
|
1571
2423
|
#endif
|
1572
2424
|
}
|
1573
2425
|
|
1574
|
-
unsigned int
|
1575
|
-
ev_supported_backends (void)
|
2426
|
+
unsigned int ecb_cold
|
2427
|
+
ev_supported_backends (void) EV_THROW
|
1576
2428
|
{
|
1577
2429
|
unsigned int flags = 0;
|
1578
2430
|
|
@@ -1585,8 +2437,8 @@ ev_supported_backends (void)
|
|
1585
2437
|
return flags;
|
1586
2438
|
}
|
1587
2439
|
|
1588
|
-
unsigned int
|
1589
|
-
ev_recommended_backends (void)
|
2440
|
+
unsigned int ecb_cold
|
2441
|
+
ev_recommended_backends (void) EV_THROW
|
1590
2442
|
{
|
1591
2443
|
unsigned int flags = ev_supported_backends ();
|
1592
2444
|
|
@@ -1607,8 +2459,8 @@ ev_recommended_backends (void)
|
|
1607
2459
|
return flags;
|
1608
2460
|
}
|
1609
2461
|
|
1610
|
-
unsigned int
|
1611
|
-
ev_embeddable_backends (void)
|
2462
|
+
unsigned int ecb_cold
|
2463
|
+
ev_embeddable_backends (void) EV_THROW
|
1612
2464
|
{
|
1613
2465
|
int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
|
1614
2466
|
|
@@ -1620,54 +2472,56 @@ ev_embeddable_backends (void)
|
|
1620
2472
|
}
|
1621
2473
|
|
1622
2474
|
unsigned int
|
1623
|
-
ev_backend (EV_P)
|
2475
|
+
ev_backend (EV_P) EV_THROW
|
1624
2476
|
{
|
1625
2477
|
return backend;
|
1626
2478
|
}
|
1627
2479
|
|
1628
2480
|
#if EV_FEATURE_API
|
1629
2481
|
unsigned int
|
1630
|
-
ev_iteration (EV_P)
|
2482
|
+
ev_iteration (EV_P) EV_THROW
|
1631
2483
|
{
|
1632
2484
|
return loop_count;
|
1633
2485
|
}
|
1634
2486
|
|
1635
2487
|
unsigned int
|
1636
|
-
ev_depth (EV_P)
|
2488
|
+
ev_depth (EV_P) EV_THROW
|
1637
2489
|
{
|
1638
2490
|
return loop_depth;
|
1639
2491
|
}
|
1640
2492
|
|
1641
2493
|
void
|
1642
|
-
ev_set_io_collect_interval (EV_P_ ev_tstamp interval)
|
2494
|
+
ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
|
1643
2495
|
{
|
1644
2496
|
io_blocktime = interval;
|
1645
2497
|
}
|
1646
2498
|
|
1647
2499
|
void
|
1648
|
-
ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval)
|
2500
|
+
ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
|
1649
2501
|
{
|
1650
2502
|
timeout_blocktime = interval;
|
1651
2503
|
}
|
1652
2504
|
|
1653
2505
|
void
|
1654
|
-
ev_set_userdata (EV_P_ void *data)
|
2506
|
+
ev_set_userdata (EV_P_ void *data) EV_THROW
|
1655
2507
|
{
|
1656
2508
|
userdata = data;
|
1657
2509
|
}
|
1658
2510
|
|
1659
2511
|
void *
|
1660
|
-
ev_userdata (EV_P)
|
2512
|
+
ev_userdata (EV_P) EV_THROW
|
1661
2513
|
{
|
1662
2514
|
return userdata;
|
1663
2515
|
}
|
1664
2516
|
|
1665
|
-
void
|
2517
|
+
void
|
2518
|
+
ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P)) EV_THROW
|
1666
2519
|
{
|
1667
2520
|
invoke_cb = invoke_pending_cb;
|
1668
2521
|
}
|
1669
2522
|
|
1670
|
-
void
|
2523
|
+
void
|
2524
|
+
ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW
|
1671
2525
|
{
|
1672
2526
|
release_cb = release;
|
1673
2527
|
acquire_cb = acquire;
|
@@ -1675,8 +2529,8 @@ void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P))
|
|
1675
2529
|
#endif
|
1676
2530
|
|
1677
2531
|
/* initialise a loop structure, must be zero-initialised */
|
1678
|
-
static void noinline
|
1679
|
-
loop_init (EV_P_ unsigned int flags)
|
2532
|
+
static void noinline ecb_cold
|
2533
|
+
loop_init (EV_P_ unsigned int flags) EV_THROW
|
1680
2534
|
{
|
1681
2535
|
if (!backend)
|
1682
2536
|
{
|
@@ -1713,27 +2567,31 @@ loop_init (EV_P_ unsigned int flags)
|
|
1713
2567
|
&& getenv ("LIBEV_FLAGS"))
|
1714
2568
|
flags = atoi (getenv ("LIBEV_FLAGS"));
|
1715
2569
|
|
1716
|
-
ev_rt_now
|
1717
|
-
mn_now
|
1718
|
-
now_floor
|
1719
|
-
rtmn_diff
|
2570
|
+
ev_rt_now = ev_time ();
|
2571
|
+
mn_now = get_clock ();
|
2572
|
+
now_floor = mn_now;
|
2573
|
+
rtmn_diff = ev_rt_now - mn_now;
|
1720
2574
|
#if EV_FEATURE_API
|
1721
|
-
invoke_cb
|
2575
|
+
invoke_cb = ev_invoke_pending;
|
1722
2576
|
#endif
|
1723
2577
|
|
1724
|
-
io_blocktime
|
1725
|
-
timeout_blocktime
|
1726
|
-
backend
|
1727
|
-
backend_fd
|
1728
|
-
sig_pending
|
2578
|
+
io_blocktime = 0.;
|
2579
|
+
timeout_blocktime = 0.;
|
2580
|
+
backend = 0;
|
2581
|
+
backend_fd = -1;
|
2582
|
+
sig_pending = 0;
|
1729
2583
|
#if EV_ASYNC_ENABLE
|
1730
|
-
async_pending
|
2584
|
+
async_pending = 0;
|
1731
2585
|
#endif
|
2586
|
+
pipe_write_skipped = 0;
|
2587
|
+
pipe_write_wanted = 0;
|
2588
|
+
evpipe [0] = -1;
|
2589
|
+
evpipe [1] = -1;
|
1732
2590
|
#if EV_USE_INOTIFY
|
1733
|
-
fs_fd
|
2591
|
+
fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
|
1734
2592
|
#endif
|
1735
2593
|
#if EV_USE_SIGNALFD
|
1736
|
-
sigfd
|
2594
|
+
sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1;
|
1737
2595
|
#endif
|
1738
2596
|
|
1739
2597
|
if (!(flags & EVBACKEND_MASK))
|
@@ -1768,7 +2626,7 @@ loop_init (EV_P_ unsigned int flags)
|
|
1768
2626
|
}
|
1769
2627
|
|
1770
2628
|
/* free up a loop structure */
|
1771
|
-
void
|
2629
|
+
void ecb_cold
|
1772
2630
|
ev_loop_destroy (EV_P)
|
1773
2631
|
{
|
1774
2632
|
int i;
|
@@ -1789,7 +2647,7 @@ ev_loop_destroy (EV_P)
|
|
1789
2647
|
#endif
|
1790
2648
|
|
1791
2649
|
#if EV_CHILD_ENABLE
|
1792
|
-
if (ev_is_active (&childev))
|
2650
|
+
if (ev_is_default_loop (EV_A) && ev_is_active (&childev))
|
1793
2651
|
{
|
1794
2652
|
ev_ref (EV_A); /* child watcher */
|
1795
2653
|
ev_signal_stop (EV_A_ &childev);
|
@@ -1801,16 +2659,8 @@ ev_loop_destroy (EV_P)
|
|
1801
2659
|
/*ev_ref (EV_A);*/
|
1802
2660
|
/*ev_io_stop (EV_A_ &pipe_w);*/
|
1803
2661
|
|
1804
|
-
|
1805
|
-
if (
|
1806
|
-
close (evfd);
|
1807
|
-
#endif
|
1808
|
-
|
1809
|
-
if (evpipe [0] >= 0)
|
1810
|
-
{
|
1811
|
-
EV_WIN32_CLOSE_FD (evpipe [0]);
|
1812
|
-
EV_WIN32_CLOSE_FD (evpipe [1]);
|
1813
|
-
}
|
2662
|
+
if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]);
|
2663
|
+
if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]);
|
1814
2664
|
}
|
1815
2665
|
|
1816
2666
|
#if EV_USE_SIGNALFD
|
@@ -1906,43 +2756,30 @@ loop_fork (EV_P)
|
|
1906
2756
|
infy_fork (EV_A);
|
1907
2757
|
#endif
|
1908
2758
|
|
2759
|
+
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
|
1909
2760
|
if (ev_is_active (&pipe_w))
|
1910
2761
|
{
|
1911
|
-
/*
|
1912
|
-
/* while we modify the fd vars */
|
1913
|
-
sig_pending = 1;
|
1914
|
-
#if EV_ASYNC_ENABLE
|
1915
|
-
async_pending = 1;
|
1916
|
-
#endif
|
2762
|
+
/* pipe_write_wanted must be false now, so modifying fd vars should be safe */
|
1917
2763
|
|
1918
2764
|
ev_ref (EV_A);
|
1919
2765
|
ev_io_stop (EV_A_ &pipe_w);
|
1920
2766
|
|
1921
|
-
#if EV_USE_EVENTFD
|
1922
|
-
if (evfd >= 0)
|
1923
|
-
close (evfd);
|
1924
|
-
#endif
|
1925
|
-
|
1926
2767
|
if (evpipe [0] >= 0)
|
1927
|
-
|
1928
|
-
EV_WIN32_CLOSE_FD (evpipe [0]);
|
1929
|
-
EV_WIN32_CLOSE_FD (evpipe [1]);
|
1930
|
-
}
|
2768
|
+
EV_WIN32_CLOSE_FD (evpipe [0]);
|
1931
2769
|
|
1932
|
-
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
|
1933
2770
|
evpipe_init (EV_A);
|
1934
|
-
/*
|
1935
|
-
|
1936
|
-
#endif
|
2771
|
+
/* iterate over everything, in case we missed something before */
|
2772
|
+
ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
|
1937
2773
|
}
|
2774
|
+
#endif
|
1938
2775
|
|
1939
2776
|
postfork = 0;
|
1940
2777
|
}
|
1941
2778
|
|
1942
2779
|
#if EV_MULTIPLICITY
|
1943
2780
|
|
1944
|
-
struct ev_loop *
|
1945
|
-
ev_loop_new (unsigned int flags)
|
2781
|
+
struct ev_loop * ecb_cold
|
2782
|
+
ev_loop_new (unsigned int flags) EV_THROW
|
1946
2783
|
{
|
1947
2784
|
EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
|
1948
2785
|
|
@@ -1959,7 +2796,7 @@ ev_loop_new (unsigned int flags)
|
|
1959
2796
|
#endif /* multiplicity */
|
1960
2797
|
|
1961
2798
|
#if EV_VERIFY
|
1962
|
-
static void noinline
|
2799
|
+
static void noinline ecb_cold
|
1963
2800
|
verify_watcher (EV_P_ W w)
|
1964
2801
|
{
|
1965
2802
|
assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
|
@@ -1968,7 +2805,7 @@ verify_watcher (EV_P_ W w)
|
|
1968
2805
|
assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
|
1969
2806
|
}
|
1970
2807
|
|
1971
|
-
static void noinline
|
2808
|
+
static void noinline ecb_cold
|
1972
2809
|
verify_heap (EV_P_ ANHE *heap, int N)
|
1973
2810
|
{
|
1974
2811
|
int i;
|
@@ -1983,7 +2820,7 @@ verify_heap (EV_P_ ANHE *heap, int N)
|
|
1983
2820
|
}
|
1984
2821
|
}
|
1985
2822
|
|
1986
|
-
static void noinline
|
2823
|
+
static void noinline ecb_cold
|
1987
2824
|
array_verify (EV_P_ W *ws, int cnt)
|
1988
2825
|
{
|
1989
2826
|
while (cnt--)
|
@@ -1995,12 +2832,12 @@ array_verify (EV_P_ W *ws, int cnt)
|
|
1995
2832
|
#endif
|
1996
2833
|
|
1997
2834
|
#if EV_FEATURE_API
|
1998
|
-
void
|
1999
|
-
ev_verify (EV_P)
|
2835
|
+
void ecb_cold
|
2836
|
+
ev_verify (EV_P) EV_THROW
|
2000
2837
|
{
|
2001
2838
|
#if EV_VERIFY
|
2002
2839
|
int i;
|
2003
|
-
WL w;
|
2840
|
+
WL w, w2;
|
2004
2841
|
|
2005
2842
|
assert (activecnt >= -1);
|
2006
2843
|
|
@@ -2010,12 +2847,23 @@ ev_verify (EV_P)
|
|
2010
2847
|
|
2011
2848
|
assert (anfdmax >= 0);
|
2012
2849
|
for (i = 0; i < anfdmax; ++i)
|
2013
|
-
|
2014
|
-
|
2015
|
-
|
2016
|
-
|
2017
|
-
|
2018
|
-
|
2850
|
+
{
|
2851
|
+
int j = 0;
|
2852
|
+
|
2853
|
+
for (w = w2 = anfds [i].head; w; w = w->next)
|
2854
|
+
{
|
2855
|
+
verify_watcher (EV_A_ (W)w);
|
2856
|
+
|
2857
|
+
if (j++ & 1)
|
2858
|
+
{
|
2859
|
+
assert (("libev: io watcher list contains a loop", w != w2));
|
2860
|
+
w2 = w2->next;
|
2861
|
+
}
|
2862
|
+
|
2863
|
+
assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
|
2864
|
+
assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
|
2865
|
+
}
|
2866
|
+
}
|
2019
2867
|
|
2020
2868
|
assert (timermax >= timercnt);
|
2021
2869
|
verify_heap (EV_A_ timers, timercnt);
|
@@ -2071,11 +2919,11 @@ ev_verify (EV_P)
|
|
2071
2919
|
#endif
|
2072
2920
|
|
2073
2921
|
#if EV_MULTIPLICITY
|
2074
|
-
struct ev_loop *
|
2922
|
+
struct ev_loop * ecb_cold
|
2075
2923
|
#else
|
2076
2924
|
int
|
2077
2925
|
#endif
|
2078
|
-
ev_default_loop (unsigned int flags)
|
2926
|
+
ev_default_loop (unsigned int flags) EV_THROW
|
2079
2927
|
{
|
2080
2928
|
if (!ev_default_loop_ptr)
|
2081
2929
|
{
|
@@ -2104,9 +2952,9 @@ ev_default_loop (unsigned int flags)
|
|
2104
2952
|
}
|
2105
2953
|
|
2106
2954
|
void
|
2107
|
-
ev_loop_fork (EV_P)
|
2955
|
+
ev_loop_fork (EV_P) EV_THROW
|
2108
2956
|
{
|
2109
|
-
postfork = 1;
|
2957
|
+
postfork = 1;
|
2110
2958
|
}
|
2111
2959
|
|
2112
2960
|
/*****************************************************************************/
|
@@ -2118,7 +2966,7 @@ ev_invoke (EV_P_ void *w, int revents)
|
|
2118
2966
|
}
|
2119
2967
|
|
2120
2968
|
unsigned int
|
2121
|
-
ev_pending_count (EV_P)
|
2969
|
+
ev_pending_count (EV_P) EV_THROW
|
2122
2970
|
{
|
2123
2971
|
int pri;
|
2124
2972
|
unsigned int count = 0;
|
@@ -2132,17 +2980,21 @@ ev_pending_count (EV_P)
|
|
2132
2980
|
void noinline
|
2133
2981
|
ev_invoke_pending (EV_P)
|
2134
2982
|
{
|
2135
|
-
|
2983
|
+
pendingpri = NUMPRI;
|
2136
2984
|
|
2137
|
-
|
2138
|
-
|
2139
|
-
|
2140
|
-
ANPENDING *p = pendings [pri] + --pendingcnt [pri];
|
2985
|
+
while (pendingpri) /* pendingpri possibly gets modified in the inner loop */
|
2986
|
+
{
|
2987
|
+
--pendingpri;
|
2141
2988
|
|
2142
|
-
|
2143
|
-
|
2144
|
-
|
2145
|
-
|
2989
|
+
while (pendingcnt [pendingpri])
|
2990
|
+
{
|
2991
|
+
ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri];
|
2992
|
+
|
2993
|
+
p->w->pending = 0;
|
2994
|
+
EV_CB_INVOKE (p->w, p->events);
|
2995
|
+
EV_FREQUENT_CHECK;
|
2996
|
+
}
|
2997
|
+
}
|
2146
2998
|
}
|
2147
2999
|
|
2148
3000
|
#if EV_IDLE_ENABLE
|
@@ -2210,12 +3062,28 @@ timers_reify (EV_P)
|
|
2210
3062
|
|
2211
3063
|
#if EV_PERIODIC_ENABLE
|
2212
3064
|
|
2213
|
-
|
3065
|
+
static void noinline
|
2214
3066
|
periodic_recalc (EV_P_ ev_periodic *w)
|
2215
3067
|
{
|
2216
|
-
|
2217
|
-
|
2218
|
-
|
3068
|
+
ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL;
|
3069
|
+
ev_tstamp at = w->offset + interval * ev_floor ((ev_rt_now - w->offset) / interval);
|
3070
|
+
|
3071
|
+
/* the above almost always errs on the low side */
|
3072
|
+
while (at <= ev_rt_now)
|
3073
|
+
{
|
3074
|
+
ev_tstamp nat = at + w->interval;
|
3075
|
+
|
3076
|
+
/* when resolution fails us, we use ev_rt_now */
|
3077
|
+
if (expect_false (nat == at))
|
3078
|
+
{
|
3079
|
+
at = ev_rt_now;
|
3080
|
+
break;
|
3081
|
+
}
|
3082
|
+
|
3083
|
+
at = nat;
|
3084
|
+
}
|
3085
|
+
|
3086
|
+
ev_at (w) = at;
|
2219
3087
|
}
|
2220
3088
|
|
2221
3089
|
/* make periodics pending */
|
@@ -2226,8 +3094,6 @@ periodics_reify (EV_P)
|
|
2226
3094
|
|
2227
3095
|
while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
|
2228
3096
|
{
|
2229
|
-
int feed_count = 0;
|
2230
|
-
|
2231
3097
|
do
|
2232
3098
|
{
|
2233
3099
|
ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
|
@@ -2247,20 +3113,6 @@ periodics_reify (EV_P)
|
|
2247
3113
|
else if (w->interval)
|
2248
3114
|
{
|
2249
3115
|
periodic_recalc (EV_A_ w);
|
2250
|
-
|
2251
|
-
/* if next trigger time is not sufficiently in the future, put it there */
|
2252
|
-
/* this might happen because of floating point inexactness */
|
2253
|
-
if (ev_at (w) - ev_rt_now < TIME_EPSILON)
|
2254
|
-
{
|
2255
|
-
ev_at (w) += w->interval;
|
2256
|
-
|
2257
|
-
/* if interval is unreasonably low we might still have a time in the past */
|
2258
|
-
/* so correct this. this will make the periodic very inexact, but the user */
|
2259
|
-
/* has effectively asked to get triggered more often than possible */
|
2260
|
-
if (ev_at (w) < ev_rt_now)
|
2261
|
-
ev_at (w) = ev_rt_now;
|
2262
|
-
}
|
2263
|
-
|
2264
3116
|
ANHE_at_cache (periodics [HEAP0]);
|
2265
3117
|
downheap (periodics, periodiccnt, HEAP0);
|
2266
3118
|
}
|
@@ -2278,7 +3130,7 @@ periodics_reify (EV_P)
|
|
2278
3130
|
|
2279
3131
|
/* simply recalculate all periodics */
|
2280
3132
|
/* TODO: maybe ensure that at least one event happens when jumping forward? */
|
2281
|
-
static void noinline
|
3133
|
+
static void noinline ecb_cold
|
2282
3134
|
periodics_reschedule (EV_P)
|
2283
3135
|
{
|
2284
3136
|
int i;
|
@@ -2301,7 +3153,7 @@ periodics_reschedule (EV_P)
|
|
2301
3153
|
#endif
|
2302
3154
|
|
2303
3155
|
/* adjust all timers by a given offset */
|
2304
|
-
static void noinline
|
3156
|
+
static void noinline ecb_cold
|
2305
3157
|
timers_reschedule (EV_P_ ev_tstamp adjust)
|
2306
3158
|
{
|
2307
3159
|
int i;
|
@@ -2348,9 +3200,12 @@ time_update (EV_P_ ev_tstamp max_block)
|
|
2348
3200
|
*/
|
2349
3201
|
for (i = 4; --i; )
|
2350
3202
|
{
|
3203
|
+
ev_tstamp diff;
|
2351
3204
|
rtmn_diff = ev_rt_now - mn_now;
|
2352
3205
|
|
2353
|
-
|
3206
|
+
diff = odiff - rtmn_diff;
|
3207
|
+
|
3208
|
+
if (expect_true ((diff < 0. ? -diff : diff) < MIN_TIMEJUMP))
|
2354
3209
|
return; /* all is well */
|
2355
3210
|
|
2356
3211
|
ev_rt_now = ev_time ();
|
@@ -2382,7 +3237,7 @@ time_update (EV_P_ ev_tstamp max_block)
|
|
2382
3237
|
}
|
2383
3238
|
}
|
2384
3239
|
|
2385
|
-
|
3240
|
+
int
|
2386
3241
|
ev_run (EV_P_ int flags)
|
2387
3242
|
{
|
2388
3243
|
#if EV_FEATURE_API
|
@@ -2450,20 +3305,25 @@ ev_run (EV_P_ int flags)
|
|
2450
3305
|
/* update time to cancel out callback processing overhead */
|
2451
3306
|
time_update (EV_A_ 1e100);
|
2452
3307
|
|
2453
|
-
|
3308
|
+
/* from now on, we want a pipe-wake-up */
|
3309
|
+
pipe_write_wanted = 1;
|
3310
|
+
|
3311
|
+
ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */
|
3312
|
+
|
3313
|
+
if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))
|
2454
3314
|
{
|
2455
3315
|
waittime = MAX_BLOCKTIME;
|
2456
3316
|
|
2457
3317
|
if (timercnt)
|
2458
3318
|
{
|
2459
|
-
ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now
|
3319
|
+
ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now;
|
2460
3320
|
if (waittime > to) waittime = to;
|
2461
3321
|
}
|
2462
3322
|
|
2463
3323
|
#if EV_PERIODIC_ENABLE
|
2464
3324
|
if (periodiccnt)
|
2465
3325
|
{
|
2466
|
-
ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now
|
3326
|
+
ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now;
|
2467
3327
|
if (waittime > to) waittime = to;
|
2468
3328
|
}
|
2469
3329
|
#endif
|
@@ -2472,13 +3332,18 @@ ev_run (EV_P_ int flags)
|
|
2472
3332
|
if (expect_false (waittime < timeout_blocktime))
|
2473
3333
|
waittime = timeout_blocktime;
|
2474
3334
|
|
3335
|
+
/* at this point, we NEED to wait, so we have to ensure */
|
3336
|
+
/* to pass a minimum nonzero value to the backend */
|
3337
|
+
if (expect_false (waittime < backend_mintime))
|
3338
|
+
waittime = backend_mintime;
|
3339
|
+
|
2475
3340
|
/* extra check because io_blocktime is commonly 0 */
|
2476
3341
|
if (expect_false (io_blocktime))
|
2477
3342
|
{
|
2478
3343
|
sleeptime = io_blocktime - (mn_now - prev_mn_now);
|
2479
3344
|
|
2480
|
-
if (sleeptime > waittime -
|
2481
|
-
sleeptime = waittime -
|
3345
|
+
if (sleeptime > waittime - backend_mintime)
|
3346
|
+
sleeptime = waittime - backend_mintime;
|
2482
3347
|
|
2483
3348
|
if (expect_true (sleeptime > 0.))
|
2484
3349
|
{
|
@@ -2495,6 +3360,16 @@ ev_run (EV_P_ int flags)
|
|
2495
3360
|
backend_poll (EV_A_ waittime);
|
2496
3361
|
assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
|
2497
3362
|
|
3363
|
+
pipe_write_wanted = 0; /* just an optimisation, no fence needed */
|
3364
|
+
|
3365
|
+
ECB_MEMORY_FENCE_ACQUIRE;
|
3366
|
+
if (pipe_write_skipped)
|
3367
|
+
{
|
3368
|
+
assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));
|
3369
|
+
ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
|
3370
|
+
}
|
3371
|
+
|
3372
|
+
|
2498
3373
|
/* update ev_rt_now, do magic */
|
2499
3374
|
time_update (EV_A_ waittime + sleeptime);
|
2500
3375
|
}
|
@@ -2530,40 +3405,42 @@ ev_run (EV_P_ int flags)
|
|
2530
3405
|
#if EV_FEATURE_API
|
2531
3406
|
--loop_depth;
|
2532
3407
|
#endif
|
3408
|
+
|
3409
|
+
return activecnt;
|
2533
3410
|
}
|
2534
3411
|
|
2535
3412
|
void
|
2536
|
-
ev_break (EV_P_ int how)
|
3413
|
+
ev_break (EV_P_ int how) EV_THROW
|
2537
3414
|
{
|
2538
3415
|
loop_done = how;
|
2539
3416
|
}
|
2540
3417
|
|
2541
3418
|
void
|
2542
|
-
ev_ref (EV_P)
|
3419
|
+
ev_ref (EV_P) EV_THROW
|
2543
3420
|
{
|
2544
3421
|
++activecnt;
|
2545
3422
|
}
|
2546
3423
|
|
2547
3424
|
void
|
2548
|
-
ev_unref (EV_P)
|
3425
|
+
ev_unref (EV_P) EV_THROW
|
2549
3426
|
{
|
2550
3427
|
--activecnt;
|
2551
3428
|
}
|
2552
3429
|
|
2553
3430
|
void
|
2554
|
-
ev_now_update (EV_P)
|
3431
|
+
ev_now_update (EV_P) EV_THROW
|
2555
3432
|
{
|
2556
3433
|
time_update (EV_A_ 1e100);
|
2557
3434
|
}
|
2558
3435
|
|
2559
3436
|
void
|
2560
|
-
ev_suspend (EV_P)
|
3437
|
+
ev_suspend (EV_P) EV_THROW
|
2561
3438
|
{
|
2562
3439
|
ev_now_update (EV_A);
|
2563
3440
|
}
|
2564
3441
|
|
2565
3442
|
void
|
2566
|
-
ev_resume (EV_P)
|
3443
|
+
ev_resume (EV_P) EV_THROW
|
2567
3444
|
{
|
2568
3445
|
ev_tstamp mn_prev = mn_now;
|
2569
3446
|
|
@@ -2612,7 +3489,7 @@ clear_pending (EV_P_ W w)
|
|
2612
3489
|
}
|
2613
3490
|
|
2614
3491
|
int
|
2615
|
-
ev_clear_pending (EV_P_ void *w)
|
3492
|
+
ev_clear_pending (EV_P_ void *w) EV_THROW
|
2616
3493
|
{
|
2617
3494
|
W w_ = (W)w;
|
2618
3495
|
int pending = w_->pending;
|
@@ -2655,7 +3532,7 @@ ev_stop (EV_P_ W w)
|
|
2655
3532
|
/*****************************************************************************/
|
2656
3533
|
|
2657
3534
|
void noinline
|
2658
|
-
ev_io_start (EV_P_ ev_io *w)
|
3535
|
+
ev_io_start (EV_P_ ev_io *w) EV_THROW
|
2659
3536
|
{
|
2660
3537
|
int fd = w->fd;
|
2661
3538
|
|
@@ -2671,6 +3548,9 @@ ev_io_start (EV_P_ ev_io *w)
|
|
2671
3548
|
array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
|
2672
3549
|
wlist_add (&anfds[fd].head, (WL)w);
|
2673
3550
|
|
3551
|
+
/* common bug, apparently */
|
3552
|
+
assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w));
|
3553
|
+
|
2674
3554
|
fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY);
|
2675
3555
|
w->events &= ~EV__IOFDSET;
|
2676
3556
|
|
@@ -2678,7 +3558,7 @@ ev_io_start (EV_P_ ev_io *w)
|
|
2678
3558
|
}
|
2679
3559
|
|
2680
3560
|
void noinline
|
2681
|
-
ev_io_stop (EV_P_ ev_io *w)
|
3561
|
+
ev_io_stop (EV_P_ ev_io *w) EV_THROW
|
2682
3562
|
{
|
2683
3563
|
clear_pending (EV_A_ (W)w);
|
2684
3564
|
if (expect_false (!ev_is_active (w)))
|
@@ -2697,7 +3577,7 @@ ev_io_stop (EV_P_ ev_io *w)
|
|
2697
3577
|
}
|
2698
3578
|
|
2699
3579
|
void noinline
|
2700
|
-
ev_timer_start (EV_P_ ev_timer *w)
|
3580
|
+
ev_timer_start (EV_P_ ev_timer *w) EV_THROW
|
2701
3581
|
{
|
2702
3582
|
if (expect_false (ev_is_active (w)))
|
2703
3583
|
return;
|
@@ -2721,7 +3601,7 @@ ev_timer_start (EV_P_ ev_timer *w)
|
|
2721
3601
|
}
|
2722
3602
|
|
2723
3603
|
void noinline
|
2724
|
-
ev_timer_stop (EV_P_ ev_timer *w)
|
3604
|
+
ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
|
2725
3605
|
{
|
2726
3606
|
clear_pending (EV_A_ (W)w);
|
2727
3607
|
if (expect_false (!ev_is_active (w)))
|
@@ -2751,10 +3631,12 @@ ev_timer_stop (EV_P_ ev_timer *w)
|
|
2751
3631
|
}
|
2752
3632
|
|
2753
3633
|
void noinline
|
2754
|
-
ev_timer_again (EV_P_ ev_timer *w)
|
3634
|
+
ev_timer_again (EV_P_ ev_timer *w) EV_THROW
|
2755
3635
|
{
|
2756
3636
|
EV_FREQUENT_CHECK;
|
2757
3637
|
|
3638
|
+
clear_pending (EV_A_ (W)w);
|
3639
|
+
|
2758
3640
|
if (ev_is_active (w))
|
2759
3641
|
{
|
2760
3642
|
if (w->repeat)
|
@@ -2776,14 +3658,14 @@ ev_timer_again (EV_P_ ev_timer *w)
|
|
2776
3658
|
}
|
2777
3659
|
|
2778
3660
|
ev_tstamp
|
2779
|
-
ev_timer_remaining (EV_P_ ev_timer *w)
|
3661
|
+
ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW
|
2780
3662
|
{
|
2781
3663
|
return ev_at (w) - (ev_is_active (w) ? mn_now : 0.);
|
2782
3664
|
}
|
2783
3665
|
|
2784
3666
|
#if EV_PERIODIC_ENABLE
|
2785
3667
|
void noinline
|
2786
|
-
ev_periodic_start (EV_P_ ev_periodic *w)
|
3668
|
+
ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
|
2787
3669
|
{
|
2788
3670
|
if (expect_false (ev_is_active (w)))
|
2789
3671
|
return;
|
@@ -2813,7 +3695,7 @@ ev_periodic_start (EV_P_ ev_periodic *w)
|
|
2813
3695
|
}
|
2814
3696
|
|
2815
3697
|
void noinline
|
2816
|
-
ev_periodic_stop (EV_P_ ev_periodic *w)
|
3698
|
+
ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
|
2817
3699
|
{
|
2818
3700
|
clear_pending (EV_A_ (W)w);
|
2819
3701
|
if (expect_false (!ev_is_active (w)))
|
@@ -2841,7 +3723,7 @@ ev_periodic_stop (EV_P_ ev_periodic *w)
|
|
2841
3723
|
}
|
2842
3724
|
|
2843
3725
|
void noinline
|
2844
|
-
ev_periodic_again (EV_P_ ev_periodic *w)
|
3726
|
+
ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
|
2845
3727
|
{
|
2846
3728
|
/* TODO: use adjustheap and recalculation */
|
2847
3729
|
ev_periodic_stop (EV_A_ w);
|
@@ -2856,7 +3738,7 @@ ev_periodic_again (EV_P_ ev_periodic *w)
|
|
2856
3738
|
#if EV_SIGNAL_ENABLE
|
2857
3739
|
|
2858
3740
|
void noinline
|
2859
|
-
ev_signal_start (EV_P_ ev_signal *w)
|
3741
|
+
ev_signal_start (EV_P_ ev_signal *w) EV_THROW
|
2860
3742
|
{
|
2861
3743
|
if (expect_false (ev_is_active (w)))
|
2862
3744
|
return;
|
@@ -2868,6 +3750,7 @@ ev_signal_start (EV_P_ ev_signal *w)
|
|
2868
3750
|
!signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop));
|
2869
3751
|
|
2870
3752
|
signals [w->signum - 1].loop = EV_A;
|
3753
|
+
ECB_MEMORY_FENCE_RELEASE;
|
2871
3754
|
#endif
|
2872
3755
|
|
2873
3756
|
EV_FREQUENT_CHECK;
|
@@ -2937,7 +3820,7 @@ ev_signal_start (EV_P_ ev_signal *w)
|
|
2937
3820
|
}
|
2938
3821
|
|
2939
3822
|
void noinline
|
2940
|
-
ev_signal_stop (EV_P_ ev_signal *w)
|
3823
|
+
ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
|
2941
3824
|
{
|
2942
3825
|
clear_pending (EV_A_ (W)w);
|
2943
3826
|
if (expect_false (!ev_is_active (w)))
|
@@ -2978,7 +3861,7 @@ ev_signal_stop (EV_P_ ev_signal *w)
|
|
2978
3861
|
#if EV_CHILD_ENABLE
|
2979
3862
|
|
2980
3863
|
void
|
2981
|
-
ev_child_start (EV_P_ ev_child *w)
|
3864
|
+
ev_child_start (EV_P_ ev_child *w) EV_THROW
|
2982
3865
|
{
|
2983
3866
|
#if EV_MULTIPLICITY
|
2984
3867
|
assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
|
@@ -2995,7 +3878,7 @@ ev_child_start (EV_P_ ev_child *w)
|
|
2995
3878
|
}
|
2996
3879
|
|
2997
3880
|
void
|
2998
|
-
ev_child_stop (EV_P_ ev_child *w)
|
3881
|
+
ev_child_stop (EV_P_ ev_child *w) EV_THROW
|
2999
3882
|
{
|
3000
3883
|
clear_pending (EV_A_ (W)w);
|
3001
3884
|
if (expect_false (!ev_is_active (w)))
|
@@ -3032,7 +3915,10 @@ static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
|
|
3032
3915
|
static void noinline
|
3033
3916
|
infy_add (EV_P_ ev_stat *w)
|
3034
3917
|
{
|
3035
|
-
w->wd = inotify_add_watch (fs_fd, w->path,
|
3918
|
+
w->wd = inotify_add_watch (fs_fd, w->path,
|
3919
|
+
IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY
|
3920
|
+
| IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
|
3921
|
+
| IN_DONT_FOLLOW | IN_MASK_ADD);
|
3036
3922
|
|
3037
3923
|
if (w->wd >= 0)
|
3038
3924
|
{
|
@@ -3046,10 +3932,16 @@ infy_add (EV_P_ ev_stat *w)
|
|
3046
3932
|
w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
|
3047
3933
|
else if (!statfs (w->path, &sfs)
|
3048
3934
|
&& (sfs.f_type == 0x1373 /* devfs */
|
3935
|
+
|| sfs.f_type == 0x4006 /* fat */
|
3936
|
+
|| sfs.f_type == 0x4d44 /* msdos */
|
3049
3937
|
|| sfs.f_type == 0xEF53 /* ext2/3 */
|
3938
|
+
|| sfs.f_type == 0x72b6 /* jffs2 */
|
3939
|
+
|| sfs.f_type == 0x858458f6 /* ramfs */
|
3940
|
+
|| sfs.f_type == 0x5346544e /* ntfs */
|
3050
3941
|
|| sfs.f_type == 0x3153464a /* jfs */
|
3942
|
+
|| sfs.f_type == 0x9123683e /* btrfs */
|
3051
3943
|
|| sfs.f_type == 0x52654973 /* reiser3 */
|
3052
|
-
|| sfs.f_type == 0x01021994 /*
|
3944
|
+
|| sfs.f_type == 0x01021994 /* tmpfs */
|
3053
3945
|
|| sfs.f_type == 0x58465342 /* xfs */))
|
3054
3946
|
w->timer.repeat = 0.; /* filesystem is local, kernel new enough */
|
3055
3947
|
else
|
@@ -3157,7 +4049,7 @@ infy_cb (EV_P_ ev_io *w, int revents)
|
|
3157
4049
|
}
|
3158
4050
|
}
|
3159
4051
|
|
3160
|
-
inline_size void
|
4052
|
+
inline_size void ecb_cold
|
3161
4053
|
ev_check_2625 (EV_P)
|
3162
4054
|
{
|
3163
4055
|
/* kernels < 2.6.25 are borked
|
@@ -3172,7 +4064,7 @@ ev_check_2625 (EV_P)
|
|
3172
4064
|
inline_size int
|
3173
4065
|
infy_newfd (void)
|
3174
4066
|
{
|
3175
|
-
#if defined
|
4067
|
+
#if defined IN_CLOEXEC && defined IN_NONBLOCK
|
3176
4068
|
int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK);
|
3177
4069
|
if (fd >= 0)
|
3178
4070
|
return fd;
|
@@ -3257,7 +4149,7 @@ infy_fork (EV_P)
|
|
3257
4149
|
#endif
|
3258
4150
|
|
3259
4151
|
void
|
3260
|
-
ev_stat_stat (EV_P_ ev_stat *w)
|
4152
|
+
ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
|
3261
4153
|
{
|
3262
4154
|
if (lstat (w->path, &w->attr) < 0)
|
3263
4155
|
w->attr.st_nlink = 0;
|
@@ -3306,7 +4198,7 @@ stat_timer_cb (EV_P_ ev_timer *w_, int revents)
|
|
3306
4198
|
}
|
3307
4199
|
|
3308
4200
|
void
|
3309
|
-
ev_stat_start (EV_P_ ev_stat *w)
|
4201
|
+
ev_stat_start (EV_P_ ev_stat *w) EV_THROW
|
3310
4202
|
{
|
3311
4203
|
if (expect_false (ev_is_active (w)))
|
3312
4204
|
return;
|
@@ -3337,7 +4229,7 @@ ev_stat_start (EV_P_ ev_stat *w)
|
|
3337
4229
|
}
|
3338
4230
|
|
3339
4231
|
void
|
3340
|
-
ev_stat_stop (EV_P_ ev_stat *w)
|
4232
|
+
ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
|
3341
4233
|
{
|
3342
4234
|
clear_pending (EV_A_ (W)w);
|
3343
4235
|
if (expect_false (!ev_is_active (w)))
|
@@ -3363,7 +4255,7 @@ ev_stat_stop (EV_P_ ev_stat *w)
|
|
3363
4255
|
|
3364
4256
|
#if EV_IDLE_ENABLE
|
3365
4257
|
void
|
3366
|
-
ev_idle_start (EV_P_ ev_idle *w)
|
4258
|
+
ev_idle_start (EV_P_ ev_idle *w) EV_THROW
|
3367
4259
|
{
|
3368
4260
|
if (expect_false (ev_is_active (w)))
|
3369
4261
|
return;
|
@@ -3386,7 +4278,7 @@ ev_idle_start (EV_P_ ev_idle *w)
|
|
3386
4278
|
}
|
3387
4279
|
|
3388
4280
|
void
|
3389
|
-
ev_idle_stop (EV_P_ ev_idle *w)
|
4281
|
+
ev_idle_stop (EV_P_ ev_idle *w) EV_THROW
|
3390
4282
|
{
|
3391
4283
|
clear_pending (EV_A_ (W)w);
|
3392
4284
|
if (expect_false (!ev_is_active (w)))
|
@@ -3410,7 +4302,7 @@ ev_idle_stop (EV_P_ ev_idle *w)
|
|
3410
4302
|
|
3411
4303
|
#if EV_PREPARE_ENABLE
|
3412
4304
|
void
|
3413
|
-
ev_prepare_start (EV_P_ ev_prepare *w)
|
4305
|
+
ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW
|
3414
4306
|
{
|
3415
4307
|
if (expect_false (ev_is_active (w)))
|
3416
4308
|
return;
|
@@ -3425,7 +4317,7 @@ ev_prepare_start (EV_P_ ev_prepare *w)
|
|
3425
4317
|
}
|
3426
4318
|
|
3427
4319
|
void
|
3428
|
-
ev_prepare_stop (EV_P_ ev_prepare *w)
|
4320
|
+
ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW
|
3429
4321
|
{
|
3430
4322
|
clear_pending (EV_A_ (W)w);
|
3431
4323
|
if (expect_false (!ev_is_active (w)))
|
@@ -3448,7 +4340,7 @@ ev_prepare_stop (EV_P_ ev_prepare *w)
|
|
3448
4340
|
|
3449
4341
|
#if EV_CHECK_ENABLE
|
3450
4342
|
void
|
3451
|
-
ev_check_start (EV_P_ ev_check *w)
|
4343
|
+
ev_check_start (EV_P_ ev_check *w) EV_THROW
|
3452
4344
|
{
|
3453
4345
|
if (expect_false (ev_is_active (w)))
|
3454
4346
|
return;
|
@@ -3463,7 +4355,7 @@ ev_check_start (EV_P_ ev_check *w)
|
|
3463
4355
|
}
|
3464
4356
|
|
3465
4357
|
void
|
3466
|
-
ev_check_stop (EV_P_ ev_check *w)
|
4358
|
+
ev_check_stop (EV_P_ ev_check *w) EV_THROW
|
3467
4359
|
{
|
3468
4360
|
clear_pending (EV_A_ (W)w);
|
3469
4361
|
if (expect_false (!ev_is_active (w)))
|
@@ -3486,7 +4378,7 @@ ev_check_stop (EV_P_ ev_check *w)
|
|
3486
4378
|
|
3487
4379
|
#if EV_EMBED_ENABLE
|
3488
4380
|
void noinline
|
3489
|
-
ev_embed_sweep (EV_P_ ev_embed *w)
|
4381
|
+
ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW
|
3490
4382
|
{
|
3491
4383
|
ev_run (w->other, EVRUN_NOWAIT);
|
3492
4384
|
}
|
@@ -3544,7 +4436,7 @@ embed_idle_cb (EV_P_ ev_idle *idle, int revents)
|
|
3544
4436
|
#endif
|
3545
4437
|
|
3546
4438
|
void
|
3547
|
-
ev_embed_start (EV_P_ ev_embed *w)
|
4439
|
+
ev_embed_start (EV_P_ ev_embed *w) EV_THROW
|
3548
4440
|
{
|
3549
4441
|
if (expect_false (ev_is_active (w)))
|
3550
4442
|
return;
|
@@ -3575,7 +4467,7 @@ ev_embed_start (EV_P_ ev_embed *w)
|
|
3575
4467
|
}
|
3576
4468
|
|
3577
4469
|
void
|
3578
|
-
ev_embed_stop (EV_P_ ev_embed *w)
|
4470
|
+
ev_embed_stop (EV_P_ ev_embed *w) EV_THROW
|
3579
4471
|
{
|
3580
4472
|
clear_pending (EV_A_ (W)w);
|
3581
4473
|
if (expect_false (!ev_is_active (w)))
|
@@ -3595,7 +4487,7 @@ ev_embed_stop (EV_P_ ev_embed *w)
|
|
3595
4487
|
|
3596
4488
|
#if EV_FORK_ENABLE
|
3597
4489
|
void
|
3598
|
-
ev_fork_start (EV_P_ ev_fork *w)
|
4490
|
+
ev_fork_start (EV_P_ ev_fork *w) EV_THROW
|
3599
4491
|
{
|
3600
4492
|
if (expect_false (ev_is_active (w)))
|
3601
4493
|
return;
|
@@ -3610,7 +4502,7 @@ ev_fork_start (EV_P_ ev_fork *w)
|
|
3610
4502
|
}
|
3611
4503
|
|
3612
4504
|
void
|
3613
|
-
ev_fork_stop (EV_P_ ev_fork *w)
|
4505
|
+
ev_fork_stop (EV_P_ ev_fork *w) EV_THROW
|
3614
4506
|
{
|
3615
4507
|
clear_pending (EV_A_ (W)w);
|
3616
4508
|
if (expect_false (!ev_is_active (w)))
|
@@ -3633,7 +4525,7 @@ ev_fork_stop (EV_P_ ev_fork *w)
|
|
3633
4525
|
|
3634
4526
|
#if EV_CLEANUP_ENABLE
|
3635
4527
|
void
|
3636
|
-
ev_cleanup_start (EV_P_ ev_cleanup *w)
|
4528
|
+
ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
|
3637
4529
|
{
|
3638
4530
|
if (expect_false (ev_is_active (w)))
|
3639
4531
|
return;
|
@@ -3650,7 +4542,7 @@ ev_cleanup_start (EV_P_ ev_cleanup *w)
|
|
3650
4542
|
}
|
3651
4543
|
|
3652
4544
|
void
|
3653
|
-
ev_cleanup_stop (EV_P_ ev_cleanup *w)
|
4545
|
+
ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW
|
3654
4546
|
{
|
3655
4547
|
clear_pending (EV_A_ (W)w);
|
3656
4548
|
if (expect_false (!ev_is_active (w)))
|
@@ -3674,7 +4566,7 @@ ev_cleanup_stop (EV_P_ ev_cleanup *w)
|
|
3674
4566
|
|
3675
4567
|
#if EV_ASYNC_ENABLE
|
3676
4568
|
void
|
3677
|
-
ev_async_start (EV_P_ ev_async *w)
|
4569
|
+
ev_async_start (EV_P_ ev_async *w) EV_THROW
|
3678
4570
|
{
|
3679
4571
|
if (expect_false (ev_is_active (w)))
|
3680
4572
|
return;
|
@@ -3693,7 +4585,7 @@ ev_async_start (EV_P_ ev_async *w)
|
|
3693
4585
|
}
|
3694
4586
|
|
3695
4587
|
void
|
3696
|
-
ev_async_stop (EV_P_ ev_async *w)
|
4588
|
+
ev_async_stop (EV_P_ ev_async *w) EV_THROW
|
3697
4589
|
{
|
3698
4590
|
clear_pending (EV_A_ (W)w);
|
3699
4591
|
if (expect_false (!ev_is_active (w)))
|
@@ -3714,7 +4606,7 @@ ev_async_stop (EV_P_ ev_async *w)
|
|
3714
4606
|
}
|
3715
4607
|
|
3716
4608
|
void
|
3717
|
-
ev_async_send (EV_P_ ev_async *w)
|
4609
|
+
ev_async_send (EV_P_ ev_async *w) EV_THROW
|
3718
4610
|
{
|
3719
4611
|
w->sent = 1;
|
3720
4612
|
evpipe_write (EV_A_ &async_pending);
|
@@ -3761,7 +4653,7 @@ once_cb_to (EV_P_ ev_timer *w, int revents)
|
|
3761
4653
|
}
|
3762
4654
|
|
3763
4655
|
void
|
3764
|
-
ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg)
|
4656
|
+
ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW
|
3765
4657
|
{
|
3766
4658
|
struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
|
3767
4659
|
|
@@ -3792,8 +4684,8 @@ ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, vo
|
|
3792
4684
|
/*****************************************************************************/
|
3793
4685
|
|
3794
4686
|
#if EV_WALK_ENABLE
|
3795
|
-
void
|
3796
|
-
ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
|
4687
|
+
void ecb_cold
|
4688
|
+
ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW
|
3797
4689
|
{
|
3798
4690
|
int i, j;
|
3799
4691
|
ev_watcher_list *wl, *wn;
|
@@ -3846,7 +4738,7 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
|
|
3846
4738
|
|
3847
4739
|
#if EV_IDLE_ENABLE
|
3848
4740
|
if (types & EV_IDLE)
|
3849
|
-
for (j = NUMPRI;
|
4741
|
+
for (j = NUMPRI; j--; )
|
3850
4742
|
for (i = idlecnt [j]; i--; )
|
3851
4743
|
cb (EV_A_ EV_IDLE, idles [j][i]);
|
3852
4744
|
#endif
|
@@ -3909,5 +4801,3 @@ ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w))
|
|
3909
4801
|
#include "ev_wrap.h"
|
3910
4802
|
#endif
|
3911
4803
|
|
3912
|
-
EV_CPP(})
|
3913
|
-
|