cool.io 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
|