Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/crypto/krb5/src/util/verto/ev.c
34907 views
1
/*
2
* libev event processing core, watcher management
3
*
4
* Copyright (c) 2007,2008,2009,2010,2011,2012,2013 Marc Alexander Lehmann <[email protected]>
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without modifica-
8
* tion, are permitted provided that the following conditions are met:
9
*
10
* 1. Redistributions of source code must retain the above copyright notice,
11
* this list of conditions and the following disclaimer.
12
*
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
*
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
18
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
19
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
20
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
21
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
25
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
26
* OF THE POSSIBILITY OF SUCH DAMAGE.
27
*
28
* Alternatively, the contents of this file may be used under the terms of
29
* the GNU General Public License ("GPL") version 2 or any later version,
30
* in which case the provisions of the GPL are applicable instead of
31
* the above. If you wish to allow the use of your version of this file
32
* only under the terms of the GPL and not to allow others to use your
33
* version of this file under the BSD license, indicate your decision
34
* by deleting the provisions above and replace them with the notice
35
* and other provisions required by the GPL. If you do not delete the
36
* provisions above, a recipient may use your version of this file under
37
* either the BSD or the GPL.
38
*/
39
40
/* this big block deduces configuration from config.h */
41
#ifndef EV_STANDALONE
42
# ifdef EV_CONFIG_H
43
# include EV_CONFIG_H
44
# else
45
# include "config.h"
46
# endif
47
48
# if HAVE_FLOOR
49
# ifndef EV_USE_FLOOR
50
# define EV_USE_FLOOR 1
51
# endif
52
# endif
53
54
# if HAVE_CLOCK_SYSCALL
55
# ifndef EV_USE_CLOCK_SYSCALL
56
# define EV_USE_CLOCK_SYSCALL 1
57
# ifndef EV_USE_REALTIME
58
# define EV_USE_REALTIME 0
59
# endif
60
# ifndef EV_USE_MONOTONIC
61
# define EV_USE_MONOTONIC 1
62
# endif
63
# endif
64
# elif !defined EV_USE_CLOCK_SYSCALL
65
# define EV_USE_CLOCK_SYSCALL 0
66
# endif
67
68
# if HAVE_CLOCK_GETTIME
69
# ifndef EV_USE_MONOTONIC
70
# define EV_USE_MONOTONIC 1
71
# endif
72
# ifndef EV_USE_REALTIME
73
# define EV_USE_REALTIME 0
74
# endif
75
# else
76
# ifndef EV_USE_MONOTONIC
77
# define EV_USE_MONOTONIC 0
78
# endif
79
# ifndef EV_USE_REALTIME
80
# define EV_USE_REALTIME 0
81
# endif
82
# endif
83
84
# if HAVE_NANOSLEEP
85
# ifndef EV_USE_NANOSLEEP
86
# define EV_USE_NANOSLEEP EV_FEATURE_OS
87
# endif
88
# else
89
# undef EV_USE_NANOSLEEP
90
# define EV_USE_NANOSLEEP 0
91
# endif
92
93
# if HAVE_SELECT && HAVE_SYS_SELECT_H
94
# ifndef EV_USE_SELECT
95
# define EV_USE_SELECT EV_FEATURE_BACKENDS
96
# endif
97
# else
98
# undef EV_USE_SELECT
99
# define EV_USE_SELECT 0
100
# endif
101
102
# if HAVE_POLL && HAVE_POLL_H
103
# ifndef EV_USE_POLL
104
# define EV_USE_POLL EV_FEATURE_BACKENDS
105
# endif
106
# else
107
# undef EV_USE_POLL
108
# define EV_USE_POLL 0
109
# endif
110
111
# if HAVE_EPOLL_CTL && HAVE_SYS_EPOLL_H
112
# ifndef EV_USE_EPOLL
113
# define EV_USE_EPOLL EV_FEATURE_BACKENDS
114
# endif
115
# else
116
# undef EV_USE_EPOLL
117
# define EV_USE_EPOLL 0
118
# endif
119
120
# if HAVE_KQUEUE && HAVE_SYS_EVENT_H
121
# ifndef EV_USE_KQUEUE
122
# define EV_USE_KQUEUE EV_FEATURE_BACKENDS
123
# endif
124
# else
125
# undef EV_USE_KQUEUE
126
# define EV_USE_KQUEUE 0
127
# endif
128
129
# if HAVE_PORT_H && HAVE_PORT_CREATE
130
# ifndef EV_USE_PORT
131
# define EV_USE_PORT EV_FEATURE_BACKENDS
132
# endif
133
# else
134
# undef EV_USE_PORT
135
# define EV_USE_PORT 0
136
# endif
137
138
# if HAVE_INOTIFY_INIT && HAVE_SYS_INOTIFY_H
139
# ifndef EV_USE_INOTIFY
140
# define EV_USE_INOTIFY EV_FEATURE_OS
141
# endif
142
# else
143
# undef EV_USE_INOTIFY
144
# define EV_USE_INOTIFY 0
145
# endif
146
147
# if HAVE_SIGNALFD && HAVE_SYS_SIGNALFD_H
148
# ifndef EV_USE_SIGNALFD
149
# define EV_USE_SIGNALFD EV_FEATURE_OS
150
# endif
151
# else
152
# undef EV_USE_SIGNALFD
153
# define EV_USE_SIGNALFD 0
154
# endif
155
156
# if HAVE_EVENTFD
157
# ifndef EV_USE_EVENTFD
158
# define EV_USE_EVENTFD EV_FEATURE_OS
159
# endif
160
# else
161
# undef EV_USE_EVENTFD
162
# define EV_USE_EVENTFD 0
163
# endif
164
165
#endif
166
167
#include <stdlib.h>
168
#include <string.h>
169
#include <fcntl.h>
170
#include <stddef.h>
171
172
#include <stdio.h>
173
174
#include <assert.h>
175
#include <errno.h>
176
#include <sys/types.h>
177
#include <time.h>
178
#include <limits.h>
179
180
#include <signal.h>
181
182
#ifdef EV_H
183
# include EV_H
184
#else
185
# include "ev.h"
186
#endif
187
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
198
199
#ifndef _WIN32
200
# include <sys/time.h>
201
# include <sys/wait.h>
202
# include <unistd.h>
203
#else
204
# include <io.h>
205
# define WIN32_LEAN_AND_MEAN
206
# include <winsock2.h>
207
# include <windows.h>
208
# ifndef EV_SELECT_IS_WINSOCKET
209
# define EV_SELECT_IS_WINSOCKET 1
210
# endif
211
# undef EV_AVOID_STDIO
212
#endif
213
214
/* OS X, in its infinite idiocy, actually HARDCODES
215
* a limit of 1024 into their select. Where people have brains,
216
* OS X engineers apparently have a vacuum. Or maybe they were
217
* ordered to have a vacuum, or they do anything for money.
218
* This might help. Or not.
219
*/
220
#define _DARWIN_UNLIMITED_SELECT 1
221
222
/* this block tries to deduce configuration from header-defined symbols and defaults */
223
224
/* try to deduce the maximum number of signals on this platform */
225
#if defined EV_NSIG
226
/* use what's provided */
227
#elif defined NSIG
228
# define EV_NSIG (NSIG)
229
#elif defined _NSIG
230
# define EV_NSIG (_NSIG)
231
#elif defined SIGMAX
232
# define EV_NSIG (SIGMAX+1)
233
#elif defined SIG_MAX
234
# define EV_NSIG (SIG_MAX+1)
235
#elif defined _SIG_MAX
236
# define EV_NSIG (_SIG_MAX+1)
237
#elif defined MAXSIG
238
# define EV_NSIG (MAXSIG+1)
239
#elif defined MAX_SIG
240
# define EV_NSIG (MAX_SIG+1)
241
#elif defined SIGARRAYSIZE
242
# define EV_NSIG (SIGARRAYSIZE) /* Assume ary[SIGARRAYSIZE] */
243
#elif defined _sys_nsig
244
# define EV_NSIG (_sys_nsig) /* Solaris 2.5 */
245
#else
246
# define EV_NSIG (8 * sizeof (sigset_t) + 1)
247
#endif
248
249
#ifndef EV_USE_FLOOR
250
# define EV_USE_FLOOR 0
251
#endif
252
253
#ifndef EV_USE_CLOCK_SYSCALL
254
# if __linux && __GLIBC__ == 2 && __GLIBC_MINOR__ < 17
255
# define EV_USE_CLOCK_SYSCALL EV_FEATURE_OS
256
# else
257
# define EV_USE_CLOCK_SYSCALL 0
258
# endif
259
#endif
260
261
#if !(_POSIX_TIMERS > 0)
262
# ifndef EV_USE_MONOTONIC
263
# define EV_USE_MONOTONIC 0
264
# endif
265
# ifndef EV_USE_REALTIME
266
# define EV_USE_REALTIME 0
267
# endif
268
#endif
269
270
#ifndef EV_USE_MONOTONIC
271
# if defined _POSIX_MONOTONIC_CLOCK && _POSIX_MONOTONIC_CLOCK >= 0
272
# define EV_USE_MONOTONIC EV_FEATURE_OS
273
# else
274
# define EV_USE_MONOTONIC 0
275
# endif
276
#endif
277
278
#ifndef EV_USE_REALTIME
279
# define EV_USE_REALTIME !EV_USE_CLOCK_SYSCALL
280
#endif
281
282
#ifndef EV_USE_NANOSLEEP
283
# if _POSIX_C_SOURCE >= 199309L
284
# define EV_USE_NANOSLEEP EV_FEATURE_OS
285
# else
286
# define EV_USE_NANOSLEEP 0
287
# endif
288
#endif
289
290
#ifndef EV_USE_SELECT
291
# define EV_USE_SELECT EV_FEATURE_BACKENDS
292
#endif
293
294
#ifndef EV_USE_POLL
295
# ifdef _WIN32
296
# define EV_USE_POLL 0
297
# else
298
# define EV_USE_POLL EV_FEATURE_BACKENDS
299
# endif
300
#endif
301
302
#ifndef EV_USE_EPOLL
303
# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
304
# define EV_USE_EPOLL EV_FEATURE_BACKENDS
305
# else
306
# define EV_USE_EPOLL 0
307
# endif
308
#endif
309
310
#ifndef EV_USE_KQUEUE
311
# define EV_USE_KQUEUE 0
312
#endif
313
314
#ifndef EV_USE_PORT
315
# define EV_USE_PORT 0
316
#endif
317
318
#ifndef EV_USE_INOTIFY
319
# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 4))
320
# define EV_USE_INOTIFY EV_FEATURE_OS
321
# else
322
# define EV_USE_INOTIFY 0
323
# endif
324
#endif
325
326
#ifndef EV_PID_HASHSIZE
327
# define EV_PID_HASHSIZE EV_FEATURE_DATA ? 16 : 1
328
#endif
329
330
#ifndef EV_INOTIFY_HASHSIZE
331
# define EV_INOTIFY_HASHSIZE EV_FEATURE_DATA ? 16 : 1
332
#endif
333
334
#ifndef EV_USE_EVENTFD
335
# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
336
# define EV_USE_EVENTFD EV_FEATURE_OS
337
# else
338
# define EV_USE_EVENTFD 0
339
# endif
340
#endif
341
342
#ifndef EV_USE_SIGNALFD
343
# if __linux && (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 7))
344
# define EV_USE_SIGNALFD EV_FEATURE_OS
345
# else
346
# define EV_USE_SIGNALFD 0
347
# endif
348
#endif
349
350
#if 0 /* debugging */
351
# define EV_VERIFY 3
352
# define EV_USE_4HEAP 1
353
# define EV_HEAP_CACHE_AT 1
354
#endif
355
356
#ifndef EV_VERIFY
357
# define EV_VERIFY (EV_FEATURE_API ? 1 : 0)
358
#endif
359
360
#ifndef EV_USE_4HEAP
361
# define EV_USE_4HEAP EV_FEATURE_DATA
362
#endif
363
364
#ifndef EV_HEAP_CACHE_AT
365
# define EV_HEAP_CACHE_AT EV_FEATURE_DATA
366
#endif
367
368
#ifdef ANDROID
369
/* supposedly, android doesn't typedef fd_mask */
370
# undef EV_USE_SELECT
371
# define EV_USE_SELECT 0
372
/* supposedly, we need to include syscall.h, not sys/syscall.h, so just disable */
373
# undef EV_USE_CLOCK_SYSCALL
374
# define EV_USE_CLOCK_SYSCALL 0
375
#endif
376
377
/* aix's poll.h seems to cause lots of trouble */
378
#ifdef _AIX
379
/* AIX has a completely broken poll.h header */
380
# undef EV_USE_POLL
381
# define EV_USE_POLL 0
382
#endif
383
384
/* on linux, we can use a (slow) syscall to avoid a dependency on pthread, */
385
/* which makes programs even slower. might work on other unices, too. */
386
#if EV_USE_CLOCK_SYSCALL
387
# include <sys/syscall.h>
388
# ifdef SYS_clock_gettime
389
# define clock_gettime(id, ts) syscall (SYS_clock_gettime, (id), (ts))
390
# undef EV_USE_MONOTONIC
391
# define EV_USE_MONOTONIC 1
392
# else
393
# undef EV_USE_CLOCK_SYSCALL
394
# define EV_USE_CLOCK_SYSCALL 0
395
# endif
396
#endif
397
398
/* this block fixes any misconfiguration where we know we run into trouble otherwise */
399
400
#ifndef CLOCK_MONOTONIC
401
# undef EV_USE_MONOTONIC
402
# define EV_USE_MONOTONIC 0
403
#endif
404
405
#ifndef CLOCK_REALTIME
406
# undef EV_USE_REALTIME
407
# define EV_USE_REALTIME 0
408
#endif
409
410
#if !EV_STAT_ENABLE
411
# undef EV_USE_INOTIFY
412
# define EV_USE_INOTIFY 0
413
#endif
414
415
#if !EV_USE_NANOSLEEP
416
/* hp-ux has it in sys/time.h, which we unconditionally include above */
417
# if !defined _WIN32 && !defined __hpux
418
# include <sys/select.h>
419
# endif
420
#endif
421
422
#if EV_USE_INOTIFY
423
# include <sys/statfs.h>
424
# include <sys/inotify.h>
425
/* some very old inotify.h headers don't have IN_DONT_FOLLOW */
426
# ifndef IN_DONT_FOLLOW
427
# undef EV_USE_INOTIFY
428
# define EV_USE_INOTIFY 0
429
# endif
430
#endif
431
432
#if EV_USE_EVENTFD
433
/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
434
# include <stdint.h>
435
# ifndef EFD_NONBLOCK
436
# define EFD_NONBLOCK O_NONBLOCK
437
# endif
438
# ifndef EFD_CLOEXEC
439
# ifdef O_CLOEXEC
440
# define EFD_CLOEXEC O_CLOEXEC
441
# else
442
# define EFD_CLOEXEC 02000000
443
# endif
444
# endif
445
EV_CPP(extern "C") int (eventfd) (unsigned int initval, int flags);
446
#endif
447
448
#if EV_USE_SIGNALFD
449
/* our minimum requirement is glibc 2.7 which has the stub, but not the header */
450
# include <stdint.h>
451
# ifndef SFD_NONBLOCK
452
# define SFD_NONBLOCK O_NONBLOCK
453
# endif
454
# ifndef SFD_CLOEXEC
455
# ifdef O_CLOEXEC
456
# define SFD_CLOEXEC O_CLOEXEC
457
# else
458
# define SFD_CLOEXEC 02000000
459
# endif
460
# endif
461
EV_CPP (extern "C") int signalfd (int fd, const sigset_t *mask, int flags);
462
463
struct signalfd_siginfo
464
{
465
uint32_t ssi_signo;
466
char pad[128 - sizeof (uint32_t)];
467
};
468
#endif
469
470
/**/
471
472
#if EV_VERIFY >= 3
473
# define EV_FREQUENT_CHECK ev_verify (EV_A)
474
#else
475
# define EV_FREQUENT_CHECK do { } while (0)
476
#endif
477
478
/*
479
* This is used to work around floating point rounding problems.
480
* This value is good at least till the year 4000.
481
*/
482
#define MIN_INTERVAL 0.0001220703125 /* 1/2**13, good till 4000 */
483
/*#define MIN_INTERVAL 0.00000095367431640625 /* 1/2**20, good till 2200 */
484
485
#define MIN_TIMEJUMP 1. /* minimum timejump that gets detected (if monotonic clock available) */
486
#define MAX_BLOCKTIME 59.743 /* never wait longer than this time (to detect time jumps) */
487
488
#define EV_TV_SET(tv,t) do { tv.tv_sec = (long)t; tv.tv_usec = (long)((t - tv.tv_sec) * 1e6); } while (0)
489
#define EV_TS_SET(ts,t) do { ts.tv_sec = (long)t; ts.tv_nsec = (long)((t - ts.tv_sec) * 1e9); } while (0)
490
491
/* the following is ecb.h embedded into libev - use update_ev_c to update from an external copy */
492
/* ECB.H BEGIN */
493
/*
494
* libecb - http://software.schmorp.de/pkg/libecb
495
*
496
* Copyright (©) 2009-2015 Marc Alexander Lehmann <[email protected]>
497
* Copyright (©) 2011 Emanuele Giaquinta
498
* All rights reserved.
499
*
500
* Redistribution and use in source and binary forms, with or without modifica-
501
* tion, are permitted provided that the following conditions are met:
502
*
503
* 1. Redistributions of source code must retain the above copyright notice,
504
* this list of conditions and the following disclaimer.
505
*
506
* 2. Redistributions in binary form must reproduce the above copyright
507
* notice, this list of conditions and the following disclaimer in the
508
* documentation and/or other materials provided with the distribution.
509
*
510
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
511
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
512
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
513
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
514
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
515
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
516
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
517
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
518
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
519
* OF THE POSSIBILITY OF SUCH DAMAGE.
520
*
521
* Alternatively, the contents of this file may be used under the terms of
522
* the GNU General Public License ("GPL") version 2 or any later version,
523
* in which case the provisions of the GPL are applicable instead of
524
* the above. If you wish to allow the use of your version of this file
525
* only under the terms of the GPL and not to allow others to use your
526
* version of this file under the BSD license, indicate your decision
527
* by deleting the provisions above and replace them with the notice
528
* and other provisions required by the GPL. If you do not delete the
529
* provisions above, a recipient may use your version of this file under
530
* either the BSD or the GPL.
531
*/
532
533
#ifndef ECB_H
534
#define ECB_H
535
536
/* 16 bits major, 16 bits minor */
537
#define ECB_VERSION 0x00010005
538
539
#ifdef _WIN32
540
typedef signed char int8_t;
541
typedef unsigned char uint8_t;
542
typedef signed short int16_t;
543
typedef unsigned short uint16_t;
544
typedef signed int int32_t;
545
typedef unsigned int uint32_t;
546
#if __GNUC__
547
typedef signed long long int64_t;
548
typedef unsigned long long uint64_t;
549
#else /* _MSC_VER || __BORLANDC__ */
550
typedef signed __int64 int64_t;
551
typedef unsigned __int64 uint64_t;
552
#endif
553
#ifdef _WIN64
554
#define ECB_PTRSIZE 8
555
typedef uint64_t uintptr_t;
556
typedef int64_t intptr_t;
557
#else
558
#define ECB_PTRSIZE 4
559
typedef uint32_t uintptr_t;
560
typedef int32_t intptr_t;
561
#endif
562
#else
563
#include <inttypes.h>
564
#if (defined INTPTR_MAX ? INTPTR_MAX : ULONG_MAX) > 0xffffffffU
565
#define ECB_PTRSIZE 8
566
#else
567
#define ECB_PTRSIZE 4
568
#endif
569
#endif
570
571
#define ECB_GCC_AMD64 (__amd64 || __amd64__ || __x86_64 || __x86_64__)
572
#define ECB_MSVC_AMD64 (_M_AMD64 || _M_X64)
573
574
/* work around x32 idiocy by defining proper macros */
575
#if ECB_GCC_AMD64 || ECB_MSVC_AMD64
576
#if _ILP32
577
#define ECB_AMD64_X32 1
578
#else
579
#define ECB_AMD64 1
580
#endif
581
#endif
582
583
/* many compilers define _GNUC_ to some versions but then only implement
584
* what their idiot authors think are the "more important" extensions,
585
* causing enormous grief in return for some better fake benchmark numbers.
586
* or so.
587
* we try to detect these and simply assume they are not gcc - if they have
588
* an issue with that they should have done it right in the first place.
589
*/
590
#if !defined __GNUC_MINOR__ || defined __INTEL_COMPILER || defined __SUNPRO_C || defined __SUNPRO_CC || defined __llvm__ || defined __clang__
591
#define ECB_GCC_VERSION(major,minor) 0
592
#else
593
#define ECB_GCC_VERSION(major,minor) (__GNUC__ > (major) || (__GNUC__ == (major) && __GNUC_MINOR__ >= (minor)))
594
#endif
595
596
#define ECB_CLANG_VERSION(major,minor) (__clang_major__ > (major) || (__clang_major__ == (major) && __clang_minor__ >= (minor)))
597
598
#if __clang__ && defined __has_builtin
599
#define ECB_CLANG_BUILTIN(x) __has_builtin (x)
600
#else
601
#define ECB_CLANG_BUILTIN(x) 0
602
#endif
603
604
#if __clang__ && defined __has_extension
605
#define ECB_CLANG_EXTENSION(x) __has_extension (x)
606
#else
607
#define ECB_CLANG_EXTENSION(x) 0
608
#endif
609
610
#define ECB_CPP (__cplusplus+0)
611
#define ECB_CPP11 (__cplusplus >= 201103L)
612
613
#if ECB_CPP
614
#define ECB_C 0
615
#define ECB_STDC_VERSION 0
616
#else
617
#define ECB_C 1
618
#define ECB_STDC_VERSION __STDC_VERSION__
619
#endif
620
621
#define ECB_C99 (ECB_STDC_VERSION >= 199901L)
622
#define ECB_C11 (ECB_STDC_VERSION >= 201112L)
623
624
#if ECB_CPP
625
#define ECB_EXTERN_C extern "C"
626
#define ECB_EXTERN_C_BEG ECB_EXTERN_C {
627
#define ECB_EXTERN_C_END }
628
#else
629
#define ECB_EXTERN_C extern
630
#define ECB_EXTERN_C_BEG
631
#define ECB_EXTERN_C_END
632
#endif
633
634
/*****************************************************************************/
635
636
/* ECB_NO_THREADS - ecb is not used by multiple threads, ever */
637
/* ECB_NO_SMP - ecb might be used in multiple threads, but only on a single cpu */
638
639
#if ECB_NO_THREADS
640
#define ECB_NO_SMP 1
641
#endif
642
643
#if ECB_NO_SMP
644
#define ECB_MEMORY_FENCE do { } while (0)
645
#endif
646
647
/* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/compiler_ref/compiler_builtins.html */
648
#if __xlC__ && ECB_CPP
649
#include <builtins.h>
650
#endif
651
652
#if 1400 <= _MSC_VER
653
#include <intrin.h> /* fence functions _ReadBarrier, also bit search functions _BitScanReverse */
654
#endif
655
656
#ifndef ECB_MEMORY_FENCE
657
#if ECB_GCC_VERSION(2,5) || defined __INTEL_COMPILER || (__llvm__ && __GNUC__) || __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
658
#if __i386 || __i386__
659
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("lock; orb $0, -1(%%esp)" : : : "memory")
660
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
661
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
662
#elif ECB_GCC_AMD64
663
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mfence" : : : "memory")
664
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("" : : : "memory")
665
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
666
#elif __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__
667
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("sync" : : : "memory")
668
#elif defined __ARM_ARCH_2__ \
669
|| defined __ARM_ARCH_3__ || defined __ARM_ARCH_3M__ \
670
|| defined __ARM_ARCH_4__ || defined __ARM_ARCH_4T__ \
671
|| defined __ARM_ARCH_5__ || defined __ARM_ARCH_5E__ \
672
|| defined __ARM_ARCH_5T__ || defined __ARM_ARCH_5TE__ \
673
|| defined __ARM_ARCH_5TEJ__
674
/* should not need any, unless running old code on newer cpu - arm doesn't support that */
675
#elif defined __ARM_ARCH_6__ || defined __ARM_ARCH_6J__ \
676
|| defined __ARM_ARCH_6K__ || defined __ARM_ARCH_6ZK__ \
677
|| defined __ARM_ARCH_6T2__
678
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mcr p15,0,%0,c7,c10,5" : : "r" (0) : "memory")
679
#elif defined __ARM_ARCH_7__ || defined __ARM_ARCH_7A__ \
680
|| defined __ARM_ARCH_7R__ || defined __ARM_ARCH_7M__
681
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb" : : : "memory")
682
#elif __aarch64__
683
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("dmb ish" : : : "memory")
684
#elif (__sparc || __sparc__) && !(__sparc_v8__ || defined __sparcv8)
685
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad | #StoreStore | #StoreLoad" : : : "memory")
686
#define ECB_MEMORY_FENCE_ACQUIRE __asm__ __volatile__ ("membar #LoadStore | #LoadLoad" : : : "memory")
687
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("membar #LoadStore | #StoreStore")
688
#elif defined __s390__ || defined __s390x__
689
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("bcr 15,0" : : : "memory")
690
#elif defined __mips__
691
/* GNU/Linux emulates sync on mips1 architectures, so we force its use */
692
/* anybody else who still uses mips1 is supposed to send in their version, with detection code. */
693
#define ECB_MEMORY_FENCE __asm__ __volatile__ (".set mips2; sync; .set mips0" : : : "memory")
694
#elif defined __alpha__
695
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mb" : : : "memory")
696
#elif defined __hppa__
697
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
698
#define ECB_MEMORY_FENCE_RELEASE __asm__ __volatile__ ("")
699
#elif defined __ia64__
700
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("mf" : : : "memory")
701
#elif defined __m68k__
702
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
703
#elif defined __m88k__
704
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("tb1 0,%%r0,128" : : : "memory")
705
#elif defined __sh__
706
#define ECB_MEMORY_FENCE __asm__ __volatile__ ("" : : : "memory")
707
#endif
708
#endif
709
#endif
710
711
#ifndef ECB_MEMORY_FENCE
712
#if ECB_GCC_VERSION(4,7)
713
/* see comment below (stdatomic.h) about the C11 memory model. */
714
#define ECB_MEMORY_FENCE __atomic_thread_fence (__ATOMIC_SEQ_CST)
715
#define ECB_MEMORY_FENCE_ACQUIRE __atomic_thread_fence (__ATOMIC_ACQUIRE)
716
#define ECB_MEMORY_FENCE_RELEASE __atomic_thread_fence (__ATOMIC_RELEASE)
717
718
#elif ECB_CLANG_EXTENSION(c_atomic)
719
/* see comment below (stdatomic.h) about the C11 memory model. */
720
#define ECB_MEMORY_FENCE __c11_atomic_thread_fence (__ATOMIC_SEQ_CST)
721
#define ECB_MEMORY_FENCE_ACQUIRE __c11_atomic_thread_fence (__ATOMIC_ACQUIRE)
722
#define ECB_MEMORY_FENCE_RELEASE __c11_atomic_thread_fence (__ATOMIC_RELEASE)
723
724
#elif ECB_GCC_VERSION(4,4) || defined __INTEL_COMPILER || defined __clang__
725
#define ECB_MEMORY_FENCE __sync_synchronize ()
726
#elif _MSC_VER >= 1500 /* VC++ 2008 */
727
/* apparently, microsoft broke all the memory barrier stuff in Visual Studio 2008... */
728
#pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
729
#define ECB_MEMORY_FENCE _ReadWriteBarrier (); MemoryBarrier()
730
#define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier (); MemoryBarrier() /* according to msdn, _ReadBarrier is not a load fence */
731
#define ECB_MEMORY_FENCE_RELEASE _WriteBarrier (); MemoryBarrier()
732
#elif _MSC_VER >= 1400 /* VC++ 2005 */
733
#pragma intrinsic(_ReadBarrier,_WriteBarrier,_ReadWriteBarrier)
734
#define ECB_MEMORY_FENCE _ReadWriteBarrier ()
735
#define ECB_MEMORY_FENCE_ACQUIRE _ReadWriteBarrier () /* according to msdn, _ReadBarrier is not a load fence */
736
#define ECB_MEMORY_FENCE_RELEASE _WriteBarrier ()
737
#elif defined _WIN32
738
#include <WinNT.h>
739
#define ECB_MEMORY_FENCE MemoryBarrier () /* actually just xchg on x86... scary */
740
#elif __SUNPRO_C >= 0x5110 || __SUNPRO_CC >= 0x5110
741
#include <mbarrier.h>
742
#define ECB_MEMORY_FENCE __machine_rw_barrier ()
743
#define ECB_MEMORY_FENCE_ACQUIRE __machine_r_barrier ()
744
#define ECB_MEMORY_FENCE_RELEASE __machine_w_barrier ()
745
#elif __xlC__
746
#define ECB_MEMORY_FENCE __sync ()
747
#endif
748
#endif
749
750
#ifndef ECB_MEMORY_FENCE
751
#if ECB_C11 && !defined __STDC_NO_ATOMICS__
752
/* we assume that these memory fences work on all variables/all memory accesses, */
753
/* not just C11 atomics and atomic accesses */
754
#include <stdatomic.h>
755
/* Unfortunately, neither gcc 4.7 nor clang 3.1 generate any instructions for */
756
/* any fence other than seq_cst, which isn't very efficient for us. */
757
/* Why that is, we don't know - either the C11 memory model is quite useless */
758
/* for most usages, or gcc and clang have a bug */
759
/* I *currently* lean towards the latter, and inefficiently implement */
760
/* all three of ecb's fences as a seq_cst fence */
761
/* Update, gcc-4.8 generates mfence for all c++ fences, but nothing */
762
/* for all __atomic_thread_fence's except seq_cst */
763
#define ECB_MEMORY_FENCE atomic_thread_fence (memory_order_seq_cst)
764
#endif
765
#endif
766
767
#ifndef ECB_MEMORY_FENCE
768
#if !ECB_AVOID_PTHREADS
769
/*
770
* if you get undefined symbol references to pthread_mutex_lock,
771
* or failure to find pthread.h, then you should implement
772
* the ECB_MEMORY_FENCE operations for your cpu/compiler
773
* OR provide pthread.h and link against the posix thread library
774
* of your system.
775
*/
776
#include <pthread.h>
777
#define ECB_NEEDS_PTHREADS 1
778
#define ECB_MEMORY_FENCE_NEEDS_PTHREADS 1
779
780
static pthread_mutex_t ecb_mf_lock = PTHREAD_MUTEX_INITIALIZER;
781
#define ECB_MEMORY_FENCE do { pthread_mutex_lock (&ecb_mf_lock); pthread_mutex_unlock (&ecb_mf_lock); } while (0)
782
#endif
783
#endif
784
785
#if !defined ECB_MEMORY_FENCE_ACQUIRE && defined ECB_MEMORY_FENCE
786
#define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
787
#endif
788
789
#if !defined ECB_MEMORY_FENCE_RELEASE && defined ECB_MEMORY_FENCE
790
#define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
791
#endif
792
793
/*****************************************************************************/
794
795
#if ECB_CPP
796
#define ecb_inline static inline
797
#elif ECB_GCC_VERSION(2,5)
798
#define ecb_inline static __inline__
799
#elif ECB_C99
800
#define ecb_inline static inline
801
#else
802
#define ecb_inline static
803
#endif
804
805
#if ECB_GCC_VERSION(3,3)
806
#define ecb_restrict __restrict__
807
#elif ECB_C99
808
#define ecb_restrict restrict
809
#else
810
#define ecb_restrict
811
#endif
812
813
typedef int ecb_bool;
814
815
#define ECB_CONCAT_(a, b) a ## b
816
#define ECB_CONCAT(a, b) ECB_CONCAT_(a, b)
817
#define ECB_STRINGIFY_(a) # a
818
#define ECB_STRINGIFY(a) ECB_STRINGIFY_(a)
819
#define ECB_STRINGIFY_EXPR(expr) ((expr), ECB_STRINGIFY_ (expr))
820
821
#define ecb_function_ ecb_inline
822
823
#if ECB_GCC_VERSION(3,1) || ECB_CLANG_VERSION(2,8)
824
#define ecb_attribute(attrlist) __attribute__ (attrlist)
825
#else
826
#define ecb_attribute(attrlist)
827
#endif
828
829
#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_constant_p)
830
#define ecb_is_constant(expr) __builtin_constant_p (expr)
831
#else
832
/* possible C11 impl for integral types
833
typedef struct ecb_is_constant_struct ecb_is_constant_struct;
834
#define ecb_is_constant(expr) _Generic ((1 ? (struct ecb_is_constant_struct *)0 : (void *)((expr) - (expr)), ecb_is_constant_struct *: 0, default: 1)) */
835
836
#define ecb_is_constant(expr) 0
837
#endif
838
839
#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_expect)
840
#define ecb_expect(expr,value) __builtin_expect ((expr),(value))
841
#else
842
#define ecb_expect(expr,value) (expr)
843
#endif
844
845
#if ECB_GCC_VERSION(3,1) || ECB_CLANG_BUILTIN(__builtin_prefetch)
846
#define ecb_prefetch(addr,rw,locality) __builtin_prefetch (addr, rw, locality)
847
#else
848
#define ecb_prefetch(addr,rw,locality)
849
#endif
850
851
/* no emulation for ecb_decltype */
852
#if ECB_CPP11
853
// older implementations might have problems with decltype(x)::type, work around it
854
template<class T> struct ecb_decltype_t { typedef T type; };
855
#define ecb_decltype(x) ecb_decltype_t<decltype (x)>::type
856
#elif ECB_GCC_VERSION(3,0) || ECB_CLANG_VERSION(2,8)
857
#define ecb_decltype(x) __typeof__ (x)
858
#endif
859
860
#if _MSC_VER >= 1300
861
#define ecb_deprecated __declspec (deprecated)
862
#else
863
#define ecb_deprecated ecb_attribute ((__deprecated__))
864
#endif
865
866
#if _MSC_VER >= 1500
867
#define ecb_deprecated_message(msg) __declspec (deprecated (msg))
868
#elif ECB_GCC_VERSION(4,5)
869
#define ecb_deprecated_message(msg) ecb_attribute ((__deprecated__ (msg))
870
#else
871
#define ecb_deprecated_message(msg) ecb_deprecated
872
#endif
873
874
#if _MSC_VER >= 1400
875
#define ecb_noinline __declspec (noinline)
876
#else
877
#define ecb_noinline ecb_attribute ((__noinline__))
878
#endif
879
880
#define ecb_unused ecb_attribute ((__unused__))
881
#define ecb_const ecb_attribute ((__const__))
882
#define ecb_pure ecb_attribute ((__pure__))
883
884
#if ECB_C11 || __IBMC_NORETURN
885
/* http://www-01.ibm.com/support/knowledgecenter/SSGH3R_13.1.0/com.ibm.xlcpp131.aix.doc/language_ref/noreturn.html */
886
#define ecb_noreturn _Noreturn
887
#elif ECB_CPP11
888
#define ecb_noreturn [[noreturn]]
889
#elif _MSC_VER >= 1200
890
/* http://msdn.microsoft.com/en-us/library/k6ktzx3s.aspx */
891
#define ecb_noreturn __declspec (noreturn)
892
#else
893
#define ecb_noreturn ecb_attribute ((__noreturn__))
894
#endif
895
896
#if ECB_GCC_VERSION(4,3)
897
#define ecb_artificial ecb_attribute ((__artificial__))
898
#define ecb_hot ecb_attribute ((__hot__))
899
#define ecb_cold ecb_attribute ((__cold__))
900
#else
901
#define ecb_artificial
902
#define ecb_hot
903
#define ecb_cold
904
#endif
905
906
/* put around conditional expressions if you are very sure that the */
907
/* expression is mostly true or mostly false. note that these return */
908
/* booleans, not the expression. */
909
#define ecb_expect_false(expr) ecb_expect (!!(expr), 0)
910
#define ecb_expect_true(expr) ecb_expect (!!(expr), 1)
911
/* for compatibility to the rest of the world */
912
#define ecb_likely(expr) ecb_expect_true (expr)
913
#define ecb_unlikely(expr) ecb_expect_false (expr)
914
915
/* count trailing zero bits and count # of one bits */
916
#if ECB_GCC_VERSION(3,4) \
917
|| (ECB_CLANG_BUILTIN(__builtin_clz) && ECB_CLANG_BUILTIN(__builtin_clzll) \
918
&& ECB_CLANG_BUILTIN(__builtin_ctz) && ECB_CLANG_BUILTIN(__builtin_ctzll) \
919
&& ECB_CLANG_BUILTIN(__builtin_popcount))
920
/* we assume int == 32 bit, long == 32 or 64 bit and long long == 64 bit */
921
#define ecb_ld32(x) (__builtin_clz (x) ^ 31)
922
#define ecb_ld64(x) (__builtin_clzll (x) ^ 63)
923
#define ecb_ctz32(x) __builtin_ctz (x)
924
#define ecb_ctz64(x) __builtin_ctzll (x)
925
#define ecb_popcount32(x) __builtin_popcount (x)
926
/* no popcountll */
927
#else
928
ecb_function_ ecb_const int ecb_ctz32 (uint32_t x);
929
ecb_function_ ecb_const int
930
ecb_ctz32 (uint32_t x)
931
{
932
#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
933
unsigned long r;
934
_BitScanForward (&r, x);
935
return (int)r;
936
#else
937
int r = 0;
938
939
x &= ~x + 1; /* this isolates the lowest bit */
940
941
#if ECB_branchless_on_i386
942
r += !!(x & 0xaaaaaaaa) << 0;
943
r += !!(x & 0xcccccccc) << 1;
944
r += !!(x & 0xf0f0f0f0) << 2;
945
r += !!(x & 0xff00ff00) << 3;
946
r += !!(x & 0xffff0000) << 4;
947
#else
948
if (x & 0xaaaaaaaa) r += 1;
949
if (x & 0xcccccccc) r += 2;
950
if (x & 0xf0f0f0f0) r += 4;
951
if (x & 0xff00ff00) r += 8;
952
if (x & 0xffff0000) r += 16;
953
#endif
954
955
return r;
956
#endif
957
}
958
959
ecb_function_ ecb_const int ecb_ctz64 (uint64_t x);
960
ecb_function_ ecb_const int
961
ecb_ctz64 (uint64_t x)
962
{
963
#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
964
unsigned long r;
965
_BitScanForward64 (&r, x);
966
return (int)r;
967
#else
968
int shift = x & 0xffffffff ? 0 : 32;
969
return ecb_ctz32 (x >> shift) + shift;
970
#endif
971
}
972
973
ecb_function_ ecb_const int ecb_popcount32 (uint32_t x);
974
ecb_function_ ecb_const int
975
ecb_popcount32 (uint32_t x)
976
{
977
x -= (x >> 1) & 0x55555555;
978
x = ((x >> 2) & 0x33333333) + (x & 0x33333333);
979
x = ((x >> 4) + x) & 0x0f0f0f0f;
980
x *= 0x01010101;
981
982
return x >> 24;
983
}
984
985
ecb_function_ ecb_const int ecb_ld32 (uint32_t x);
986
ecb_function_ ecb_const int ecb_ld32 (uint32_t x)
987
{
988
#if 1400 <= _MSC_VER && (_M_IX86 || _M_X64 || _M_IA64 || _M_ARM)
989
unsigned long r;
990
_BitScanReverse (&r, x);
991
return (int)r;
992
#else
993
int r = 0;
994
995
if (x >> 16) { x >>= 16; r += 16; }
996
if (x >> 8) { x >>= 8; r += 8; }
997
if (x >> 4) { x >>= 4; r += 4; }
998
if (x >> 2) { x >>= 2; r += 2; }
999
if (x >> 1) { r += 1; }
1000
1001
return r;
1002
#endif
1003
}
1004
1005
ecb_function_ ecb_const int ecb_ld64 (uint64_t x);
1006
ecb_function_ ecb_const int ecb_ld64 (uint64_t x)
1007
{
1008
#if 1400 <= _MSC_VER && (_M_X64 || _M_IA64 || _M_ARM)
1009
unsigned long r;
1010
_BitScanReverse64 (&r, x);
1011
return (int)r;
1012
#else
1013
int r = 0;
1014
1015
if (x >> 32) { x >>= 32; r += 32; }
1016
1017
return r + ecb_ld32 (x);
1018
#endif
1019
}
1020
#endif
1021
1022
ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x);
1023
ecb_function_ ecb_const ecb_bool ecb_is_pot32 (uint32_t x) { return !(x & (x - 1)); }
1024
ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x);
1025
ecb_function_ ecb_const ecb_bool ecb_is_pot64 (uint64_t x) { return !(x & (x - 1)); }
1026
1027
ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x);
1028
ecb_function_ ecb_const uint8_t ecb_bitrev8 (uint8_t x)
1029
{
1030
return ( (x * 0x0802U & 0x22110U)
1031
| (x * 0x8020U & 0x88440U)) * 0x10101U >> 16;
1032
}
1033
1034
ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x);
1035
ecb_function_ ecb_const uint16_t ecb_bitrev16 (uint16_t x)
1036
{
1037
x = ((x >> 1) & 0x5555) | ((x & 0x5555) << 1);
1038
x = ((x >> 2) & 0x3333) | ((x & 0x3333) << 2);
1039
x = ((x >> 4) & 0x0f0f) | ((x & 0x0f0f) << 4);
1040
x = ( x >> 8 ) | ( x << 8);
1041
1042
return x;
1043
}
1044
1045
ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x);
1046
ecb_function_ ecb_const uint32_t ecb_bitrev32 (uint32_t x)
1047
{
1048
x = ((x >> 1) & 0x55555555) | ((x & 0x55555555) << 1);
1049
x = ((x >> 2) & 0x33333333) | ((x & 0x33333333) << 2);
1050
x = ((x >> 4) & 0x0f0f0f0f) | ((x & 0x0f0f0f0f) << 4);
1051
x = ((x >> 8) & 0x00ff00ff) | ((x & 0x00ff00ff) << 8);
1052
x = ( x >> 16 ) | ( x << 16);
1053
1054
return x;
1055
}
1056
1057
/* popcount64 is only available on 64 bit cpus as gcc builtin */
1058
/* so for this version we are lazy */
1059
ecb_function_ ecb_const int ecb_popcount64 (uint64_t x);
1060
ecb_function_ ecb_const int
1061
ecb_popcount64 (uint64_t x)
1062
{
1063
return ecb_popcount32 (x) + ecb_popcount32 (x >> 32);
1064
}
1065
1066
ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count);
1067
ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count);
1068
ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count);
1069
ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count);
1070
ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count);
1071
ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count);
1072
ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count);
1073
ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count);
1074
1075
ecb_inline ecb_const uint8_t ecb_rotl8 (uint8_t x, unsigned int count) { return (x >> ( 8 - count)) | (x << count); }
1076
ecb_inline ecb_const uint8_t ecb_rotr8 (uint8_t x, unsigned int count) { return (x << ( 8 - count)) | (x >> count); }
1077
ecb_inline ecb_const uint16_t ecb_rotl16 (uint16_t x, unsigned int count) { return (x >> (16 - count)) | (x << count); }
1078
ecb_inline ecb_const uint16_t ecb_rotr16 (uint16_t x, unsigned int count) { return (x << (16 - count)) | (x >> count); }
1079
ecb_inline ecb_const uint32_t ecb_rotl32 (uint32_t x, unsigned int count) { return (x >> (32 - count)) | (x << count); }
1080
ecb_inline ecb_const uint32_t ecb_rotr32 (uint32_t x, unsigned int count) { return (x << (32 - count)) | (x >> count); }
1081
ecb_inline ecb_const uint64_t ecb_rotl64 (uint64_t x, unsigned int count) { return (x >> (64 - count)) | (x << count); }
1082
ecb_inline ecb_const uint64_t ecb_rotr64 (uint64_t x, unsigned int count) { return (x << (64 - count)) | (x >> count); }
1083
1084
#if ECB_GCC_VERSION(4,3) || (ECB_CLANG_BUILTIN(__builtin_bswap32) && ECB_CLANG_BUILTIN(__builtin_bswap64))
1085
#if ECB_GCC_VERSION(4,8) || ECB_CLANG_BUILTIN(__builtin_bswap16)
1086
#define ecb_bswap16(x) __builtin_bswap16 (x)
1087
#else
1088
#define ecb_bswap16(x) (__builtin_bswap32 (x) >> 16)
1089
#endif
1090
#define ecb_bswap32(x) __builtin_bswap32 (x)
1091
#define ecb_bswap64(x) __builtin_bswap64 (x)
1092
#elif _MSC_VER
1093
#include <stdlib.h>
1094
#define ecb_bswap16(x) ((uint16_t)_byteswap_ushort ((uint16_t)(x)))
1095
#define ecb_bswap32(x) ((uint32_t)_byteswap_ulong ((uint32_t)(x)))
1096
#define ecb_bswap64(x) ((uint64_t)_byteswap_uint64 ((uint64_t)(x)))
1097
#else
1098
ecb_function_ ecb_const uint16_t ecb_bswap16 (uint16_t x);
1099
ecb_function_ ecb_const uint16_t
1100
ecb_bswap16 (uint16_t x)
1101
{
1102
return ecb_rotl16 (x, 8);
1103
}
1104
1105
ecb_function_ ecb_const uint32_t ecb_bswap32 (uint32_t x);
1106
ecb_function_ ecb_const uint32_t
1107
ecb_bswap32 (uint32_t x)
1108
{
1109
return (((uint32_t)ecb_bswap16 (x)) << 16) | ecb_bswap16 (x >> 16);
1110
}
1111
1112
ecb_function_ ecb_const uint64_t ecb_bswap64 (uint64_t x);
1113
ecb_function_ ecb_const uint64_t
1114
ecb_bswap64 (uint64_t x)
1115
{
1116
return (((uint64_t)ecb_bswap32 (x)) << 32) | ecb_bswap32 (x >> 32);
1117
}
1118
#endif
1119
1120
#if ECB_GCC_VERSION(4,5) || ECB_CLANG_BUILTIN(__builtin_unreachable)
1121
#define ecb_unreachable() __builtin_unreachable ()
1122
#else
1123
/* this seems to work fine, but gcc always emits a warning for it :/ */
1124
ecb_inline ecb_noreturn void ecb_unreachable (void);
1125
ecb_inline ecb_noreturn void ecb_unreachable (void) { }
1126
#endif
1127
1128
/* try to tell the compiler that some condition is definitely true */
1129
#define ecb_assume(cond) if (!(cond)) ecb_unreachable (); else 0
1130
1131
ecb_inline ecb_const uint32_t ecb_byteorder_helper (void);
1132
ecb_inline ecb_const uint32_t
1133
ecb_byteorder_helper (void)
1134
{
1135
/* the union code still generates code under pressure in gcc, */
1136
/* but less than using pointers, and always seems to */
1137
/* successfully return a constant. */
1138
/* the reason why we have this horrible preprocessor mess */
1139
/* is to avoid it in all cases, at least on common architectures */
1140
/* or when using a recent enough gcc version (>= 4.6) */
1141
#if (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__) \
1142
|| ((__i386 || __i386__ || _M_IX86 || ECB_GCC_AMD64 || ECB_MSVC_AMD64) && !__VOS__)
1143
#define ECB_LITTLE_ENDIAN 1
1144
return 0x44332211;
1145
#elif (defined __BYTE_ORDER__ && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__) \
1146
|| ((__AARCH64EB__ || __MIPSEB__ || __ARMEB__) && !__VOS__)
1147
#define ECB_BIG_ENDIAN 1
1148
return 0x11223344;
1149
#else
1150
union
1151
{
1152
uint8_t c[4];
1153
uint32_t u;
1154
} u = { 0x11, 0x22, 0x33, 0x44 };
1155
return u.u;
1156
#endif
1157
}
1158
1159
ecb_inline ecb_const ecb_bool ecb_big_endian (void);
1160
ecb_inline ecb_const ecb_bool ecb_big_endian (void) { return ecb_byteorder_helper () == 0x11223344; }
1161
ecb_inline ecb_const ecb_bool ecb_little_endian (void);
1162
ecb_inline ecb_const ecb_bool ecb_little_endian (void) { return ecb_byteorder_helper () == 0x44332211; }
1163
1164
#if ECB_GCC_VERSION(3,0) || ECB_C99
1165
#define ecb_mod(m,n) ((m) % (n) + ((m) % (n) < 0 ? (n) : 0))
1166
#else
1167
#define ecb_mod(m,n) ((m) < 0 ? ((n) - 1 - ((-1 - (m)) % (n))) : ((m) % (n)))
1168
#endif
1169
1170
#if ECB_CPP
1171
template<typename T>
1172
static inline T ecb_div_rd (T val, T div)
1173
{
1174
return val < 0 ? - ((-val + div - 1) / div) : (val ) / div;
1175
}
1176
template<typename T>
1177
static inline T ecb_div_ru (T val, T div)
1178
{
1179
return val < 0 ? - ((-val ) / div) : (val + div - 1) / div;
1180
}
1181
#else
1182
#define ecb_div_rd(val,div) ((val) < 0 ? - ((-(val) + (div) - 1) / (div)) : ((val) ) / (div))
1183
#define ecb_div_ru(val,div) ((val) < 0 ? - ((-(val) ) / (div)) : ((val) + (div) - 1) / (div))
1184
#endif
1185
1186
#if ecb_cplusplus_does_not_suck
1187
/* does not work for local types (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2657.htm) */
1188
template<typename T, int N>
1189
static inline int ecb_array_length (const T (&arr)[N])
1190
{
1191
return N;
1192
}
1193
#else
1194
#define ecb_array_length(name) (sizeof (name) / sizeof (name [0]))
1195
#endif
1196
1197
ecb_function_ ecb_const uint32_t ecb_binary16_to_binary32 (uint32_t x);
1198
ecb_function_ ecb_const uint32_t
1199
ecb_binary16_to_binary32 (uint32_t x)
1200
{
1201
unsigned int s = (x & 0x8000) << (31 - 15);
1202
int e = (x >> 10) & 0x001f;
1203
unsigned int m = x & 0x03ff;
1204
1205
if (ecb_expect_false (e == 31))
1206
/* infinity or NaN */
1207
e = 255 - (127 - 15);
1208
else if (ecb_expect_false (!e))
1209
{
1210
if (ecb_expect_true (!m))
1211
/* zero, handled by code below by forcing e to 0 */
1212
e = 0 - (127 - 15);
1213
else
1214
{
1215
/* subnormal, renormalise */
1216
unsigned int s = 10 - ecb_ld32 (m);
1217
1218
m = (m << s) & 0x3ff; /* mask implicit bit */
1219
e -= s - 1;
1220
}
1221
}
1222
1223
/* e and m now are normalised, or zero, (or inf or nan) */
1224
e += 127 - 15;
1225
1226
return s | (e << 23) | (m << (23 - 10));
1227
}
1228
1229
ecb_function_ ecb_const uint16_t ecb_binary32_to_binary16 (uint32_t x);
1230
ecb_function_ ecb_const uint16_t
1231
ecb_binary32_to_binary16 (uint32_t x)
1232
{
1233
unsigned int s = (x >> 16) & 0x00008000; /* sign bit, the easy part */
1234
unsigned int e = ((x >> 23) & 0x000000ff) - (127 - 15); /* the desired exponent */
1235
unsigned int m = x & 0x007fffff;
1236
1237
x &= 0x7fffffff;
1238
1239
/* if it's within range of binary16 normals, use fast path */
1240
if (ecb_expect_true (0x38800000 <= x && x <= 0x477fefff))
1241
{
1242
/* mantissa round-to-even */
1243
m += 0x00000fff + ((m >> (23 - 10)) & 1);
1244
1245
/* handle overflow */
1246
if (ecb_expect_false (m >= 0x00800000))
1247
{
1248
m >>= 1;
1249
e += 1;
1250
}
1251
1252
return s | (e << 10) | (m >> (23 - 10));
1253
}
1254
1255
/* handle large numbers and infinity */
1256
if (ecb_expect_true (0x477fefff < x && x <= 0x7f800000))
1257
return s | 0x7c00;
1258
1259
/* handle zero, subnormals and small numbers */
1260
if (ecb_expect_true (x < 0x38800000))
1261
{
1262
/* zero */
1263
if (ecb_expect_true (!x))
1264
return s;
1265
1266
/* handle subnormals */
1267
1268
/* too small, will be zero */
1269
if (e < (14 - 24)) /* might not be sharp, but is good enough */
1270
return s;
1271
1272
m |= 0x00800000; /* make implicit bit explicit */
1273
1274
/* very tricky - we need to round to the nearest e (+10) bit value */
1275
{
1276
unsigned int bits = 14 - e;
1277
unsigned int half = (1 << (bits - 1)) - 1;
1278
unsigned int even = (m >> bits) & 1;
1279
1280
/* if this overflows, we will end up with a normalised number */
1281
m = (m + half + even) >> bits;
1282
}
1283
1284
return s | m;
1285
}
1286
1287
/* handle NaNs, preserve leftmost nan bits, but make sure we don't turn them into infinities */
1288
m >>= 13;
1289
1290
return s | 0x7c00 | m | !m;
1291
}
1292
1293
/*******************************************************************************/
1294
/* floating point stuff, can be disabled by defining ECB_NO_LIBM */
1295
1296
/* basically, everything uses "ieee pure-endian" floating point numbers */
1297
/* the only noteworthy exception is ancient armle, which uses order 43218765 */
1298
#if 0 \
1299
|| __i386 || __i386__ \
1300
|| ECB_GCC_AMD64 \
1301
|| __powerpc__ || __ppc__ || __powerpc64__ || __ppc64__ \
1302
|| defined __s390__ || defined __s390x__ \
1303
|| defined __mips__ \
1304
|| defined __alpha__ \
1305
|| defined __hppa__ \
1306
|| defined __ia64__ \
1307
|| defined __m68k__ \
1308
|| defined __m88k__ \
1309
|| defined __sh__ \
1310
|| defined _M_IX86 || defined ECB_MSVC_AMD64 || defined _M_IA64 \
1311
|| (defined __arm__ && (defined __ARM_EABI__ || defined __EABI__ || defined __VFP_FP__ || defined _WIN32_WCE || defined __ANDROID__)) \
1312
|| defined __aarch64__
1313
#define ECB_STDFP 1
1314
#include <string.h> /* for memcpy */
1315
#else
1316
#define ECB_STDFP 0
1317
#endif
1318
1319
#ifndef ECB_NO_LIBM
1320
1321
#include <math.h> /* for frexp*, ldexp*, INFINITY, NAN */
1322
1323
/* only the oldest of old doesn't have this one. solaris. */
1324
#ifdef INFINITY
1325
#define ECB_INFINITY INFINITY
1326
#else
1327
#define ECB_INFINITY HUGE_VAL
1328
#endif
1329
1330
#ifdef NAN
1331
#define ECB_NAN NAN
1332
#else
1333
#define ECB_NAN ECB_INFINITY
1334
#endif
1335
1336
#if ECB_C99 || _XOPEN_VERSION >= 600 || _POSIX_VERSION >= 200112L
1337
#define ecb_ldexpf(x,e) ldexpf ((x), (e))
1338
#define ecb_frexpf(x,e) frexpf ((x), (e))
1339
#else
1340
#define ecb_ldexpf(x,e) (float) ldexp ((double) (x), (e))
1341
#define ecb_frexpf(x,e) (float) frexp ((double) (x), (e))
1342
#endif
1343
1344
/* convert a float to ieee single/binary32 */
1345
ecb_function_ ecb_const uint32_t ecb_float_to_binary32 (float x);
1346
ecb_function_ ecb_const uint32_t
1347
ecb_float_to_binary32 (float x)
1348
{
1349
uint32_t r;
1350
1351
#if ECB_STDFP
1352
memcpy (&r, &x, 4);
1353
#else
1354
/* slow emulation, works for anything but -0 */
1355
uint32_t m;
1356
int e;
1357
1358
if (x == 0e0f ) return 0x00000000U;
1359
if (x > +3.40282346638528860e+38f) return 0x7f800000U;
1360
if (x < -3.40282346638528860e+38f) return 0xff800000U;
1361
if (x != x ) return 0x7fbfffffU;
1362
1363
m = ecb_frexpf (x, &e) * 0x1000000U;
1364
1365
r = m & 0x80000000U;
1366
1367
if (r)
1368
m = -m;
1369
1370
if (e <= -126)
1371
{
1372
m &= 0xffffffU;
1373
m >>= (-125 - e);
1374
e = -126;
1375
}
1376
1377
r |= (e + 126) << 23;
1378
r |= m & 0x7fffffU;
1379
#endif
1380
1381
return r;
1382
}
1383
1384
/* converts an ieee single/binary32 to a float */
1385
ecb_function_ ecb_const float ecb_binary32_to_float (uint32_t x);
1386
ecb_function_ ecb_const float
1387
ecb_binary32_to_float (uint32_t x)
1388
{
1389
float r;
1390
1391
#if ECB_STDFP
1392
memcpy (&r, &x, 4);
1393
#else
1394
/* emulation, only works for normals and subnormals and +0 */
1395
int neg = x >> 31;
1396
int e = (x >> 23) & 0xffU;
1397
1398
x &= 0x7fffffU;
1399
1400
if (e)
1401
x |= 0x800000U;
1402
else
1403
e = 1;
1404
1405
/* we distrust ldexpf a bit and do the 2**-24 scaling by an extra multiply */
1406
r = ecb_ldexpf (x * (0.5f / 0x800000U), e - 126);
1407
1408
r = neg ? -r : r;
1409
#endif
1410
1411
return r;
1412
}
1413
1414
/* convert a double to ieee double/binary64 */
1415
ecb_function_ ecb_const uint64_t ecb_double_to_binary64 (double x);
1416
ecb_function_ ecb_const uint64_t
1417
ecb_double_to_binary64 (double x)
1418
{
1419
uint64_t r;
1420
1421
#if ECB_STDFP
1422
memcpy (&r, &x, 8);
1423
#else
1424
/* slow emulation, works for anything but -0 */
1425
uint64_t m;
1426
int e;
1427
1428
if (x == 0e0 ) return 0x0000000000000000U;
1429
if (x > +1.79769313486231470e+308) return 0x7ff0000000000000U;
1430
if (x < -1.79769313486231470e+308) return 0xfff0000000000000U;
1431
if (x != x ) return 0X7ff7ffffffffffffU;
1432
1433
m = frexp (x, &e) * 0x20000000000000U;
1434
1435
r = m & 0x8000000000000000;;
1436
1437
if (r)
1438
m = -m;
1439
1440
if (e <= -1022)
1441
{
1442
m &= 0x1fffffffffffffU;
1443
m >>= (-1021 - e);
1444
e = -1022;
1445
}
1446
1447
r |= ((uint64_t)(e + 1022)) << 52;
1448
r |= m & 0xfffffffffffffU;
1449
#endif
1450
1451
return r;
1452
}
1453
1454
/* converts an ieee double/binary64 to a double */
1455
ecb_function_ ecb_const double ecb_binary64_to_double (uint64_t x);
1456
ecb_function_ ecb_const double
1457
ecb_binary64_to_double (uint64_t x)
1458
{
1459
double r;
1460
1461
#if ECB_STDFP
1462
memcpy (&r, &x, 8);
1463
#else
1464
/* emulation, only works for normals and subnormals and +0 */
1465
int neg = x >> 63;
1466
int e = (x >> 52) & 0x7ffU;
1467
1468
x &= 0xfffffffffffffU;
1469
1470
if (e)
1471
x |= 0x10000000000000U;
1472
else
1473
e = 1;
1474
1475
/* we distrust ldexp a bit and do the 2**-53 scaling by an extra multiply */
1476
r = ldexp (x * (0.5 / 0x10000000000000U), e - 1022);
1477
1478
r = neg ? -r : r;
1479
#endif
1480
1481
return r;
1482
}
1483
1484
/* convert a float to ieee half/binary16 */
1485
ecb_function_ ecb_const uint16_t ecb_float_to_binary16 (float x);
1486
ecb_function_ ecb_const uint16_t
1487
ecb_float_to_binary16 (float x)
1488
{
1489
return ecb_binary32_to_binary16 (ecb_float_to_binary32 (x));
1490
}
1491
1492
/* convert an ieee half/binary16 to float */
1493
ecb_function_ ecb_const float ecb_binary16_to_float (uint16_t x);
1494
ecb_function_ ecb_const float
1495
ecb_binary16_to_float (uint16_t x)
1496
{
1497
return ecb_binary32_to_float (ecb_binary16_to_binary32 (x));
1498
}
1499
1500
#endif
1501
1502
#endif
1503
1504
/* ECB.H END */
1505
1506
#if ECB_MEMORY_FENCE_NEEDS_PTHREADS
1507
/* if your architecture doesn't need memory fences, e.g. because it is
1508
* single-cpu/core, or if you use libev in a project that doesn't use libev
1509
* from multiple threads, then you can define ECB_AVOID_PTHREADS when compiling
1510
* libev, in which cases the memory fences become nops.
1511
* alternatively, you can remove this #error and link against libpthread,
1512
* which will then provide the memory fences.
1513
*/
1514
/*
1515
* krb5 change: per the comment below, we are allowing pthreads on platforms
1516
* which are too old to have better memory thead support, as is the case on
1517
* older Solaris versions.
1518
*/
1519
#if 0
1520
# error "memory fences not defined for your architecture, please report"
1521
#endif
1522
#endif
1523
1524
#ifndef ECB_MEMORY_FENCE
1525
# define ECB_MEMORY_FENCE do { } while (0)
1526
# define ECB_MEMORY_FENCE_ACQUIRE ECB_MEMORY_FENCE
1527
# define ECB_MEMORY_FENCE_RELEASE ECB_MEMORY_FENCE
1528
#endif
1529
1530
#define expect_false(cond) ecb_expect_false (cond)
1531
#define expect_true(cond) ecb_expect_true (cond)
1532
#define noinline ecb_noinline
1533
1534
#define inline_size ecb_inline
1535
1536
#if EV_FEATURE_CODE
1537
# define inline_speed ecb_inline
1538
#else
1539
# define inline_speed static noinline
1540
#endif
1541
1542
#define NUMPRI (EV_MAXPRI - EV_MINPRI + 1)
1543
1544
#if EV_MINPRI == EV_MAXPRI
1545
# define ABSPRI(w) (((W)w), 0)
1546
#else
1547
# define ABSPRI(w) (((W)w)->priority - EV_MINPRI)
1548
#endif
1549
1550
#define EMPTY /* required for microsofts broken pseudo-c compiler */
1551
#define EMPTY2(a,b) /* used to suppress some warnings */
1552
1553
typedef ev_watcher *W;
1554
typedef ev_watcher_list *WL;
1555
typedef ev_watcher_time *WT;
1556
1557
#define ev_active(w) ((W)(w))->active
1558
#define ev_at(w) ((WT)(w))->at
1559
1560
#if EV_USE_REALTIME
1561
/* sig_atomic_t is used to avoid per-thread variables or locking but still */
1562
/* giving it a reasonably high chance of working on typical architectures */
1563
static EV_ATOMIC_T have_realtime; /* did clock_gettime (CLOCK_REALTIME) work? */
1564
#endif
1565
1566
#if EV_USE_MONOTONIC
1567
static EV_ATOMIC_T have_monotonic; /* did clock_gettime (CLOCK_MONOTONIC) work? */
1568
#endif
1569
1570
#ifndef EV_FD_TO_WIN32_HANDLE
1571
# define EV_FD_TO_WIN32_HANDLE(fd) _get_osfhandle (fd)
1572
#endif
1573
#ifndef EV_WIN32_HANDLE_TO_FD
1574
# define EV_WIN32_HANDLE_TO_FD(handle) _open_osfhandle (handle, 0)
1575
#endif
1576
#ifndef EV_WIN32_CLOSE_FD
1577
# define EV_WIN32_CLOSE_FD(fd) close (fd)
1578
#endif
1579
1580
#ifdef _WIN32
1581
# include "ev_win32.c"
1582
#endif
1583
1584
/*****************************************************************************/
1585
1586
/* define a suitable floor function (only used by periodics atm) */
1587
1588
#if EV_USE_FLOOR
1589
# include <math.h>
1590
# define ev_floor(v) floor (v)
1591
#else
1592
1593
#include <float.h>
1594
1595
/* a floor() replacement function, should be independent of ev_tstamp type */
1596
static ev_tstamp noinline
1597
ev_floor (ev_tstamp v)
1598
{
1599
/* the choice of shift factor is not terribly important */
1600
#if FLT_RADIX != 2 /* assume FLT_RADIX == 10 */
1601
const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 10000000000000000000. : 1000000000.;
1602
#else
1603
const ev_tstamp shift = sizeof (unsigned long) >= 8 ? 18446744073709551616. : 4294967296.;
1604
#endif
1605
1606
/* argument too large for an unsigned long? */
1607
if (expect_false (v >= shift))
1608
{
1609
ev_tstamp f;
1610
1611
if (v == v - 1.)
1612
return v; /* very large number */
1613
1614
f = shift * ev_floor (v * (1. / shift));
1615
return f + ev_floor (v - f);
1616
}
1617
1618
/* special treatment for negative args? */
1619
if (expect_false (v < 0.))
1620
{
1621
ev_tstamp f = -ev_floor (-v);
1622
1623
return f - (f == v ? 0 : 1);
1624
}
1625
1626
/* fits into an unsigned long */
1627
return (unsigned long)v;
1628
}
1629
1630
#endif
1631
1632
/*****************************************************************************/
1633
1634
#ifdef __linux
1635
# include <sys/utsname.h>
1636
#endif
1637
1638
static unsigned int noinline ecb_cold
1639
ev_linux_version (void)
1640
{
1641
#ifdef __linux
1642
unsigned int v = 0;
1643
struct utsname buf;
1644
int i;
1645
char *p = buf.release;
1646
1647
if (uname (&buf))
1648
return 0;
1649
1650
for (i = 3+1; --i; )
1651
{
1652
unsigned int c = 0;
1653
1654
for (;;)
1655
{
1656
if (*p >= '0' && *p <= '9')
1657
c = c * 10 + *p++ - '0';
1658
else
1659
{
1660
p += *p == '.';
1661
break;
1662
}
1663
}
1664
1665
v = (v << 8) | c;
1666
}
1667
1668
return v;
1669
#else
1670
return 0;
1671
#endif
1672
}
1673
1674
/*****************************************************************************/
1675
1676
#if EV_AVOID_STDIO
1677
static void noinline ecb_cold
1678
ev_printerr (const char *msg)
1679
{
1680
write (STDERR_FILENO, msg, strlen (msg));
1681
}
1682
#endif
1683
1684
static void (*syserr_cb)(const char *msg) EV_THROW;
1685
1686
void ecb_cold
1687
ev_set_syserr_cb (void (*cb)(const char *msg) EV_THROW) EV_THROW
1688
{
1689
syserr_cb = cb;
1690
}
1691
1692
static void noinline ecb_cold
1693
ev_syserr (const char *msg)
1694
{
1695
if (!msg)
1696
msg = "(libev) system error";
1697
1698
if (syserr_cb)
1699
syserr_cb (msg);
1700
else
1701
{
1702
#if EV_AVOID_STDIO
1703
ev_printerr (msg);
1704
ev_printerr (": ");
1705
ev_printerr (strerror (errno));
1706
ev_printerr ("\n");
1707
#else
1708
perror (msg);
1709
#endif
1710
abort ();
1711
}
1712
}
1713
1714
static void *
1715
ev_realloc_emul (void *ptr, long size) EV_THROW
1716
{
1717
/* some systems, notably openbsd and darwin, fail to properly
1718
* implement realloc (x, 0) (as required by both ansi c-89 and
1719
* the single unix specification, so work around them here.
1720
* recently, also (at least) fedora and debian started breaking it,
1721
* despite documenting it otherwise.
1722
*/
1723
1724
if (size)
1725
return realloc (ptr, size);
1726
1727
free (ptr);
1728
return 0;
1729
}
1730
1731
static void *(*alloc)(void *ptr, long size) EV_THROW = ev_realloc_emul;
1732
1733
void ecb_cold
1734
ev_set_allocator (void *(*cb)(void *ptr, long size) EV_THROW) EV_THROW
1735
{
1736
alloc = cb;
1737
}
1738
1739
inline_speed void *
1740
ev_realloc (void *ptr, long size)
1741
{
1742
ptr = alloc (ptr, size);
1743
1744
if (!ptr && size)
1745
{
1746
#if EV_AVOID_STDIO
1747
ev_printerr ("(libev) memory allocation failed, aborting.\n");
1748
#else
1749
fprintf (stderr, "(libev) cannot allocate %ld bytes, aborting.", size);
1750
#endif
1751
abort ();
1752
}
1753
1754
return ptr;
1755
}
1756
1757
#define ev_malloc(size) ev_realloc (0, (size))
1758
#define ev_free(ptr) ev_realloc ((ptr), 0)
1759
1760
/*****************************************************************************/
1761
1762
/* set in reify when reification needed */
1763
#define EV_ANFD_REIFY 1
1764
1765
/* file descriptor info structure */
1766
typedef struct
1767
{
1768
WL head;
1769
unsigned char events; /* the events watched for */
1770
unsigned char reify; /* flag set when this ANFD needs reification (EV_ANFD_REIFY, EV__IOFDSET) */
1771
unsigned char emask; /* the epoll backend stores the actual kernel mask in here */
1772
unsigned char unused;
1773
#if EV_USE_EPOLL
1774
unsigned int egen; /* generation counter to counter epoll bugs */
1775
#endif
1776
#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
1777
SOCKET handle;
1778
#endif
1779
#if EV_USE_IOCP
1780
OVERLAPPED or, ow;
1781
#endif
1782
} ANFD;
1783
1784
/* stores the pending event set for a given watcher */
1785
typedef struct
1786
{
1787
W w;
1788
int events; /* the pending event set for the given watcher */
1789
} ANPENDING;
1790
1791
#if EV_USE_INOTIFY
1792
/* hash table entry per inotify-id */
1793
typedef struct
1794
{
1795
WL head;
1796
} ANFS;
1797
#endif
1798
1799
/* Heap Entry */
1800
#if EV_HEAP_CACHE_AT
1801
/* a heap element */
1802
typedef struct {
1803
ev_tstamp at;
1804
WT w;
1805
} ANHE;
1806
1807
#define ANHE_w(he) (he).w /* access watcher, read-write */
1808
#define ANHE_at(he) (he).at /* access cached at, read-only */
1809
#define ANHE_at_cache(he) (he).at = (he).w->at /* update at from watcher */
1810
#else
1811
/* a heap element */
1812
typedef WT ANHE;
1813
1814
#define ANHE_w(he) (he)
1815
#define ANHE_at(he) (he)->at
1816
#define ANHE_at_cache(he)
1817
#endif
1818
1819
#if EV_MULTIPLICITY
1820
1821
struct ev_loop
1822
{
1823
ev_tstamp ev_rt_now;
1824
#define ev_rt_now ((loop)->ev_rt_now)
1825
#define VAR(name,decl) decl;
1826
#include "ev_vars.h"
1827
#undef VAR
1828
};
1829
#include "ev_wrap.h"
1830
1831
static struct ev_loop default_loop_struct;
1832
EV_API_DECL struct ev_loop *ev_default_loop_ptr = 0; /* needs to be initialised to make it a definition despite extern */
1833
1834
#else
1835
1836
EV_API_DECL ev_tstamp ev_rt_now = 0; /* needs to be initialised to make it a definition despite extern */
1837
#define VAR(name,decl) static decl;
1838
#include "ev_vars.h"
1839
#undef VAR
1840
1841
static int ev_default_loop_ptr;
1842
1843
#endif
1844
1845
#if EV_FEATURE_API
1846
# define EV_RELEASE_CB if (expect_false (release_cb)) release_cb (EV_A)
1847
# define EV_ACQUIRE_CB if (expect_false (acquire_cb)) acquire_cb (EV_A)
1848
# define EV_INVOKE_PENDING invoke_cb (EV_A)
1849
#else
1850
# define EV_RELEASE_CB (void)0
1851
# define EV_ACQUIRE_CB (void)0
1852
# define EV_INVOKE_PENDING ev_invoke_pending (EV_A)
1853
#endif
1854
1855
#define EVBREAK_RECURSE 0x80
1856
1857
/*****************************************************************************/
1858
1859
#ifndef EV_HAVE_EV_TIME
1860
ev_tstamp
1861
ev_time (void) EV_THROW
1862
{
1863
#if EV_USE_REALTIME
1864
if (expect_true (have_realtime))
1865
{
1866
struct timespec ts;
1867
clock_gettime (CLOCK_REALTIME, &ts);
1868
return ts.tv_sec + ts.tv_nsec * 1e-9;
1869
}
1870
#endif
1871
1872
struct timeval tv;
1873
gettimeofday (&tv, 0);
1874
return tv.tv_sec + tv.tv_usec * 1e-6;
1875
}
1876
#endif
1877
1878
inline_size ev_tstamp
1879
get_clock (void)
1880
{
1881
#if EV_USE_MONOTONIC
1882
if (expect_true (have_monotonic))
1883
{
1884
struct timespec ts;
1885
clock_gettime (CLOCK_MONOTONIC, &ts);
1886
return ts.tv_sec + ts.tv_nsec * 1e-9;
1887
}
1888
#endif
1889
1890
return ev_time ();
1891
}
1892
1893
#if EV_MULTIPLICITY
1894
ev_tstamp
1895
ev_now (EV_P) EV_THROW
1896
{
1897
return ev_rt_now;
1898
}
1899
#endif
1900
1901
void
1902
ev_sleep (ev_tstamp delay) EV_THROW
1903
{
1904
if (delay > 0.)
1905
{
1906
#if EV_USE_NANOSLEEP
1907
struct timespec ts;
1908
1909
EV_TS_SET (ts, delay);
1910
nanosleep (&ts, 0);
1911
#elif defined _WIN32
1912
Sleep ((unsigned long)(delay * 1e3));
1913
#else
1914
struct timeval tv;
1915
1916
/* here we rely on sys/time.h + sys/types.h + unistd.h providing select */
1917
/* something not guaranteed by newer posix versions, but guaranteed */
1918
/* by older ones */
1919
EV_TV_SET (tv, delay);
1920
select (0, 0, 0, 0, &tv);
1921
#endif
1922
}
1923
}
1924
1925
/*****************************************************************************/
1926
1927
#define MALLOC_ROUND 4096 /* prefer to allocate in chunks of this size, must be 2**n and >> 4 longs */
1928
1929
/* find a suitable new size for the given array, */
1930
/* hopefully by rounding to a nice-to-malloc size */
1931
inline_size int
1932
array_nextsize (int elem, int cur, int cnt)
1933
{
1934
int ncur = cur + 1;
1935
1936
do
1937
ncur <<= 1;
1938
while (cnt > ncur);
1939
1940
/* if size is large, round to MALLOC_ROUND - 4 * longs to accommodate malloc overhead */
1941
if (elem * ncur > MALLOC_ROUND - sizeof (void *) * 4)
1942
{
1943
ncur *= elem;
1944
ncur = (ncur + elem + (MALLOC_ROUND - 1) + sizeof (void *) * 4) & ~(MALLOC_ROUND - 1);
1945
ncur = ncur - sizeof (void *) * 4;
1946
ncur /= elem;
1947
}
1948
1949
return ncur;
1950
}
1951
1952
static void * noinline ecb_cold
1953
array_realloc (int elem, void *base, int *cur, int cnt)
1954
{
1955
*cur = array_nextsize (elem, *cur, cnt);
1956
return ev_realloc (base, elem * *cur);
1957
}
1958
1959
#define array_init_zero(base,count) \
1960
memset ((void *)(base), 0, sizeof (*(base)) * (count))
1961
1962
#define array_needsize(type,base,cur,cnt,init) \
1963
if (expect_false ((cnt) > (cur))) \
1964
{ \
1965
int ecb_unused ocur_ = (cur); \
1966
(base) = (type *)array_realloc \
1967
(sizeof (type), (base), &(cur), (cnt)); \
1968
init ((base) + (ocur_), (cur) - ocur_); \
1969
}
1970
1971
#if 0
1972
#define array_slim(type,stem) \
1973
if (stem ## max < array_roundsize (stem ## cnt >> 2)) \
1974
{ \
1975
stem ## max = array_roundsize (stem ## cnt >> 1); \
1976
base = (type *)ev_realloc (base, sizeof (type) * (stem ## max));\
1977
fprintf (stderr, "slimmed down " # stem " to %d\n", stem ## max);/*D*/\
1978
}
1979
#endif
1980
1981
#define array_free(stem, idx) \
1982
ev_free (stem ## s idx); stem ## cnt idx = stem ## max idx = 0; stem ## s idx = 0
1983
1984
/*****************************************************************************/
1985
1986
/* dummy callback for pending events */
1987
static void noinline
1988
pendingcb (EV_P_ ev_prepare *w, int revents)
1989
{
1990
}
1991
1992
void noinline
1993
ev_feed_event (EV_P_ void *w, int revents) EV_THROW
1994
{
1995
W w_ = (W)w;
1996
int pri = ABSPRI (w_);
1997
1998
if (expect_false (w_->pending))
1999
pendings [pri][w_->pending - 1].events |= revents;
2000
else
2001
{
2002
w_->pending = ++pendingcnt [pri];
2003
array_needsize (ANPENDING, pendings [pri], pendingmax [pri], w_->pending, EMPTY2);
2004
pendings [pri][w_->pending - 1].w = w_;
2005
pendings [pri][w_->pending - 1].events = revents;
2006
}
2007
2008
pendingpri = NUMPRI - 1;
2009
}
2010
2011
inline_speed void
2012
feed_reverse (EV_P_ W w)
2013
{
2014
array_needsize (W, rfeeds, rfeedmax, rfeedcnt + 1, EMPTY2);
2015
rfeeds [rfeedcnt++] = w;
2016
}
2017
2018
inline_size void
2019
feed_reverse_done (EV_P_ int revents)
2020
{
2021
do
2022
ev_feed_event (EV_A_ rfeeds [--rfeedcnt], revents);
2023
while (rfeedcnt);
2024
}
2025
2026
inline_speed void
2027
queue_events (EV_P_ W *events, int eventcnt, int type)
2028
{
2029
int i;
2030
2031
for (i = 0; i < eventcnt; ++i)
2032
ev_feed_event (EV_A_ events [i], type);
2033
}
2034
2035
/*****************************************************************************/
2036
2037
inline_speed void
2038
fd_event_nocheck (EV_P_ int fd, int revents)
2039
{
2040
ANFD *anfd = anfds + fd;
2041
ev_io *w;
2042
2043
for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
2044
{
2045
int ev = w->events & revents;
2046
2047
if (ev)
2048
ev_feed_event (EV_A_ (W)w, ev);
2049
}
2050
}
2051
2052
/* do not submit kernel events for fds that have reify set */
2053
/* because that means they changed while we were polling for new events */
2054
inline_speed void
2055
fd_event (EV_P_ int fd, int revents)
2056
{
2057
ANFD *anfd = anfds + fd;
2058
2059
if (expect_true (!anfd->reify))
2060
fd_event_nocheck (EV_A_ fd, revents);
2061
}
2062
2063
void
2064
ev_feed_fd_event (EV_P_ int fd, int revents) EV_THROW
2065
{
2066
if (fd >= 0 && fd < anfdmax)
2067
fd_event_nocheck (EV_A_ fd, revents);
2068
}
2069
2070
/* make sure the external fd watch events are in-sync */
2071
/* with the kernel/libev internal state */
2072
inline_size void
2073
fd_reify (EV_P)
2074
{
2075
int i;
2076
2077
#if EV_SELECT_IS_WINSOCKET || EV_USE_IOCP
2078
for (i = 0; i < fdchangecnt; ++i)
2079
{
2080
int fd = fdchanges [i];
2081
ANFD *anfd = anfds + fd;
2082
2083
if (anfd->reify & EV__IOFDSET && anfd->head)
2084
{
2085
SOCKET handle = EV_FD_TO_WIN32_HANDLE (fd);
2086
2087
if (handle != anfd->handle)
2088
{
2089
unsigned long arg;
2090
2091
assert (("libev: only socket fds supported in this configuration", ioctlsocket (handle, FIONREAD, &arg) == 0));
2092
2093
/* handle changed, but fd didn't - we need to do it in two steps */
2094
backend_modify (EV_A_ fd, anfd->events, 0);
2095
anfd->events = 0;
2096
anfd->handle = handle;
2097
}
2098
}
2099
}
2100
#endif
2101
2102
for (i = 0; i < fdchangecnt; ++i)
2103
{
2104
int fd = fdchanges [i];
2105
ANFD *anfd = anfds + fd;
2106
ev_io *w;
2107
2108
unsigned char o_events = anfd->events;
2109
unsigned char o_reify = anfd->reify;
2110
2111
anfd->reify = 0;
2112
2113
/*if (expect_true (o_reify & EV_ANFD_REIFY)) probably a deoptimisation */
2114
{
2115
anfd->events = 0;
2116
2117
for (w = (ev_io *)anfd->head; w; w = (ev_io *)((WL)w)->next)
2118
anfd->events |= (unsigned char)w->events;
2119
2120
if (o_events != anfd->events)
2121
o_reify = EV__IOFDSET; /* actually |= */
2122
}
2123
2124
if (o_reify & EV__IOFDSET)
2125
backend_modify (EV_A_ fd, o_events, anfd->events);
2126
}
2127
2128
fdchangecnt = 0;
2129
}
2130
2131
/* something about the given fd changed */
2132
inline_size void
2133
fd_change (EV_P_ int fd, int flags)
2134
{
2135
unsigned char reify = anfds [fd].reify;
2136
anfds [fd].reify |= flags;
2137
2138
if (expect_true (!reify))
2139
{
2140
++fdchangecnt;
2141
array_needsize (int, fdchanges, fdchangemax, fdchangecnt, EMPTY2);
2142
fdchanges [fdchangecnt - 1] = fd;
2143
}
2144
}
2145
2146
/* the given fd is invalid/unusable, so make sure it doesn't hurt us anymore */
2147
inline_speed void ecb_cold
2148
fd_kill (EV_P_ int fd)
2149
{
2150
ev_io *w;
2151
2152
while ((w = (ev_io *)anfds [fd].head))
2153
{
2154
ev_io_stop (EV_A_ w);
2155
ev_feed_event (EV_A_ (W)w, EV_ERROR | EV_READ | EV_WRITE);
2156
}
2157
}
2158
2159
/* check whether the given fd is actually valid, for error recovery */
2160
inline_size int ecb_cold
2161
fd_valid (int fd)
2162
{
2163
#ifdef _WIN32
2164
return EV_FD_TO_WIN32_HANDLE (fd) != -1;
2165
#else
2166
return fcntl (fd, F_GETFD) != -1;
2167
#endif
2168
}
2169
2170
/* called on EBADF to verify fds */
2171
static void noinline ecb_cold
2172
fd_ebadf (EV_P)
2173
{
2174
int fd;
2175
2176
for (fd = 0; fd < anfdmax; ++fd)
2177
if (anfds [fd].events)
2178
if (!fd_valid (fd) && errno == EBADF)
2179
fd_kill (EV_A_ fd);
2180
}
2181
2182
/* called on ENOMEM in select/poll to kill some fds and retry */
2183
static void noinline ecb_cold
2184
fd_enomem (EV_P)
2185
{
2186
int fd;
2187
2188
for (fd = anfdmax; fd--; )
2189
if (anfds [fd].events)
2190
{
2191
fd_kill (EV_A_ fd);
2192
break;
2193
}
2194
}
2195
2196
/* usually called after fork if backend needs to re-arm all fds from scratch */
2197
static void noinline
2198
fd_rearm_all (EV_P)
2199
{
2200
int fd;
2201
2202
for (fd = 0; fd < anfdmax; ++fd)
2203
if (anfds [fd].events)
2204
{
2205
anfds [fd].events = 0;
2206
anfds [fd].emask = 0;
2207
fd_change (EV_A_ fd, EV__IOFDSET | EV_ANFD_REIFY);
2208
}
2209
}
2210
2211
/* used to prepare libev internal fd's */
2212
/* this is not fork-safe */
2213
inline_speed void
2214
fd_intern (int fd)
2215
{
2216
#ifdef _WIN32
2217
unsigned long arg = 1;
2218
ioctlsocket (EV_FD_TO_WIN32_HANDLE (fd), FIONBIO, &arg);
2219
#else
2220
fcntl (fd, F_SETFD, FD_CLOEXEC);
2221
fcntl (fd, F_SETFL, O_NONBLOCK);
2222
#endif
2223
}
2224
2225
/*****************************************************************************/
2226
2227
/*
2228
* the heap functions want a real array index. array index 0 is guaranteed to not
2229
* be in-use at any time. the first heap entry is at array [HEAP0]. DHEAP gives
2230
* the branching factor of the d-tree.
2231
*/
2232
2233
/*
2234
* at the moment we allow libev the luxury of two heaps,
2235
* a small-code-size 2-heap one and a ~1.5kb larger 4-heap
2236
* which is more cache-efficient.
2237
* the difference is about 5% with 50000+ watchers.
2238
*/
2239
#if EV_USE_4HEAP
2240
2241
#define DHEAP 4
2242
#define HEAP0 (DHEAP - 1) /* index of first element in heap */
2243
#define HPARENT(k) ((((k) - HEAP0 - 1) / DHEAP) + HEAP0)
2244
#define UPHEAP_DONE(p,k) ((p) == (k))
2245
2246
/* away from the root */
2247
inline_speed void
2248
downheap (ANHE *heap, int N, int k)
2249
{
2250
ANHE he = heap [k];
2251
ANHE *E = heap + N + HEAP0;
2252
2253
for (;;)
2254
{
2255
ev_tstamp minat;
2256
ANHE *minpos;
2257
ANHE *pos = heap + DHEAP * (k - HEAP0) + HEAP0 + 1;
2258
2259
/* find minimum child */
2260
if (expect_true (pos + DHEAP - 1 < E))
2261
{
2262
/* fast path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
2263
if ( ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
2264
if ( ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
2265
if ( ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
2266
}
2267
else if (pos < E)
2268
{
2269
/* slow path */ (minpos = pos + 0), (minat = ANHE_at (*minpos));
2270
if (pos + 1 < E && ANHE_at (pos [1]) < minat) (minpos = pos + 1), (minat = ANHE_at (*minpos));
2271
if (pos + 2 < E && ANHE_at (pos [2]) < minat) (minpos = pos + 2), (minat = ANHE_at (*minpos));
2272
if (pos + 3 < E && ANHE_at (pos [3]) < minat) (minpos = pos + 3), (minat = ANHE_at (*minpos));
2273
}
2274
else
2275
break;
2276
2277
if (ANHE_at (he) <= minat)
2278
break;
2279
2280
heap [k] = *minpos;
2281
ev_active (ANHE_w (*minpos)) = k;
2282
2283
k = minpos - heap;
2284
}
2285
2286
heap [k] = he;
2287
ev_active (ANHE_w (he)) = k;
2288
}
2289
2290
#else /* 4HEAP */
2291
2292
#define HEAP0 1
2293
#define HPARENT(k) ((k) >> 1)
2294
#define UPHEAP_DONE(p,k) (!(p))
2295
2296
/* away from the root */
2297
inline_speed void
2298
downheap (ANHE *heap, int N, int k)
2299
{
2300
ANHE he = heap [k];
2301
2302
for (;;)
2303
{
2304
int c = k << 1;
2305
2306
if (c >= N + HEAP0)
2307
break;
2308
2309
c += c + 1 < N + HEAP0 && ANHE_at (heap [c]) > ANHE_at (heap [c + 1])
2310
? 1 : 0;
2311
2312
if (ANHE_at (he) <= ANHE_at (heap [c]))
2313
break;
2314
2315
heap [k] = heap [c];
2316
ev_active (ANHE_w (heap [k])) = k;
2317
2318
k = c;
2319
}
2320
2321
heap [k] = he;
2322
ev_active (ANHE_w (he)) = k;
2323
}
2324
#endif
2325
2326
/* towards the root */
2327
inline_speed void
2328
upheap (ANHE *heap, int k)
2329
{
2330
ANHE he = heap [k];
2331
2332
for (;;)
2333
{
2334
int p = HPARENT (k);
2335
2336
if (UPHEAP_DONE (p, k) || ANHE_at (heap [p]) <= ANHE_at (he))
2337
break;
2338
2339
heap [k] = heap [p];
2340
ev_active (ANHE_w (heap [k])) = k;
2341
k = p;
2342
}
2343
2344
heap [k] = he;
2345
ev_active (ANHE_w (he)) = k;
2346
}
2347
2348
/* move an element suitably so it is in a correct place */
2349
inline_size void
2350
adjustheap (ANHE *heap, int N, int k)
2351
{
2352
if (k > HEAP0 && ANHE_at (heap [k]) <= ANHE_at (heap [HPARENT (k)]))
2353
upheap (heap, k);
2354
else
2355
downheap (heap, N, k);
2356
}
2357
2358
/* rebuild the heap: this function is used only once and executed rarely */
2359
inline_size void
2360
reheap (ANHE *heap, int N)
2361
{
2362
int i;
2363
2364
/* we don't use floyds algorithm, upheap is simpler and is more cache-efficient */
2365
/* also, this is easy to implement and correct for both 2-heaps and 4-heaps */
2366
for (i = 0; i < N; ++i)
2367
upheap (heap, i + HEAP0);
2368
}
2369
2370
/*****************************************************************************/
2371
2372
/* associate signal watchers to a signal signal */
2373
typedef struct
2374
{
2375
EV_ATOMIC_T pending;
2376
#if EV_MULTIPLICITY
2377
EV_P;
2378
#endif
2379
WL head;
2380
} ANSIG;
2381
2382
static ANSIG signals [EV_NSIG - 1];
2383
2384
/*****************************************************************************/
2385
2386
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
2387
2388
static void noinline ecb_cold
2389
evpipe_init (EV_P)
2390
{
2391
if (!ev_is_active (&pipe_w))
2392
{
2393
int fds [2];
2394
2395
# if EV_USE_EVENTFD
2396
fds [0] = -1;
2397
fds [1] = eventfd (0, EFD_NONBLOCK | EFD_CLOEXEC);
2398
if (fds [1] < 0 && errno == EINVAL)
2399
fds [1] = eventfd (0, 0);
2400
2401
if (fds [1] < 0)
2402
# endif
2403
{
2404
while (pipe (fds))
2405
ev_syserr ("(libev) error creating signal/async pipe");
2406
2407
fd_intern (fds [0]);
2408
}
2409
2410
evpipe [0] = fds [0];
2411
2412
if (evpipe [1] < 0)
2413
evpipe [1] = fds [1]; /* first call, set write fd */
2414
else
2415
{
2416
/* on subsequent calls, do not change evpipe [1] */
2417
/* so that evpipe_write can always rely on its value. */
2418
/* this branch does not do anything sensible on windows, */
2419
/* so must not be executed on windows */
2420
2421
dup2 (fds [1], evpipe [1]);
2422
close (fds [1]);
2423
}
2424
2425
fd_intern (evpipe [1]);
2426
2427
ev_io_set (&pipe_w, evpipe [0] < 0 ? evpipe [1] : evpipe [0], EV_READ);
2428
ev_io_start (EV_A_ &pipe_w);
2429
ev_unref (EV_A); /* watcher should not keep loop alive */
2430
}
2431
}
2432
2433
inline_speed void
2434
evpipe_write (EV_P_ EV_ATOMIC_T *flag)
2435
{
2436
ECB_MEMORY_FENCE; /* push out the write before this function was called, acquire flag */
2437
2438
if (expect_true (*flag))
2439
return;
2440
2441
*flag = 1;
2442
ECB_MEMORY_FENCE_RELEASE; /* make sure flag is visible before the wakeup */
2443
2444
pipe_write_skipped = 1;
2445
2446
ECB_MEMORY_FENCE; /* make sure pipe_write_skipped is visible before we check pipe_write_wanted */
2447
2448
if (pipe_write_wanted)
2449
{
2450
int old_errno;
2451
2452
pipe_write_skipped = 0;
2453
ECB_MEMORY_FENCE_RELEASE;
2454
2455
old_errno = errno; /* save errno because write will clobber it */
2456
2457
#if EV_USE_EVENTFD
2458
if (evpipe [0] < 0)
2459
{
2460
uint64_t counter = 1;
2461
write (evpipe [1], &counter, sizeof (uint64_t));
2462
}
2463
else
2464
#endif
2465
{
2466
#ifdef _WIN32
2467
WSABUF buf;
2468
DWORD sent;
2469
buf.buf = &buf;
2470
buf.len = 1;
2471
WSASend (EV_FD_TO_WIN32_HANDLE (evpipe [1]), &buf, 1, &sent, 0, 0, 0);
2472
#else
2473
write (evpipe [1], &(evpipe [1]), 1);
2474
#endif
2475
}
2476
2477
errno = old_errno;
2478
}
2479
}
2480
2481
/* called whenever the libev signal pipe */
2482
/* got some events (signal, async) */
2483
static void
2484
pipecb (EV_P_ ev_io *iow, int revents)
2485
{
2486
int i;
2487
2488
if (revents & EV_READ)
2489
{
2490
#if EV_USE_EVENTFD
2491
if (evpipe [0] < 0)
2492
{
2493
uint64_t counter;
2494
read (evpipe [1], &counter, sizeof (uint64_t));
2495
}
2496
else
2497
#endif
2498
{
2499
char dummy[4];
2500
#ifdef _WIN32
2501
WSABUF buf;
2502
DWORD recvd;
2503
DWORD flags = 0;
2504
buf.buf = dummy;
2505
buf.len = sizeof (dummy);
2506
WSARecv (EV_FD_TO_WIN32_HANDLE (evpipe [0]), &buf, 1, &recvd, &flags, 0, 0);
2507
#else
2508
read (evpipe [0], &dummy, sizeof (dummy));
2509
#endif
2510
}
2511
}
2512
2513
pipe_write_skipped = 0;
2514
2515
ECB_MEMORY_FENCE; /* push out skipped, acquire flags */
2516
2517
#if EV_SIGNAL_ENABLE
2518
if (sig_pending)
2519
{
2520
sig_pending = 0;
2521
2522
ECB_MEMORY_FENCE;
2523
2524
for (i = EV_NSIG - 1; i--; )
2525
if (expect_false (signals [i].pending))
2526
ev_feed_signal_event (EV_A_ i + 1);
2527
}
2528
#endif
2529
2530
#if EV_ASYNC_ENABLE
2531
if (async_pending)
2532
{
2533
async_pending = 0;
2534
2535
ECB_MEMORY_FENCE;
2536
2537
for (i = asynccnt; i--; )
2538
if (asyncs [i]->sent)
2539
{
2540
asyncs [i]->sent = 0;
2541
ECB_MEMORY_FENCE_RELEASE;
2542
ev_feed_event (EV_A_ asyncs [i], EV_ASYNC);
2543
}
2544
}
2545
#endif
2546
}
2547
2548
/*****************************************************************************/
2549
2550
void
2551
ev_feed_signal (int signum) EV_THROW
2552
{
2553
#if EV_MULTIPLICITY
2554
EV_P;
2555
ECB_MEMORY_FENCE_ACQUIRE;
2556
EV_A = signals [signum - 1].loop;
2557
2558
if (!EV_A)
2559
return;
2560
#endif
2561
2562
signals [signum - 1].pending = 1;
2563
evpipe_write (EV_A_ &sig_pending);
2564
}
2565
2566
static void
2567
ev_sighandler (int signum)
2568
{
2569
#ifdef _WIN32
2570
signal (signum, ev_sighandler);
2571
#endif
2572
2573
ev_feed_signal (signum);
2574
}
2575
2576
void noinline
2577
ev_feed_signal_event (EV_P_ int signum) EV_THROW
2578
{
2579
WL w;
2580
2581
if (expect_false (signum <= 0 || signum >= EV_NSIG))
2582
return;
2583
2584
--signum;
2585
2586
#if EV_MULTIPLICITY
2587
/* it is permissible to try to feed a signal to the wrong loop */
2588
/* or, likely more useful, feeding a signal nobody is waiting for */
2589
2590
if (expect_false (signals [signum].loop != EV_A))
2591
return;
2592
#endif
2593
2594
signals [signum].pending = 0;
2595
ECB_MEMORY_FENCE_RELEASE;
2596
2597
for (w = signals [signum].head; w; w = w->next)
2598
ev_feed_event (EV_A_ (W)w, EV_SIGNAL);
2599
}
2600
2601
#if EV_USE_SIGNALFD
2602
static void
2603
sigfdcb (EV_P_ ev_io *iow, int revents)
2604
{
2605
struct signalfd_siginfo si[2], *sip; /* these structs are big */
2606
2607
for (;;)
2608
{
2609
ssize_t res = read (sigfd, si, sizeof (si));
2610
2611
/* not ISO-C, as res might be -1, but works with SuS */
2612
for (sip = si; (char *)sip < (char *)si + res; ++sip)
2613
ev_feed_signal_event (EV_A_ sip->ssi_signo);
2614
2615
if (res < (ssize_t)sizeof (si))
2616
break;
2617
}
2618
}
2619
#endif
2620
2621
#endif
2622
2623
/*****************************************************************************/
2624
2625
#if EV_CHILD_ENABLE
2626
static WL childs [EV_PID_HASHSIZE];
2627
2628
static ev_signal childev;
2629
2630
#ifndef WIFCONTINUED
2631
# define WIFCONTINUED(status) 0
2632
#endif
2633
2634
/* handle a single child status event */
2635
inline_speed void
2636
child_reap (EV_P_ int chain, int pid, int status)
2637
{
2638
ev_child *w;
2639
int traced = WIFSTOPPED (status) || WIFCONTINUED (status);
2640
2641
for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
2642
{
2643
if ((w->pid == pid || !w->pid)
2644
&& (!traced || (w->flags & 1)))
2645
{
2646
ev_set_priority (w, EV_MAXPRI); /* need to do it *now*, this *must* be the same prio as the signal watcher itself */
2647
w->rpid = pid;
2648
w->rstatus = status;
2649
ev_feed_event (EV_A_ (W)w, EV_CHILD);
2650
}
2651
}
2652
}
2653
2654
#ifndef WCONTINUED
2655
# define WCONTINUED 0
2656
#endif
2657
2658
/* called on sigchld etc., calls waitpid */
2659
static void
2660
childcb (EV_P_ ev_signal *sw, int revents)
2661
{
2662
int pid, status;
2663
2664
/* some systems define WCONTINUED but then fail to support it (linux 2.4) */
2665
if (0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED | WCONTINUED)))
2666
if (!WCONTINUED
2667
|| errno != EINVAL
2668
|| 0 >= (pid = waitpid (-1, &status, WNOHANG | WUNTRACED)))
2669
return;
2670
2671
/* make sure we are called again until all children have been reaped */
2672
/* we need to do it this way so that the callback gets called before we continue */
2673
ev_feed_event (EV_A_ (W)sw, EV_SIGNAL);
2674
2675
child_reap (EV_A_ pid, pid, status);
2676
if ((EV_PID_HASHSIZE) > 1)
2677
child_reap (EV_A_ 0, pid, status); /* this might trigger a watcher twice, but feed_event catches that */
2678
}
2679
2680
#endif
2681
2682
/*****************************************************************************/
2683
2684
#if EV_USE_IOCP
2685
# include "ev_iocp.c"
2686
#endif
2687
#if EV_USE_PORT
2688
# include "ev_port.c"
2689
#endif
2690
#if EV_USE_KQUEUE
2691
# include "ev_kqueue.c"
2692
#endif
2693
#if EV_USE_EPOLL
2694
# include "ev_epoll.c"
2695
#endif
2696
#if EV_USE_POLL
2697
# include "ev_poll.c"
2698
#endif
2699
#if EV_USE_SELECT
2700
# include "ev_select.c"
2701
#endif
2702
2703
int ecb_cold
2704
ev_version_major (void) EV_THROW
2705
{
2706
return EV_VERSION_MAJOR;
2707
}
2708
2709
int ecb_cold
2710
ev_version_minor (void) EV_THROW
2711
{
2712
return EV_VERSION_MINOR;
2713
}
2714
2715
/* return true if we are running with elevated privileges and should ignore env variables */
2716
int inline_size ecb_cold
2717
enable_secure (void)
2718
{
2719
#ifdef _WIN32
2720
return 0;
2721
#else
2722
return getuid () != geteuid ()
2723
|| getgid () != getegid ();
2724
#endif
2725
}
2726
2727
unsigned int ecb_cold
2728
ev_supported_backends (void) EV_THROW
2729
{
2730
unsigned int flags = 0;
2731
2732
if (EV_USE_PORT ) flags |= EVBACKEND_PORT;
2733
if (EV_USE_KQUEUE) flags |= EVBACKEND_KQUEUE;
2734
if (EV_USE_EPOLL ) flags |= EVBACKEND_EPOLL;
2735
if (EV_USE_POLL ) flags |= EVBACKEND_POLL;
2736
if (EV_USE_SELECT) flags |= EVBACKEND_SELECT;
2737
2738
return flags;
2739
}
2740
2741
unsigned int ecb_cold
2742
ev_recommended_backends (void) EV_THROW
2743
{
2744
unsigned int flags = ev_supported_backends ();
2745
2746
#ifndef __NetBSD__
2747
/* kqueue is borked on everything but netbsd apparently */
2748
/* it usually doesn't work correctly on anything but sockets and pipes */
2749
flags &= ~EVBACKEND_KQUEUE;
2750
#endif
2751
#ifdef __APPLE__
2752
/* only select works correctly on that "unix-certified" platform */
2753
flags &= ~EVBACKEND_KQUEUE; /* horribly broken, even for sockets */
2754
flags &= ~EVBACKEND_POLL; /* poll is based on kqueue from 10.5 onwards */
2755
#endif
2756
#ifdef __FreeBSD__
2757
flags &= ~EVBACKEND_POLL; /* poll return value is unusable (http://forums.freebsd.org/archive/index.php/t-10270.html) */
2758
#endif
2759
2760
return flags;
2761
}
2762
2763
unsigned int ecb_cold
2764
ev_embeddable_backends (void) EV_THROW
2765
{
2766
int flags = EVBACKEND_EPOLL | EVBACKEND_KQUEUE | EVBACKEND_PORT;
2767
2768
/* epoll embeddability broken on all linux versions up to at least 2.6.23 */
2769
if (ev_linux_version () < 0x020620) /* disable it on linux < 2.6.32 */
2770
flags &= ~EVBACKEND_EPOLL;
2771
2772
return flags;
2773
}
2774
2775
unsigned int
2776
ev_backend (EV_P) EV_THROW
2777
{
2778
return backend;
2779
}
2780
2781
#if EV_FEATURE_API
2782
unsigned int
2783
ev_iteration (EV_P) EV_THROW
2784
{
2785
return loop_count;
2786
}
2787
2788
unsigned int
2789
ev_depth (EV_P) EV_THROW
2790
{
2791
return loop_depth;
2792
}
2793
2794
void
2795
ev_set_io_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
2796
{
2797
io_blocktime = interval;
2798
}
2799
2800
void
2801
ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval) EV_THROW
2802
{
2803
timeout_blocktime = interval;
2804
}
2805
2806
void
2807
ev_set_userdata (EV_P_ void *data) EV_THROW
2808
{
2809
userdata = data;
2810
}
2811
2812
void *
2813
ev_userdata (EV_P) EV_THROW
2814
{
2815
return userdata;
2816
}
2817
2818
void
2819
ev_set_invoke_pending_cb (EV_P_ ev_loop_callback invoke_pending_cb) EV_THROW
2820
{
2821
invoke_cb = invoke_pending_cb;
2822
}
2823
2824
void
2825
ev_set_loop_release_cb (EV_P_ void (*release)(EV_P) EV_THROW, void (*acquire)(EV_P) EV_THROW) EV_THROW
2826
{
2827
release_cb = release;
2828
acquire_cb = acquire;
2829
}
2830
#endif
2831
2832
/* initialise a loop structure, must be zero-initialised */
2833
static void noinline ecb_cold
2834
loop_init (EV_P_ unsigned int flags) EV_THROW
2835
{
2836
if (!backend)
2837
{
2838
origflags = flags;
2839
2840
#if EV_USE_REALTIME
2841
if (!have_realtime)
2842
{
2843
struct timespec ts;
2844
2845
if (!clock_gettime (CLOCK_REALTIME, &ts))
2846
have_realtime = 1;
2847
}
2848
#endif
2849
2850
#if EV_USE_MONOTONIC
2851
if (!have_monotonic)
2852
{
2853
struct timespec ts;
2854
2855
if (!clock_gettime (CLOCK_MONOTONIC, &ts))
2856
have_monotonic = 1;
2857
}
2858
#endif
2859
2860
/* pid check not overridable via env */
2861
#ifndef _WIN32
2862
if (flags & EVFLAG_FORKCHECK)
2863
curpid = getpid ();
2864
#endif
2865
2866
if (!(flags & EVFLAG_NOENV)
2867
&& !enable_secure ()
2868
&& getenv ("LIBEV_FLAGS"))
2869
flags = atoi (getenv ("LIBEV_FLAGS"));
2870
2871
ev_rt_now = ev_time ();
2872
mn_now = get_clock ();
2873
now_floor = mn_now;
2874
rtmn_diff = ev_rt_now - mn_now;
2875
#if EV_FEATURE_API
2876
invoke_cb = ev_invoke_pending;
2877
#endif
2878
2879
io_blocktime = 0.;
2880
timeout_blocktime = 0.;
2881
backend = 0;
2882
backend_fd = -1;
2883
sig_pending = 0;
2884
#if EV_ASYNC_ENABLE
2885
async_pending = 0;
2886
#endif
2887
pipe_write_skipped = 0;
2888
pipe_write_wanted = 0;
2889
evpipe [0] = -1;
2890
evpipe [1] = -1;
2891
#if EV_USE_INOTIFY
2892
fs_fd = flags & EVFLAG_NOINOTIFY ? -1 : -2;
2893
#endif
2894
#if EV_USE_SIGNALFD
2895
sigfd = flags & EVFLAG_SIGNALFD ? -2 : -1;
2896
#endif
2897
2898
if (!(flags & EVBACKEND_MASK))
2899
flags |= ev_recommended_backends ();
2900
2901
#if EV_USE_IOCP
2902
if (!backend && (flags & EVBACKEND_IOCP )) backend = iocp_init (EV_A_ flags);
2903
#endif
2904
#if EV_USE_PORT
2905
if (!backend && (flags & EVBACKEND_PORT )) backend = port_init (EV_A_ flags);
2906
#endif
2907
#if EV_USE_KQUEUE
2908
if (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags);
2909
#endif
2910
#if EV_USE_EPOLL
2911
if (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init (EV_A_ flags);
2912
#endif
2913
#if EV_USE_POLL
2914
if (!backend && (flags & EVBACKEND_POLL )) backend = poll_init (EV_A_ flags);
2915
#endif
2916
#if EV_USE_SELECT
2917
if (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
2918
#endif
2919
2920
ev_prepare_init (&pending_w, pendingcb);
2921
2922
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
2923
ev_init (&pipe_w, pipecb);
2924
ev_set_priority (&pipe_w, EV_MAXPRI);
2925
#endif
2926
}
2927
}
2928
2929
/* free up a loop structure */
2930
void ecb_cold
2931
ev_loop_destroy (EV_P)
2932
{
2933
int i;
2934
2935
#if EV_MULTIPLICITY
2936
/* mimic free (0) */
2937
if (!EV_A)
2938
return;
2939
#endif
2940
2941
#if EV_CLEANUP_ENABLE
2942
/* queue cleanup watchers (and execute them) */
2943
if (expect_false (cleanupcnt))
2944
{
2945
queue_events (EV_A_ (W *)cleanups, cleanupcnt, EV_CLEANUP);
2946
EV_INVOKE_PENDING;
2947
}
2948
#endif
2949
2950
#if EV_CHILD_ENABLE
2951
if (ev_is_default_loop (EV_A) && ev_is_active (&childev))
2952
{
2953
ev_ref (EV_A); /* child watcher */
2954
ev_signal_stop (EV_A_ &childev);
2955
}
2956
#endif
2957
2958
if (ev_is_active (&pipe_w))
2959
{
2960
/*ev_ref (EV_A);*/
2961
/*ev_io_stop (EV_A_ &pipe_w);*/
2962
2963
if (evpipe [0] >= 0) EV_WIN32_CLOSE_FD (evpipe [0]);
2964
if (evpipe [1] >= 0) EV_WIN32_CLOSE_FD (evpipe [1]);
2965
}
2966
2967
#if EV_USE_SIGNALFD
2968
if (ev_is_active (&sigfd_w))
2969
close (sigfd);
2970
#endif
2971
2972
#if EV_USE_INOTIFY
2973
if (fs_fd >= 0)
2974
close (fs_fd);
2975
#endif
2976
2977
if (backend_fd >= 0)
2978
close (backend_fd);
2979
2980
#if EV_USE_IOCP
2981
if (backend == EVBACKEND_IOCP ) iocp_destroy (EV_A);
2982
#endif
2983
#if EV_USE_PORT
2984
if (backend == EVBACKEND_PORT ) port_destroy (EV_A);
2985
#endif
2986
#if EV_USE_KQUEUE
2987
if (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A);
2988
#endif
2989
#if EV_USE_EPOLL
2990
if (backend == EVBACKEND_EPOLL ) epoll_destroy (EV_A);
2991
#endif
2992
#if EV_USE_POLL
2993
if (backend == EVBACKEND_POLL ) poll_destroy (EV_A);
2994
#endif
2995
#if EV_USE_SELECT
2996
if (backend == EVBACKEND_SELECT) select_destroy (EV_A);
2997
#endif
2998
2999
for (i = NUMPRI; i--; )
3000
{
3001
array_free (pending, [i]);
3002
#if EV_IDLE_ENABLE
3003
array_free (idle, [i]);
3004
#endif
3005
}
3006
3007
ev_free (anfds); anfds = 0; anfdmax = 0;
3008
3009
/* have to use the microsoft-never-gets-it-right macro */
3010
array_free (rfeed, EMPTY);
3011
array_free (fdchange, EMPTY);
3012
array_free (timer, EMPTY);
3013
#if EV_PERIODIC_ENABLE
3014
array_free (periodic, EMPTY);
3015
#endif
3016
#if EV_FORK_ENABLE
3017
array_free (fork, EMPTY);
3018
#endif
3019
#if EV_CLEANUP_ENABLE
3020
array_free (cleanup, EMPTY);
3021
#endif
3022
array_free (prepare, EMPTY);
3023
array_free (check, EMPTY);
3024
#if EV_ASYNC_ENABLE
3025
array_free (async, EMPTY);
3026
#endif
3027
3028
backend = 0;
3029
3030
#if EV_MULTIPLICITY
3031
if (ev_is_default_loop (EV_A))
3032
#endif
3033
ev_default_loop_ptr = 0;
3034
#if EV_MULTIPLICITY
3035
else
3036
ev_free (EV_A);
3037
#endif
3038
}
3039
3040
#if EV_USE_INOTIFY
3041
inline_size void infy_fork (EV_P);
3042
#endif
3043
3044
inline_size void
3045
loop_fork (EV_P)
3046
{
3047
#if EV_USE_PORT
3048
if (backend == EVBACKEND_PORT ) port_fork (EV_A);
3049
#endif
3050
#if EV_USE_KQUEUE
3051
if (backend == EVBACKEND_KQUEUE) kqueue_fork (EV_A);
3052
#endif
3053
#if EV_USE_EPOLL
3054
if (backend == EVBACKEND_EPOLL ) epoll_fork (EV_A);
3055
#endif
3056
#if EV_USE_INOTIFY
3057
infy_fork (EV_A);
3058
#endif
3059
3060
#if EV_SIGNAL_ENABLE || EV_ASYNC_ENABLE
3061
if (ev_is_active (&pipe_w) && postfork != 2)
3062
{
3063
/* pipe_write_wanted must be false now, so modifying fd vars should be safe */
3064
3065
ev_ref (EV_A);
3066
ev_io_stop (EV_A_ &pipe_w);
3067
3068
if (evpipe [0] >= 0)
3069
EV_WIN32_CLOSE_FD (evpipe [0]);
3070
3071
evpipe_init (EV_A);
3072
/* iterate over everything, in case we missed something before */
3073
ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
3074
}
3075
#endif
3076
3077
postfork = 0;
3078
}
3079
3080
#if EV_MULTIPLICITY
3081
3082
struct ev_loop * ecb_cold
3083
ev_loop_new (unsigned int flags) EV_THROW
3084
{
3085
EV_P = (struct ev_loop *)ev_malloc (sizeof (struct ev_loop));
3086
3087
memset (EV_A, 0, sizeof (struct ev_loop));
3088
loop_init (EV_A_ flags);
3089
3090
if (ev_backend (EV_A))
3091
return EV_A;
3092
3093
ev_free (EV_A);
3094
return 0;
3095
}
3096
3097
#endif /* multiplicity */
3098
3099
#if EV_VERIFY
3100
static void noinline ecb_cold
3101
verify_watcher (EV_P_ W w)
3102
{
3103
assert (("libev: watcher has invalid priority", ABSPRI (w) >= 0 && ABSPRI (w) < NUMPRI));
3104
3105
if (w->pending)
3106
assert (("libev: pending watcher not on pending queue", pendings [ABSPRI (w)][w->pending - 1].w == w));
3107
}
3108
3109
static void noinline ecb_cold
3110
verify_heap (EV_P_ ANHE *heap, int N)
3111
{
3112
int i;
3113
3114
for (i = HEAP0; i < N + HEAP0; ++i)
3115
{
3116
assert (("libev: active index mismatch in heap", ev_active (ANHE_w (heap [i])) == i));
3117
assert (("libev: heap condition violated", i == HEAP0 || ANHE_at (heap [HPARENT (i)]) <= ANHE_at (heap [i])));
3118
assert (("libev: heap at cache mismatch", ANHE_at (heap [i]) == ev_at (ANHE_w (heap [i]))));
3119
3120
verify_watcher (EV_A_ (W)ANHE_w (heap [i]));
3121
}
3122
}
3123
3124
static void noinline ecb_cold
3125
array_verify (EV_P_ W *ws, int cnt)
3126
{
3127
while (cnt--)
3128
{
3129
assert (("libev: active index mismatch", ev_active (ws [cnt]) == cnt + 1));
3130
verify_watcher (EV_A_ ws [cnt]);
3131
}
3132
}
3133
#endif
3134
3135
#if EV_FEATURE_API
3136
void ecb_cold
3137
ev_verify (EV_P) EV_THROW
3138
{
3139
#if EV_VERIFY
3140
int i;
3141
WL w, w2;
3142
3143
assert (activecnt >= -1);
3144
3145
assert (fdchangemax >= fdchangecnt);
3146
for (i = 0; i < fdchangecnt; ++i)
3147
assert (("libev: negative fd in fdchanges", fdchanges [i] >= 0));
3148
3149
assert (anfdmax >= 0);
3150
for (i = 0; i < anfdmax; ++i)
3151
{
3152
int j = 0;
3153
3154
for (w = w2 = anfds [i].head; w; w = w->next)
3155
{
3156
verify_watcher (EV_A_ (W)w);
3157
3158
if (j++ & 1)
3159
{
3160
assert (("libev: io watcher list contains a loop", w != w2));
3161
w2 = w2->next;
3162
}
3163
3164
assert (("libev: inactive fd watcher on anfd list", ev_active (w) == 1));
3165
assert (("libev: fd mismatch between watcher and anfd", ((ev_io *)w)->fd == i));
3166
}
3167
}
3168
3169
assert (timermax >= timercnt);
3170
verify_heap (EV_A_ timers, timercnt);
3171
3172
#if EV_PERIODIC_ENABLE
3173
assert (periodicmax >= periodiccnt);
3174
verify_heap (EV_A_ periodics, periodiccnt);
3175
#endif
3176
3177
for (i = NUMPRI; i--; )
3178
{
3179
assert (pendingmax [i] >= pendingcnt [i]);
3180
#if EV_IDLE_ENABLE
3181
assert (idleall >= 0);
3182
assert (idlemax [i] >= idlecnt [i]);
3183
array_verify (EV_A_ (W *)idles [i], idlecnt [i]);
3184
#endif
3185
}
3186
3187
#if EV_FORK_ENABLE
3188
assert (forkmax >= forkcnt);
3189
array_verify (EV_A_ (W *)forks, forkcnt);
3190
#endif
3191
3192
#if EV_CLEANUP_ENABLE
3193
assert (cleanupmax >= cleanupcnt);
3194
array_verify (EV_A_ (W *)cleanups, cleanupcnt);
3195
#endif
3196
3197
#if EV_ASYNC_ENABLE
3198
assert (asyncmax >= asynccnt);
3199
array_verify (EV_A_ (W *)asyncs, asynccnt);
3200
#endif
3201
3202
#if EV_PREPARE_ENABLE
3203
assert (preparemax >= preparecnt);
3204
array_verify (EV_A_ (W *)prepares, preparecnt);
3205
#endif
3206
3207
#if EV_CHECK_ENABLE
3208
assert (checkmax >= checkcnt);
3209
array_verify (EV_A_ (W *)checks, checkcnt);
3210
#endif
3211
3212
# if 0
3213
#if EV_CHILD_ENABLE
3214
for (w = (ev_child *)childs [chain & ((EV_PID_HASHSIZE) - 1)]; w; w = (ev_child *)((WL)w)->next)
3215
for (signum = EV_NSIG; signum--; ) if (signals [signum].pending)
3216
#endif
3217
# endif
3218
#endif
3219
}
3220
#endif
3221
3222
#if EV_MULTIPLICITY
3223
struct ev_loop * ecb_cold
3224
#else
3225
int
3226
#endif
3227
ev_default_loop (unsigned int flags) EV_THROW
3228
{
3229
if (!ev_default_loop_ptr)
3230
{
3231
#if EV_MULTIPLICITY
3232
EV_P = ev_default_loop_ptr = &default_loop_struct;
3233
#else
3234
ev_default_loop_ptr = 1;
3235
#endif
3236
3237
loop_init (EV_A_ flags);
3238
3239
if (ev_backend (EV_A))
3240
{
3241
#if EV_CHILD_ENABLE
3242
ev_signal_init (&childev, childcb, SIGCHLD);
3243
ev_set_priority (&childev, EV_MAXPRI);
3244
ev_signal_start (EV_A_ &childev);
3245
ev_unref (EV_A); /* child watcher should not keep loop alive */
3246
#endif
3247
}
3248
else
3249
ev_default_loop_ptr = 0;
3250
}
3251
3252
return ev_default_loop_ptr;
3253
}
3254
3255
void
3256
ev_loop_fork (EV_P) EV_THROW
3257
{
3258
postfork = 1;
3259
}
3260
3261
/*****************************************************************************/
3262
3263
void
3264
ev_invoke (EV_P_ void *w, int revents)
3265
{
3266
EV_CB_INVOKE ((W)w, revents);
3267
}
3268
3269
unsigned int
3270
ev_pending_count (EV_P) EV_THROW
3271
{
3272
int pri;
3273
unsigned int count = 0;
3274
3275
for (pri = NUMPRI; pri--; )
3276
count += pendingcnt [pri];
3277
3278
return count;
3279
}
3280
3281
void noinline
3282
ev_invoke_pending (EV_P)
3283
{
3284
pendingpri = NUMPRI;
3285
3286
while (pendingpri) /* pendingpri possibly gets modified in the inner loop */
3287
{
3288
--pendingpri;
3289
3290
while (pendingcnt [pendingpri])
3291
{
3292
ANPENDING *p = pendings [pendingpri] + --pendingcnt [pendingpri];
3293
3294
p->w->pending = 0;
3295
EV_CB_INVOKE (p->w, p->events);
3296
EV_FREQUENT_CHECK;
3297
}
3298
}
3299
}
3300
3301
#if EV_IDLE_ENABLE
3302
/* make idle watchers pending. this handles the "call-idle */
3303
/* only when higher priorities are idle" logic */
3304
inline_size void
3305
idle_reify (EV_P)
3306
{
3307
if (expect_false (idleall))
3308
{
3309
int pri;
3310
3311
for (pri = NUMPRI; pri--; )
3312
{
3313
if (pendingcnt [pri])
3314
break;
3315
3316
if (idlecnt [pri])
3317
{
3318
queue_events (EV_A_ (W *)idles [pri], idlecnt [pri], EV_IDLE);
3319
break;
3320
}
3321
}
3322
}
3323
}
3324
#endif
3325
3326
/* make timers pending */
3327
inline_size void
3328
timers_reify (EV_P)
3329
{
3330
EV_FREQUENT_CHECK;
3331
3332
if (timercnt && ANHE_at (timers [HEAP0]) < mn_now)
3333
{
3334
do
3335
{
3336
ev_timer *w = (ev_timer *)ANHE_w (timers [HEAP0]);
3337
3338
/*assert (("libev: inactive timer on timer heap detected", ev_is_active (w)));*/
3339
3340
/* first reschedule or stop timer */
3341
if (w->repeat)
3342
{
3343
ev_at (w) += w->repeat;
3344
if (ev_at (w) < mn_now)
3345
ev_at (w) = mn_now;
3346
3347
assert (("libev: negative ev_timer repeat value found while processing timers", w->repeat > 0.));
3348
3349
ANHE_at_cache (timers [HEAP0]);
3350
downheap (timers, timercnt, HEAP0);
3351
}
3352
else
3353
ev_timer_stop (EV_A_ w); /* nonrepeating: stop timer */
3354
3355
EV_FREQUENT_CHECK;
3356
feed_reverse (EV_A_ (W)w);
3357
}
3358
while (timercnt && ANHE_at (timers [HEAP0]) < mn_now);
3359
3360
feed_reverse_done (EV_A_ EV_TIMER);
3361
}
3362
}
3363
3364
#if EV_PERIODIC_ENABLE
3365
3366
static void noinline
3367
periodic_recalc (EV_P_ ev_periodic *w)
3368
{
3369
ev_tstamp interval = w->interval > MIN_INTERVAL ? w->interval : MIN_INTERVAL;
3370
ev_tstamp at = w->offset + interval * ev_floor ((ev_rt_now - w->offset) / interval);
3371
3372
/* the above almost always errs on the low side */
3373
while (at <= ev_rt_now)
3374
{
3375
ev_tstamp nat = at + w->interval;
3376
3377
/* when resolution fails us, we use ev_rt_now */
3378
if (expect_false (nat == at))
3379
{
3380
at = ev_rt_now;
3381
break;
3382
}
3383
3384
at = nat;
3385
}
3386
3387
ev_at (w) = at;
3388
}
3389
3390
/* make periodics pending */
3391
inline_size void
3392
periodics_reify (EV_P)
3393
{
3394
EV_FREQUENT_CHECK;
3395
3396
while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now)
3397
{
3398
do
3399
{
3400
ev_periodic *w = (ev_periodic *)ANHE_w (periodics [HEAP0]);
3401
3402
/*assert (("libev: inactive timer on periodic heap detected", ev_is_active (w)));*/
3403
3404
/* first reschedule or stop timer */
3405
if (w->reschedule_cb)
3406
{
3407
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
3408
3409
assert (("libev: ev_periodic reschedule callback returned time in the past", ev_at (w) >= ev_rt_now));
3410
3411
ANHE_at_cache (periodics [HEAP0]);
3412
downheap (periodics, periodiccnt, HEAP0);
3413
}
3414
else if (w->interval)
3415
{
3416
periodic_recalc (EV_A_ w);
3417
ANHE_at_cache (periodics [HEAP0]);
3418
downheap (periodics, periodiccnt, HEAP0);
3419
}
3420
else
3421
ev_periodic_stop (EV_A_ w); /* nonrepeating: stop timer */
3422
3423
EV_FREQUENT_CHECK;
3424
feed_reverse (EV_A_ (W)w);
3425
}
3426
while (periodiccnt && ANHE_at (periodics [HEAP0]) < ev_rt_now);
3427
3428
feed_reverse_done (EV_A_ EV_PERIODIC);
3429
}
3430
}
3431
3432
/* simply recalculate all periodics */
3433
/* TODO: maybe ensure that at least one event happens when jumping forward? */
3434
static void noinline ecb_cold
3435
periodics_reschedule (EV_P)
3436
{
3437
int i;
3438
3439
/* adjust periodics after time jump */
3440
for (i = HEAP0; i < periodiccnt + HEAP0; ++i)
3441
{
3442
ev_periodic *w = (ev_periodic *)ANHE_w (periodics [i]);
3443
3444
if (w->reschedule_cb)
3445
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
3446
else if (w->interval)
3447
periodic_recalc (EV_A_ w);
3448
3449
ANHE_at_cache (periodics [i]);
3450
}
3451
3452
reheap (periodics, periodiccnt);
3453
}
3454
#endif
3455
3456
/* adjust all timers by a given offset */
3457
static void noinline ecb_cold
3458
timers_reschedule (EV_P_ ev_tstamp adjust)
3459
{
3460
int i;
3461
3462
for (i = 0; i < timercnt; ++i)
3463
{
3464
ANHE *he = timers + i + HEAP0;
3465
ANHE_w (*he)->at += adjust;
3466
ANHE_at_cache (*he);
3467
}
3468
}
3469
3470
/* fetch new monotonic and realtime times from the kernel */
3471
/* also detect if there was a timejump, and act accordingly */
3472
inline_speed void
3473
time_update (EV_P_ ev_tstamp max_block)
3474
{
3475
#if EV_USE_MONOTONIC
3476
if (expect_true (have_monotonic))
3477
{
3478
int i;
3479
ev_tstamp odiff = rtmn_diff;
3480
3481
mn_now = get_clock ();
3482
3483
/* only fetch the realtime clock every 0.5*MIN_TIMEJUMP seconds */
3484
/* interpolate in the meantime */
3485
if (expect_true (mn_now - now_floor < MIN_TIMEJUMP * .5))
3486
{
3487
ev_rt_now = rtmn_diff + mn_now;
3488
return;
3489
}
3490
3491
now_floor = mn_now;
3492
ev_rt_now = ev_time ();
3493
3494
/* loop a few times, before making important decisions.
3495
* on the choice of "4": one iteration isn't enough,
3496
* in case we get preempted during the calls to
3497
* ev_time and get_clock. a second call is almost guaranteed
3498
* to succeed in that case, though. and looping a few more times
3499
* doesn't hurt either as we only do this on time-jumps or
3500
* in the unlikely event of having been preempted here.
3501
*/
3502
for (i = 4; --i; )
3503
{
3504
ev_tstamp diff;
3505
rtmn_diff = ev_rt_now - mn_now;
3506
3507
diff = odiff - rtmn_diff;
3508
3509
if (expect_true ((diff < 0. ? -diff : diff) < MIN_TIMEJUMP))
3510
return; /* all is well */
3511
3512
ev_rt_now = ev_time ();
3513
mn_now = get_clock ();
3514
now_floor = mn_now;
3515
}
3516
3517
/* no timer adjustment, as the monotonic clock doesn't jump */
3518
/* timers_reschedule (EV_A_ rtmn_diff - odiff) */
3519
# if EV_PERIODIC_ENABLE
3520
periodics_reschedule (EV_A);
3521
# endif
3522
}
3523
else
3524
#endif
3525
{
3526
ev_rt_now = ev_time ();
3527
3528
if (expect_false (mn_now > ev_rt_now || ev_rt_now > mn_now + max_block + MIN_TIMEJUMP))
3529
{
3530
/* adjust timers. this is easy, as the offset is the same for all of them */
3531
timers_reschedule (EV_A_ ev_rt_now - mn_now);
3532
#if EV_PERIODIC_ENABLE
3533
periodics_reschedule (EV_A);
3534
#endif
3535
}
3536
3537
mn_now = ev_rt_now;
3538
}
3539
}
3540
3541
int
3542
ev_run (EV_P_ int flags)
3543
{
3544
#if EV_FEATURE_API
3545
++loop_depth;
3546
#endif
3547
3548
assert (("libev: ev_loop recursion during release detected", loop_done != EVBREAK_RECURSE));
3549
3550
loop_done = EVBREAK_CANCEL;
3551
3552
EV_INVOKE_PENDING; /* in case we recurse, ensure ordering stays nice and clean */
3553
3554
do
3555
{
3556
#if EV_VERIFY >= 2
3557
ev_verify (EV_A);
3558
#endif
3559
3560
#ifndef _WIN32
3561
if (expect_false (curpid)) /* penalise the forking check even more */
3562
if (expect_false (getpid () != curpid))
3563
{
3564
curpid = getpid ();
3565
postfork = 1;
3566
}
3567
#endif
3568
3569
#if EV_FORK_ENABLE
3570
/* we might have forked, so queue fork handlers */
3571
if (expect_false (postfork))
3572
if (forkcnt)
3573
{
3574
queue_events (EV_A_ (W *)forks, forkcnt, EV_FORK);
3575
EV_INVOKE_PENDING;
3576
}
3577
#endif
3578
3579
#if EV_PREPARE_ENABLE
3580
/* queue prepare watchers (and execute them) */
3581
if (expect_false (preparecnt))
3582
{
3583
queue_events (EV_A_ (W *)prepares, preparecnt, EV_PREPARE);
3584
EV_INVOKE_PENDING;
3585
}
3586
#endif
3587
3588
if (expect_false (loop_done))
3589
break;
3590
3591
/* we might have forked, so reify kernel state if necessary */
3592
if (expect_false (postfork))
3593
loop_fork (EV_A);
3594
3595
/* update fd-related kernel structures */
3596
fd_reify (EV_A);
3597
3598
/* calculate blocking time */
3599
{
3600
ev_tstamp waittime = 0.;
3601
ev_tstamp sleeptime = 0.;
3602
3603
/* remember old timestamp for io_blocktime calculation */
3604
ev_tstamp prev_mn_now = mn_now;
3605
3606
/* update time to cancel out callback processing overhead */
3607
time_update (EV_A_ 1e100);
3608
3609
/* from now on, we want a pipe-wake-up */
3610
pipe_write_wanted = 1;
3611
3612
ECB_MEMORY_FENCE; /* make sure pipe_write_wanted is visible before we check for potential skips */
3613
3614
if (expect_true (!(flags & EVRUN_NOWAIT || idleall || !activecnt || pipe_write_skipped)))
3615
{
3616
waittime = MAX_BLOCKTIME;
3617
3618
if (timercnt)
3619
{
3620
ev_tstamp to = ANHE_at (timers [HEAP0]) - mn_now;
3621
if (waittime > to) waittime = to;
3622
}
3623
3624
#if EV_PERIODIC_ENABLE
3625
if (periodiccnt)
3626
{
3627
ev_tstamp to = ANHE_at (periodics [HEAP0]) - ev_rt_now;
3628
if (waittime > to) waittime = to;
3629
}
3630
#endif
3631
3632
/* don't let timeouts decrease the waittime below timeout_blocktime */
3633
if (expect_false (waittime < timeout_blocktime))
3634
waittime = timeout_blocktime;
3635
3636
/* at this point, we NEED to wait, so we have to ensure */
3637
/* to pass a minimum nonzero value to the backend */
3638
if (expect_false (waittime < backend_mintime))
3639
waittime = backend_mintime;
3640
3641
/* extra check because io_blocktime is commonly 0 */
3642
if (expect_false (io_blocktime))
3643
{
3644
sleeptime = io_blocktime - (mn_now - prev_mn_now);
3645
3646
if (sleeptime > waittime - backend_mintime)
3647
sleeptime = waittime - backend_mintime;
3648
3649
if (expect_true (sleeptime > 0.))
3650
{
3651
ev_sleep (sleeptime);
3652
waittime -= sleeptime;
3653
}
3654
}
3655
}
3656
3657
#if EV_FEATURE_API
3658
++loop_count;
3659
#endif
3660
assert ((loop_done = EVBREAK_RECURSE, 1)); /* assert for side effect */
3661
backend_poll (EV_A_ waittime);
3662
assert ((loop_done = EVBREAK_CANCEL, 1)); /* assert for side effect */
3663
3664
pipe_write_wanted = 0; /* just an optimisation, no fence needed */
3665
3666
ECB_MEMORY_FENCE_ACQUIRE;
3667
if (pipe_write_skipped)
3668
{
3669
assert (("libev: pipe_w not active, but pipe not written", ev_is_active (&pipe_w)));
3670
ev_feed_event (EV_A_ &pipe_w, EV_CUSTOM);
3671
}
3672
3673
3674
/* update ev_rt_now, do magic */
3675
time_update (EV_A_ waittime + sleeptime);
3676
}
3677
3678
/* queue pending timers and reschedule them */
3679
timers_reify (EV_A); /* relative timers called last */
3680
#if EV_PERIODIC_ENABLE
3681
periodics_reify (EV_A); /* absolute timers called first */
3682
#endif
3683
3684
#if EV_IDLE_ENABLE
3685
/* queue idle watchers unless other events are pending */
3686
idle_reify (EV_A);
3687
#endif
3688
3689
#if EV_CHECK_ENABLE
3690
/* queue check watchers, to be executed first */
3691
if (expect_false (checkcnt))
3692
queue_events (EV_A_ (W *)checks, checkcnt, EV_CHECK);
3693
#endif
3694
3695
EV_INVOKE_PENDING;
3696
}
3697
while (expect_true (
3698
activecnt
3699
&& !loop_done
3700
&& !(flags & (EVRUN_ONCE | EVRUN_NOWAIT))
3701
));
3702
3703
if (loop_done == EVBREAK_ONE)
3704
loop_done = EVBREAK_CANCEL;
3705
3706
#if EV_FEATURE_API
3707
--loop_depth;
3708
#endif
3709
3710
return activecnt;
3711
}
3712
3713
void
3714
ev_break (EV_P_ int how) EV_THROW
3715
{
3716
loop_done = how;
3717
}
3718
3719
void
3720
ev_ref (EV_P) EV_THROW
3721
{
3722
++activecnt;
3723
}
3724
3725
void
3726
ev_unref (EV_P) EV_THROW
3727
{
3728
--activecnt;
3729
}
3730
3731
void
3732
ev_now_update (EV_P) EV_THROW
3733
{
3734
time_update (EV_A_ 1e100);
3735
}
3736
3737
void
3738
ev_suspend (EV_P) EV_THROW
3739
{
3740
ev_now_update (EV_A);
3741
}
3742
3743
void
3744
ev_resume (EV_P) EV_THROW
3745
{
3746
ev_tstamp mn_prev = mn_now;
3747
3748
ev_now_update (EV_A);
3749
timers_reschedule (EV_A_ mn_now - mn_prev);
3750
#if EV_PERIODIC_ENABLE
3751
/* TODO: really do this? */
3752
periodics_reschedule (EV_A);
3753
#endif
3754
}
3755
3756
/*****************************************************************************/
3757
/* singly-linked list management, used when the expected list length is short */
3758
3759
inline_size void
3760
wlist_add (WL *head, WL elem)
3761
{
3762
elem->next = *head;
3763
*head = elem;
3764
}
3765
3766
inline_size void
3767
wlist_del (WL *head, WL elem)
3768
{
3769
while (*head)
3770
{
3771
if (expect_true (*head == elem))
3772
{
3773
*head = elem->next;
3774
break;
3775
}
3776
3777
head = &(*head)->next;
3778
}
3779
}
3780
3781
/* internal, faster, version of ev_clear_pending */
3782
inline_speed void
3783
clear_pending (EV_P_ W w)
3784
{
3785
if (w->pending)
3786
{
3787
pendings [ABSPRI (w)][w->pending - 1].w = (W)&pending_w;
3788
w->pending = 0;
3789
}
3790
}
3791
3792
int
3793
ev_clear_pending (EV_P_ void *w) EV_THROW
3794
{
3795
W w_ = (W)w;
3796
int pending = w_->pending;
3797
3798
if (expect_true (pending))
3799
{
3800
ANPENDING *p = pendings [ABSPRI (w_)] + pending - 1;
3801
p->w = (W)&pending_w;
3802
w_->pending = 0;
3803
return p->events;
3804
}
3805
else
3806
return 0;
3807
}
3808
3809
inline_size void
3810
pri_adjust (EV_P_ W w)
3811
{
3812
int pri = ev_priority (w);
3813
pri = pri < EV_MINPRI ? EV_MINPRI : pri;
3814
pri = pri > EV_MAXPRI ? EV_MAXPRI : pri;
3815
ev_set_priority (w, pri);
3816
}
3817
3818
inline_speed void
3819
ev_start (EV_P_ W w, int active)
3820
{
3821
pri_adjust (EV_A_ w);
3822
w->active = active;
3823
ev_ref (EV_A);
3824
}
3825
3826
inline_size void
3827
ev_stop (EV_P_ W w)
3828
{
3829
ev_unref (EV_A);
3830
w->active = 0;
3831
}
3832
3833
/*****************************************************************************/
3834
3835
void noinline
3836
ev_io_start (EV_P_ ev_io *w) EV_THROW
3837
{
3838
int fd = w->fd;
3839
3840
if (expect_false (ev_is_active (w)))
3841
return;
3842
3843
assert (("libev: ev_io_start called with negative fd", fd >= 0));
3844
assert (("libev: ev_io_start called with illegal event mask", !(w->events & ~(EV__IOFDSET | EV_READ | EV_WRITE))));
3845
3846
EV_FREQUENT_CHECK;
3847
3848
ev_start (EV_A_ (W)w, 1);
3849
array_needsize (ANFD, anfds, anfdmax, fd + 1, array_init_zero);
3850
wlist_add (&anfds[fd].head, (WL)w);
3851
3852
/* common bug, apparently */
3853
assert (("libev: ev_io_start called with corrupted watcher", ((WL)w)->next != (WL)w));
3854
3855
fd_change (EV_A_ fd, w->events & EV__IOFDSET | EV_ANFD_REIFY);
3856
w->events &= ~EV__IOFDSET;
3857
3858
EV_FREQUENT_CHECK;
3859
}
3860
3861
void noinline
3862
ev_io_stop (EV_P_ ev_io *w) EV_THROW
3863
{
3864
clear_pending (EV_A_ (W)w);
3865
if (expect_false (!ev_is_active (w)))
3866
return;
3867
3868
assert (("libev: ev_io_stop called with illegal fd (must stay constant after start!)", w->fd >= 0 && w->fd < anfdmax));
3869
3870
EV_FREQUENT_CHECK;
3871
3872
wlist_del (&anfds[w->fd].head, (WL)w);
3873
ev_stop (EV_A_ (W)w);
3874
3875
fd_change (EV_A_ w->fd, EV_ANFD_REIFY);
3876
3877
EV_FREQUENT_CHECK;
3878
}
3879
3880
void noinline
3881
ev_timer_start (EV_P_ ev_timer *w) EV_THROW
3882
{
3883
if (expect_false (ev_is_active (w)))
3884
return;
3885
3886
ev_at (w) += mn_now;
3887
3888
assert (("libev: ev_timer_start called with negative timer repeat value", w->repeat >= 0.));
3889
3890
EV_FREQUENT_CHECK;
3891
3892
++timercnt;
3893
ev_start (EV_A_ (W)w, timercnt + HEAP0 - 1);
3894
array_needsize (ANHE, timers, timermax, ev_active (w) + 1, EMPTY2);
3895
ANHE_w (timers [ev_active (w)]) = (WT)w;
3896
ANHE_at_cache (timers [ev_active (w)]);
3897
upheap (timers, ev_active (w));
3898
3899
EV_FREQUENT_CHECK;
3900
3901
/*assert (("libev: internal timer heap corruption", timers [ev_active (w)] == (WT)w));*/
3902
}
3903
3904
void noinline
3905
ev_timer_stop (EV_P_ ev_timer *w) EV_THROW
3906
{
3907
clear_pending (EV_A_ (W)w);
3908
if (expect_false (!ev_is_active (w)))
3909
return;
3910
3911
EV_FREQUENT_CHECK;
3912
3913
{
3914
int active = ev_active (w);
3915
3916
assert (("libev: internal timer heap corruption", ANHE_w (timers [active]) == (WT)w));
3917
3918
--timercnt;
3919
3920
if (expect_true (active < timercnt + HEAP0))
3921
{
3922
timers [active] = timers [timercnt + HEAP0];
3923
adjustheap (timers, timercnt, active);
3924
}
3925
}
3926
3927
ev_at (w) -= mn_now;
3928
3929
ev_stop (EV_A_ (W)w);
3930
3931
EV_FREQUENT_CHECK;
3932
}
3933
3934
void noinline
3935
ev_timer_again (EV_P_ ev_timer *w) EV_THROW
3936
{
3937
EV_FREQUENT_CHECK;
3938
3939
clear_pending (EV_A_ (W)w);
3940
3941
if (ev_is_active (w))
3942
{
3943
if (w->repeat)
3944
{
3945
ev_at (w) = mn_now + w->repeat;
3946
ANHE_at_cache (timers [ev_active (w)]);
3947
adjustheap (timers, timercnt, ev_active (w));
3948
}
3949
else
3950
ev_timer_stop (EV_A_ w);
3951
}
3952
else if (w->repeat)
3953
{
3954
ev_at (w) = w->repeat;
3955
ev_timer_start (EV_A_ w);
3956
}
3957
3958
EV_FREQUENT_CHECK;
3959
}
3960
3961
ev_tstamp
3962
ev_timer_remaining (EV_P_ ev_timer *w) EV_THROW
3963
{
3964
return ev_at (w) - (ev_is_active (w) ? mn_now : 0.);
3965
}
3966
3967
#if EV_PERIODIC_ENABLE
3968
void noinline
3969
ev_periodic_start (EV_P_ ev_periodic *w) EV_THROW
3970
{
3971
if (expect_false (ev_is_active (w)))
3972
return;
3973
3974
if (w->reschedule_cb)
3975
ev_at (w) = w->reschedule_cb (w, ev_rt_now);
3976
else if (w->interval)
3977
{
3978
assert (("libev: ev_periodic_start called with negative interval value", w->interval >= 0.));
3979
periodic_recalc (EV_A_ w);
3980
}
3981
else
3982
ev_at (w) = w->offset;
3983
3984
EV_FREQUENT_CHECK;
3985
3986
++periodiccnt;
3987
ev_start (EV_A_ (W)w, periodiccnt + HEAP0 - 1);
3988
array_needsize (ANHE, periodics, periodicmax, ev_active (w) + 1, EMPTY2);
3989
ANHE_w (periodics [ev_active (w)]) = (WT)w;
3990
ANHE_at_cache (periodics [ev_active (w)]);
3991
upheap (periodics, ev_active (w));
3992
3993
EV_FREQUENT_CHECK;
3994
3995
/*assert (("libev: internal periodic heap corruption", ANHE_w (periodics [ev_active (w)]) == (WT)w));*/
3996
}
3997
3998
void noinline
3999
ev_periodic_stop (EV_P_ ev_periodic *w) EV_THROW
4000
{
4001
clear_pending (EV_A_ (W)w);
4002
if (expect_false (!ev_is_active (w)))
4003
return;
4004
4005
EV_FREQUENT_CHECK;
4006
4007
{
4008
int active = ev_active (w);
4009
4010
assert (("libev: internal periodic heap corruption", ANHE_w (periodics [active]) == (WT)w));
4011
4012
--periodiccnt;
4013
4014
if (expect_true (active < periodiccnt + HEAP0))
4015
{
4016
periodics [active] = periodics [periodiccnt + HEAP0];
4017
adjustheap (periodics, periodiccnt, active);
4018
}
4019
}
4020
4021
ev_stop (EV_A_ (W)w);
4022
4023
EV_FREQUENT_CHECK;
4024
}
4025
4026
void noinline
4027
ev_periodic_again (EV_P_ ev_periodic *w) EV_THROW
4028
{
4029
/* TODO: use adjustheap and recalculation */
4030
ev_periodic_stop (EV_A_ w);
4031
ev_periodic_start (EV_A_ w);
4032
}
4033
#endif
4034
4035
#ifndef SA_RESTART
4036
# define SA_RESTART 0
4037
#endif
4038
4039
#if EV_SIGNAL_ENABLE
4040
4041
void noinline
4042
ev_signal_start (EV_P_ ev_signal *w) EV_THROW
4043
{
4044
if (expect_false (ev_is_active (w)))
4045
return;
4046
4047
assert (("libev: ev_signal_start called with illegal signal number", w->signum > 0 && w->signum < EV_NSIG));
4048
4049
#if EV_MULTIPLICITY
4050
assert (("libev: a signal must not be attached to two different loops",
4051
!signals [w->signum - 1].loop || signals [w->signum - 1].loop == loop));
4052
4053
signals [w->signum - 1].loop = EV_A;
4054
ECB_MEMORY_FENCE_RELEASE;
4055
#endif
4056
4057
EV_FREQUENT_CHECK;
4058
4059
#if EV_USE_SIGNALFD
4060
if (sigfd == -2)
4061
{
4062
sigfd = signalfd (-1, &sigfd_set, SFD_NONBLOCK | SFD_CLOEXEC);
4063
if (sigfd < 0 && errno == EINVAL)
4064
sigfd = signalfd (-1, &sigfd_set, 0); /* retry without flags */
4065
4066
if (sigfd >= 0)
4067
{
4068
fd_intern (sigfd); /* doing it twice will not hurt */
4069
4070
sigemptyset (&sigfd_set);
4071
4072
ev_io_init (&sigfd_w, sigfdcb, sigfd, EV_READ);
4073
ev_set_priority (&sigfd_w, EV_MAXPRI);
4074
ev_io_start (EV_A_ &sigfd_w);
4075
ev_unref (EV_A); /* signalfd watcher should not keep loop alive */
4076
}
4077
}
4078
4079
if (sigfd >= 0)
4080
{
4081
/* TODO: check .head */
4082
sigaddset (&sigfd_set, w->signum);
4083
sigprocmask (SIG_BLOCK, &sigfd_set, 0);
4084
4085
signalfd (sigfd, &sigfd_set, 0);
4086
}
4087
#endif
4088
4089
ev_start (EV_A_ (W)w, 1);
4090
wlist_add (&signals [w->signum - 1].head, (WL)w);
4091
4092
if (!((WL)w)->next)
4093
# if EV_USE_SIGNALFD
4094
if (sigfd < 0) /*TODO*/
4095
# endif
4096
{
4097
# ifdef _WIN32
4098
evpipe_init (EV_A);
4099
4100
signal (w->signum, ev_sighandler);
4101
# else
4102
struct sigaction sa;
4103
4104
evpipe_init (EV_A);
4105
4106
sa.sa_handler = ev_sighandler;
4107
sigfillset (&sa.sa_mask);
4108
sa.sa_flags = SA_RESTART; /* if restarting works we save one iteration */
4109
sigaction (w->signum, &sa, 0);
4110
4111
if (origflags & EVFLAG_NOSIGMASK)
4112
{
4113
sigemptyset (&sa.sa_mask);
4114
sigaddset (&sa.sa_mask, w->signum);
4115
sigprocmask (SIG_UNBLOCK, &sa.sa_mask, 0);
4116
}
4117
#endif
4118
}
4119
4120
EV_FREQUENT_CHECK;
4121
}
4122
4123
void noinline
4124
ev_signal_stop (EV_P_ ev_signal *w) EV_THROW
4125
{
4126
clear_pending (EV_A_ (W)w);
4127
if (expect_false (!ev_is_active (w)))
4128
return;
4129
4130
EV_FREQUENT_CHECK;
4131
4132
wlist_del (&signals [w->signum - 1].head, (WL)w);
4133
ev_stop (EV_A_ (W)w);
4134
4135
if (!signals [w->signum - 1].head)
4136
{
4137
#if EV_MULTIPLICITY
4138
signals [w->signum - 1].loop = 0; /* unattach from signal */
4139
#endif
4140
#if EV_USE_SIGNALFD
4141
if (sigfd >= 0)
4142
{
4143
sigset_t ss;
4144
4145
sigemptyset (&ss);
4146
sigaddset (&ss, w->signum);
4147
sigdelset (&sigfd_set, w->signum);
4148
4149
signalfd (sigfd, &sigfd_set, 0);
4150
sigprocmask (SIG_UNBLOCK, &ss, 0);
4151
}
4152
else
4153
#endif
4154
signal (w->signum, SIG_DFL);
4155
}
4156
4157
EV_FREQUENT_CHECK;
4158
}
4159
4160
#endif
4161
4162
#if EV_CHILD_ENABLE
4163
4164
void
4165
ev_child_start (EV_P_ ev_child *w) EV_THROW
4166
{
4167
#if EV_MULTIPLICITY
4168
assert (("libev: child watchers are only supported in the default loop", loop == ev_default_loop_ptr));
4169
#endif
4170
if (expect_false (ev_is_active (w)))
4171
return;
4172
4173
EV_FREQUENT_CHECK;
4174
4175
ev_start (EV_A_ (W)w, 1);
4176
wlist_add (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
4177
4178
EV_FREQUENT_CHECK;
4179
}
4180
4181
void
4182
ev_child_stop (EV_P_ ev_child *w) EV_THROW
4183
{
4184
clear_pending (EV_A_ (W)w);
4185
if (expect_false (!ev_is_active (w)))
4186
return;
4187
4188
EV_FREQUENT_CHECK;
4189
4190
wlist_del (&childs [w->pid & ((EV_PID_HASHSIZE) - 1)], (WL)w);
4191
ev_stop (EV_A_ (W)w);
4192
4193
EV_FREQUENT_CHECK;
4194
}
4195
4196
#endif
4197
4198
#if EV_STAT_ENABLE
4199
4200
# ifdef _WIN32
4201
# undef lstat
4202
# define lstat(a,b) _stati64 (a,b)
4203
# endif
4204
4205
#define DEF_STAT_INTERVAL 5.0074891
4206
#define NFS_STAT_INTERVAL 30.1074891 /* for filesystems potentially failing inotify */
4207
#define MIN_STAT_INTERVAL 0.1074891
4208
4209
static void noinline stat_timer_cb (EV_P_ ev_timer *w_, int revents);
4210
4211
#if EV_USE_INOTIFY
4212
4213
/* the * 2 is to allow for alignment padding, which for some reason is >> 8 */
4214
# define EV_INOTIFY_BUFSIZE (sizeof (struct inotify_event) * 2 + NAME_MAX)
4215
4216
static void noinline
4217
infy_add (EV_P_ ev_stat *w)
4218
{
4219
w->wd = inotify_add_watch (fs_fd, w->path,
4220
IN_ATTRIB | IN_DELETE_SELF | IN_MOVE_SELF | IN_MODIFY
4221
| IN_CREATE | IN_DELETE | IN_MOVED_FROM | IN_MOVED_TO
4222
| IN_DONT_FOLLOW | IN_MASK_ADD);
4223
4224
if (w->wd >= 0)
4225
{
4226
struct statfs sfs;
4227
4228
/* now local changes will be tracked by inotify, but remote changes won't */
4229
/* unless the filesystem is known to be local, we therefore still poll */
4230
/* also do poll on <2.6.25, but with normal frequency */
4231
4232
if (!fs_2625)
4233
w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
4234
else if (!statfs (w->path, &sfs)
4235
&& (sfs.f_type == 0x1373 /* devfs */
4236
|| sfs.f_type == 0x4006 /* fat */
4237
|| sfs.f_type == 0x4d44 /* msdos */
4238
|| sfs.f_type == 0xEF53 /* ext2/3 */
4239
|| sfs.f_type == 0x72b6 /* jffs2 */
4240
|| sfs.f_type == 0x858458f6 /* ramfs */
4241
|| sfs.f_type == 0x5346544e /* ntfs */
4242
|| sfs.f_type == 0x3153464a /* jfs */
4243
|| sfs.f_type == 0x9123683e /* btrfs */
4244
|| sfs.f_type == 0x52654973 /* reiser3 */
4245
|| sfs.f_type == 0x01021994 /* tmpfs */
4246
|| sfs.f_type == 0x58465342 /* xfs */))
4247
w->timer.repeat = 0.; /* filesystem is local, kernel new enough */
4248
else
4249
w->timer.repeat = w->interval ? w->interval : NFS_STAT_INTERVAL; /* remote, use reduced frequency */
4250
}
4251
else
4252
{
4253
/* can't use inotify, continue to stat */
4254
w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
4255
4256
/* if path is not there, monitor some parent directory for speedup hints */
4257
/* note that exceeding the hardcoded path limit is not a correctness issue, */
4258
/* but an efficiency issue only */
4259
if ((errno == ENOENT || errno == EACCES) && strlen (w->path) < 4096)
4260
{
4261
char path [4096];
4262
strcpy (path, w->path);
4263
4264
do
4265
{
4266
int mask = IN_MASK_ADD | IN_DELETE_SELF | IN_MOVE_SELF
4267
| (errno == EACCES ? IN_ATTRIB : IN_CREATE | IN_MOVED_TO);
4268
4269
char *pend = strrchr (path, '/');
4270
4271
if (!pend || pend == path)
4272
break;
4273
4274
*pend = 0;
4275
w->wd = inotify_add_watch (fs_fd, path, mask);
4276
}
4277
while (w->wd < 0 && (errno == ENOENT || errno == EACCES));
4278
}
4279
}
4280
4281
if (w->wd >= 0)
4282
wlist_add (&fs_hash [w->wd & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
4283
4284
/* now re-arm timer, if required */
4285
if (ev_is_active (&w->timer)) ev_ref (EV_A);
4286
ev_timer_again (EV_A_ &w->timer);
4287
if (ev_is_active (&w->timer)) ev_unref (EV_A);
4288
}
4289
4290
static void noinline
4291
infy_del (EV_P_ ev_stat *w)
4292
{
4293
int slot;
4294
int wd = w->wd;
4295
4296
if (wd < 0)
4297
return;
4298
4299
w->wd = -2;
4300
slot = wd & ((EV_INOTIFY_HASHSIZE) - 1);
4301
wlist_del (&fs_hash [slot].head, (WL)w);
4302
4303
/* remove this watcher, if others are watching it, they will rearm */
4304
inotify_rm_watch (fs_fd, wd);
4305
}
4306
4307
static void noinline
4308
infy_wd (EV_P_ int slot, int wd, struct inotify_event *ev)
4309
{
4310
if (slot < 0)
4311
/* overflow, need to check for all hash slots */
4312
for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
4313
infy_wd (EV_A_ slot, wd, ev);
4314
else
4315
{
4316
WL w_;
4317
4318
for (w_ = fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head; w_; )
4319
{
4320
ev_stat *w = (ev_stat *)w_;
4321
w_ = w_->next; /* lets us remove this watcher and all before it */
4322
4323
if (w->wd == wd || wd == -1)
4324
{
4325
if (ev->mask & (IN_IGNORED | IN_UNMOUNT | IN_DELETE_SELF))
4326
{
4327
wlist_del (&fs_hash [slot & ((EV_INOTIFY_HASHSIZE) - 1)].head, (WL)w);
4328
w->wd = -1;
4329
infy_add (EV_A_ w); /* re-add, no matter what */
4330
}
4331
4332
stat_timer_cb (EV_A_ &w->timer, 0);
4333
}
4334
}
4335
}
4336
}
4337
4338
static void
4339
infy_cb (EV_P_ ev_io *w, int revents)
4340
{
4341
char buf [EV_INOTIFY_BUFSIZE];
4342
int ofs;
4343
int len = read (fs_fd, buf, sizeof (buf));
4344
4345
for (ofs = 0; ofs < len; )
4346
{
4347
struct inotify_event *ev = (struct inotify_event *)(buf + ofs);
4348
infy_wd (EV_A_ ev->wd, ev->wd, ev);
4349
ofs += sizeof (struct inotify_event) + ev->len;
4350
}
4351
}
4352
4353
inline_size void ecb_cold
4354
ev_check_2625 (EV_P)
4355
{
4356
/* kernels < 2.6.25 are borked
4357
* http://www.ussg.indiana.edu/hypermail/linux/kernel/0711.3/1208.html
4358
*/
4359
if (ev_linux_version () < 0x020619)
4360
return;
4361
4362
fs_2625 = 1;
4363
}
4364
4365
inline_size int
4366
infy_newfd (void)
4367
{
4368
#if defined IN_CLOEXEC && defined IN_NONBLOCK
4369
int fd = inotify_init1 (IN_CLOEXEC | IN_NONBLOCK);
4370
if (fd >= 0)
4371
return fd;
4372
#endif
4373
return inotify_init ();
4374
}
4375
4376
inline_size void
4377
infy_init (EV_P)
4378
{
4379
if (fs_fd != -2)
4380
return;
4381
4382
fs_fd = -1;
4383
4384
ev_check_2625 (EV_A);
4385
4386
fs_fd = infy_newfd ();
4387
4388
if (fs_fd >= 0)
4389
{
4390
fd_intern (fs_fd);
4391
ev_io_init (&fs_w, infy_cb, fs_fd, EV_READ);
4392
ev_set_priority (&fs_w, EV_MAXPRI);
4393
ev_io_start (EV_A_ &fs_w);
4394
ev_unref (EV_A);
4395
}
4396
}
4397
4398
inline_size void
4399
infy_fork (EV_P)
4400
{
4401
int slot;
4402
4403
if (fs_fd < 0)
4404
return;
4405
4406
ev_ref (EV_A);
4407
ev_io_stop (EV_A_ &fs_w);
4408
close (fs_fd);
4409
fs_fd = infy_newfd ();
4410
4411
if (fs_fd >= 0)
4412
{
4413
fd_intern (fs_fd);
4414
ev_io_set (&fs_w, fs_fd, EV_READ);
4415
ev_io_start (EV_A_ &fs_w);
4416
ev_unref (EV_A);
4417
}
4418
4419
for (slot = 0; slot < (EV_INOTIFY_HASHSIZE); ++slot)
4420
{
4421
WL w_ = fs_hash [slot].head;
4422
fs_hash [slot].head = 0;
4423
4424
while (w_)
4425
{
4426
ev_stat *w = (ev_stat *)w_;
4427
w_ = w_->next; /* lets us add this watcher */
4428
4429
w->wd = -1;
4430
4431
if (fs_fd >= 0)
4432
infy_add (EV_A_ w); /* re-add, no matter what */
4433
else
4434
{
4435
w->timer.repeat = w->interval ? w->interval : DEF_STAT_INTERVAL;
4436
if (ev_is_active (&w->timer)) ev_ref (EV_A);
4437
ev_timer_again (EV_A_ &w->timer);
4438
if (ev_is_active (&w->timer)) ev_unref (EV_A);
4439
}
4440
}
4441
}
4442
}
4443
4444
#endif
4445
4446
#ifdef _WIN32
4447
# define EV_LSTAT(p,b) _stati64 (p, b)
4448
#else
4449
# define EV_LSTAT(p,b) lstat (p, b)
4450
#endif
4451
4452
void
4453
ev_stat_stat (EV_P_ ev_stat *w) EV_THROW
4454
{
4455
if (lstat (w->path, &w->attr) < 0)
4456
w->attr.st_nlink = 0;
4457
else if (!w->attr.st_nlink)
4458
w->attr.st_nlink = 1;
4459
}
4460
4461
static void noinline
4462
stat_timer_cb (EV_P_ ev_timer *w_, int revents)
4463
{
4464
ev_stat *w = (ev_stat *)(((char *)w_) - offsetof (ev_stat, timer));
4465
4466
ev_statdata prev = w->attr;
4467
ev_stat_stat (EV_A_ w);
4468
4469
/* memcmp doesn't work on netbsd, they.... do stuff to their struct stat */
4470
if (
4471
prev.st_dev != w->attr.st_dev
4472
|| prev.st_ino != w->attr.st_ino
4473
|| prev.st_mode != w->attr.st_mode
4474
|| prev.st_nlink != w->attr.st_nlink
4475
|| prev.st_uid != w->attr.st_uid
4476
|| prev.st_gid != w->attr.st_gid
4477
|| prev.st_rdev != w->attr.st_rdev
4478
|| prev.st_size != w->attr.st_size
4479
|| prev.st_atime != w->attr.st_atime
4480
|| prev.st_mtime != w->attr.st_mtime
4481
|| prev.st_ctime != w->attr.st_ctime
4482
) {
4483
/* we only update w->prev on actual differences */
4484
/* in case we test more often than invoke the callback, */
4485
/* to ensure that prev is always different to attr */
4486
w->prev = prev;
4487
4488
#if EV_USE_INOTIFY
4489
if (fs_fd >= 0)
4490
{
4491
infy_del (EV_A_ w);
4492
infy_add (EV_A_ w);
4493
ev_stat_stat (EV_A_ w); /* avoid race... */
4494
}
4495
#endif
4496
4497
ev_feed_event (EV_A_ w, EV_STAT);
4498
}
4499
}
4500
4501
void
4502
ev_stat_start (EV_P_ ev_stat *w) EV_THROW
4503
{
4504
if (expect_false (ev_is_active (w)))
4505
return;
4506
4507
ev_stat_stat (EV_A_ w);
4508
4509
if (w->interval < MIN_STAT_INTERVAL && w->interval)
4510
w->interval = MIN_STAT_INTERVAL;
4511
4512
ev_timer_init (&w->timer, stat_timer_cb, 0., w->interval ? w->interval : DEF_STAT_INTERVAL);
4513
ev_set_priority (&w->timer, ev_priority (w));
4514
4515
#if EV_USE_INOTIFY
4516
infy_init (EV_A);
4517
4518
if (fs_fd >= 0)
4519
infy_add (EV_A_ w);
4520
else
4521
#endif
4522
{
4523
ev_timer_again (EV_A_ &w->timer);
4524
ev_unref (EV_A);
4525
}
4526
4527
ev_start (EV_A_ (W)w, 1);
4528
4529
EV_FREQUENT_CHECK;
4530
}
4531
4532
void
4533
ev_stat_stop (EV_P_ ev_stat *w) EV_THROW
4534
{
4535
clear_pending (EV_A_ (W)w);
4536
if (expect_false (!ev_is_active (w)))
4537
return;
4538
4539
EV_FREQUENT_CHECK;
4540
4541
#if EV_USE_INOTIFY
4542
infy_del (EV_A_ w);
4543
#endif
4544
4545
if (ev_is_active (&w->timer))
4546
{
4547
ev_ref (EV_A);
4548
ev_timer_stop (EV_A_ &w->timer);
4549
}
4550
4551
ev_stop (EV_A_ (W)w);
4552
4553
EV_FREQUENT_CHECK;
4554
}
4555
#endif
4556
4557
#if EV_IDLE_ENABLE
4558
void
4559
ev_idle_start (EV_P_ ev_idle *w) EV_THROW
4560
{
4561
if (expect_false (ev_is_active (w)))
4562
return;
4563
4564
pri_adjust (EV_A_ (W)w);
4565
4566
EV_FREQUENT_CHECK;
4567
4568
{
4569
int active = ++idlecnt [ABSPRI (w)];
4570
4571
++idleall;
4572
ev_start (EV_A_ (W)w, active);
4573
4574
array_needsize (ev_idle *, idles [ABSPRI (w)], idlemax [ABSPRI (w)], active, EMPTY2);
4575
idles [ABSPRI (w)][active - 1] = w;
4576
}
4577
4578
EV_FREQUENT_CHECK;
4579
}
4580
4581
void
4582
ev_idle_stop (EV_P_ ev_idle *w) EV_THROW
4583
{
4584
clear_pending (EV_A_ (W)w);
4585
if (expect_false (!ev_is_active (w)))
4586
return;
4587
4588
EV_FREQUENT_CHECK;
4589
4590
{
4591
int active = ev_active (w);
4592
4593
idles [ABSPRI (w)][active - 1] = idles [ABSPRI (w)][--idlecnt [ABSPRI (w)]];
4594
ev_active (idles [ABSPRI (w)][active - 1]) = active;
4595
4596
ev_stop (EV_A_ (W)w);
4597
--idleall;
4598
}
4599
4600
EV_FREQUENT_CHECK;
4601
}
4602
#endif
4603
4604
#if EV_PREPARE_ENABLE
4605
void
4606
ev_prepare_start (EV_P_ ev_prepare *w) EV_THROW
4607
{
4608
if (expect_false (ev_is_active (w)))
4609
return;
4610
4611
EV_FREQUENT_CHECK;
4612
4613
ev_start (EV_A_ (W)w, ++preparecnt);
4614
array_needsize (ev_prepare *, prepares, preparemax, preparecnt, EMPTY2);
4615
prepares [preparecnt - 1] = w;
4616
4617
EV_FREQUENT_CHECK;
4618
}
4619
4620
void
4621
ev_prepare_stop (EV_P_ ev_prepare *w) EV_THROW
4622
{
4623
clear_pending (EV_A_ (W)w);
4624
if (expect_false (!ev_is_active (w)))
4625
return;
4626
4627
EV_FREQUENT_CHECK;
4628
4629
{
4630
int active = ev_active (w);
4631
4632
prepares [active - 1] = prepares [--preparecnt];
4633
ev_active (prepares [active - 1]) = active;
4634
}
4635
4636
ev_stop (EV_A_ (W)w);
4637
4638
EV_FREQUENT_CHECK;
4639
}
4640
#endif
4641
4642
#if EV_CHECK_ENABLE
4643
void
4644
ev_check_start (EV_P_ ev_check *w) EV_THROW
4645
{
4646
if (expect_false (ev_is_active (w)))
4647
return;
4648
4649
EV_FREQUENT_CHECK;
4650
4651
ev_start (EV_A_ (W)w, ++checkcnt);
4652
array_needsize (ev_check *, checks, checkmax, checkcnt, EMPTY2);
4653
checks [checkcnt - 1] = w;
4654
4655
EV_FREQUENT_CHECK;
4656
}
4657
4658
void
4659
ev_check_stop (EV_P_ ev_check *w) EV_THROW
4660
{
4661
clear_pending (EV_A_ (W)w);
4662
if (expect_false (!ev_is_active (w)))
4663
return;
4664
4665
EV_FREQUENT_CHECK;
4666
4667
{
4668
int active = ev_active (w);
4669
4670
checks [active - 1] = checks [--checkcnt];
4671
ev_active (checks [active - 1]) = active;
4672
}
4673
4674
ev_stop (EV_A_ (W)w);
4675
4676
EV_FREQUENT_CHECK;
4677
}
4678
#endif
4679
4680
#if EV_EMBED_ENABLE
4681
void noinline
4682
ev_embed_sweep (EV_P_ ev_embed *w) EV_THROW
4683
{
4684
ev_run (w->other, EVRUN_NOWAIT);
4685
}
4686
4687
static void
4688
embed_io_cb (EV_P_ ev_io *io, int revents)
4689
{
4690
ev_embed *w = (ev_embed *)(((char *)io) - offsetof (ev_embed, io));
4691
4692
if (ev_cb (w))
4693
ev_feed_event (EV_A_ (W)w, EV_EMBED);
4694
else
4695
ev_run (w->other, EVRUN_NOWAIT);
4696
}
4697
4698
static void
4699
embed_prepare_cb (EV_P_ ev_prepare *prepare, int revents)
4700
{
4701
ev_embed *w = (ev_embed *)(((char *)prepare) - offsetof (ev_embed, prepare));
4702
4703
{
4704
EV_P = w->other;
4705
4706
while (fdchangecnt)
4707
{
4708
fd_reify (EV_A);
4709
ev_run (EV_A_ EVRUN_NOWAIT);
4710
}
4711
}
4712
}
4713
4714
static void
4715
embed_fork_cb (EV_P_ ev_fork *fork_w, int revents)
4716
{
4717
ev_embed *w = (ev_embed *)(((char *)fork_w) - offsetof (ev_embed, fork));
4718
4719
ev_embed_stop (EV_A_ w);
4720
4721
{
4722
EV_P = w->other;
4723
4724
ev_loop_fork (EV_A);
4725
ev_run (EV_A_ EVRUN_NOWAIT);
4726
}
4727
4728
ev_embed_start (EV_A_ w);
4729
}
4730
4731
#if 0
4732
static void
4733
embed_idle_cb (EV_P_ ev_idle *idle, int revents)
4734
{
4735
ev_idle_stop (EV_A_ idle);
4736
}
4737
#endif
4738
4739
void
4740
ev_embed_start (EV_P_ ev_embed *w) EV_THROW
4741
{
4742
if (expect_false (ev_is_active (w)))
4743
return;
4744
4745
{
4746
EV_P = w->other;
4747
assert (("libev: loop to be embedded is not embeddable", backend & ev_embeddable_backends ()));
4748
ev_io_init (&w->io, embed_io_cb, backend_fd, EV_READ);
4749
}
4750
4751
EV_FREQUENT_CHECK;
4752
4753
ev_set_priority (&w->io, ev_priority (w));
4754
ev_io_start (EV_A_ &w->io);
4755
4756
ev_prepare_init (&w->prepare, embed_prepare_cb);
4757
ev_set_priority (&w->prepare, EV_MINPRI);
4758
ev_prepare_start (EV_A_ &w->prepare);
4759
4760
ev_fork_init (&w->fork, embed_fork_cb);
4761
ev_fork_start (EV_A_ &w->fork);
4762
4763
/*ev_idle_init (&w->idle, e,bed_idle_cb);*/
4764
4765
ev_start (EV_A_ (W)w, 1);
4766
4767
EV_FREQUENT_CHECK;
4768
}
4769
4770
void
4771
ev_embed_stop (EV_P_ ev_embed *w) EV_THROW
4772
{
4773
clear_pending (EV_A_ (W)w);
4774
if (expect_false (!ev_is_active (w)))
4775
return;
4776
4777
EV_FREQUENT_CHECK;
4778
4779
ev_io_stop (EV_A_ &w->io);
4780
ev_prepare_stop (EV_A_ &w->prepare);
4781
ev_fork_stop (EV_A_ &w->fork);
4782
4783
ev_stop (EV_A_ (W)w);
4784
4785
EV_FREQUENT_CHECK;
4786
}
4787
#endif
4788
4789
#if EV_FORK_ENABLE
4790
void
4791
ev_fork_start (EV_P_ ev_fork *w) EV_THROW
4792
{
4793
if (expect_false (ev_is_active (w)))
4794
return;
4795
4796
EV_FREQUENT_CHECK;
4797
4798
ev_start (EV_A_ (W)w, ++forkcnt);
4799
array_needsize (ev_fork *, forks, forkmax, forkcnt, EMPTY2);
4800
forks [forkcnt - 1] = w;
4801
4802
EV_FREQUENT_CHECK;
4803
}
4804
4805
void
4806
ev_fork_stop (EV_P_ ev_fork *w) EV_THROW
4807
{
4808
clear_pending (EV_A_ (W)w);
4809
if (expect_false (!ev_is_active (w)))
4810
return;
4811
4812
EV_FREQUENT_CHECK;
4813
4814
{
4815
int active = ev_active (w);
4816
4817
forks [active - 1] = forks [--forkcnt];
4818
ev_active (forks [active - 1]) = active;
4819
}
4820
4821
ev_stop (EV_A_ (W)w);
4822
4823
EV_FREQUENT_CHECK;
4824
}
4825
#endif
4826
4827
#if EV_CLEANUP_ENABLE
4828
void
4829
ev_cleanup_start (EV_P_ ev_cleanup *w) EV_THROW
4830
{
4831
if (expect_false (ev_is_active (w)))
4832
return;
4833
4834
EV_FREQUENT_CHECK;
4835
4836
ev_start (EV_A_ (W)w, ++cleanupcnt);
4837
array_needsize (ev_cleanup *, cleanups, cleanupmax, cleanupcnt, EMPTY2);
4838
cleanups [cleanupcnt - 1] = w;
4839
4840
/* cleanup watchers should never keep a refcount on the loop */
4841
ev_unref (EV_A);
4842
EV_FREQUENT_CHECK;
4843
}
4844
4845
void
4846
ev_cleanup_stop (EV_P_ ev_cleanup *w) EV_THROW
4847
{
4848
clear_pending (EV_A_ (W)w);
4849
if (expect_false (!ev_is_active (w)))
4850
return;
4851
4852
EV_FREQUENT_CHECK;
4853
ev_ref (EV_A);
4854
4855
{
4856
int active = ev_active (w);
4857
4858
cleanups [active - 1] = cleanups [--cleanupcnt];
4859
ev_active (cleanups [active - 1]) = active;
4860
}
4861
4862
ev_stop (EV_A_ (W)w);
4863
4864
EV_FREQUENT_CHECK;
4865
}
4866
#endif
4867
4868
#if EV_ASYNC_ENABLE
4869
void
4870
ev_async_start (EV_P_ ev_async *w) EV_THROW
4871
{
4872
if (expect_false (ev_is_active (w)))
4873
return;
4874
4875
w->sent = 0;
4876
4877
evpipe_init (EV_A);
4878
4879
EV_FREQUENT_CHECK;
4880
4881
ev_start (EV_A_ (W)w, ++asynccnt);
4882
array_needsize (ev_async *, asyncs, asyncmax, asynccnt, EMPTY2);
4883
asyncs [asynccnt - 1] = w;
4884
4885
EV_FREQUENT_CHECK;
4886
}
4887
4888
void
4889
ev_async_stop (EV_P_ ev_async *w) EV_THROW
4890
{
4891
clear_pending (EV_A_ (W)w);
4892
if (expect_false (!ev_is_active (w)))
4893
return;
4894
4895
EV_FREQUENT_CHECK;
4896
4897
{
4898
int active = ev_active (w);
4899
4900
asyncs [active - 1] = asyncs [--asynccnt];
4901
ev_active (asyncs [active - 1]) = active;
4902
}
4903
4904
ev_stop (EV_A_ (W)w);
4905
4906
EV_FREQUENT_CHECK;
4907
}
4908
4909
void
4910
ev_async_send (EV_P_ ev_async *w) EV_THROW
4911
{
4912
w->sent = 1;
4913
evpipe_write (EV_A_ &async_pending);
4914
}
4915
#endif
4916
4917
/*****************************************************************************/
4918
4919
struct ev_once
4920
{
4921
ev_io io;
4922
ev_timer to;
4923
void (*cb)(int revents, void *arg);
4924
void *arg;
4925
};
4926
4927
static void
4928
once_cb (EV_P_ struct ev_once *once, int revents)
4929
{
4930
void (*cb)(int revents, void *arg) = once->cb;
4931
void *arg = once->arg;
4932
4933
ev_io_stop (EV_A_ &once->io);
4934
ev_timer_stop (EV_A_ &once->to);
4935
ev_free (once);
4936
4937
cb (revents, arg);
4938
}
4939
4940
static void
4941
once_cb_io (EV_P_ ev_io *w, int revents)
4942
{
4943
struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, io));
4944
4945
once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->to));
4946
}
4947
4948
static void
4949
once_cb_to (EV_P_ ev_timer *w, int revents)
4950
{
4951
struct ev_once *once = (struct ev_once *)(((char *)w) - offsetof (struct ev_once, to));
4952
4953
once_cb (EV_A_ once, revents | ev_clear_pending (EV_A_ &once->io));
4954
}
4955
4956
void
4957
ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg) EV_THROW
4958
{
4959
struct ev_once *once = (struct ev_once *)ev_malloc (sizeof (struct ev_once));
4960
4961
if (expect_false (!once))
4962
{
4963
cb (EV_ERROR | EV_READ | EV_WRITE | EV_TIMER, arg);
4964
return;
4965
}
4966
4967
once->cb = cb;
4968
once->arg = arg;
4969
4970
ev_init (&once->io, once_cb_io);
4971
if (fd >= 0)
4972
{
4973
ev_io_set (&once->io, fd, events);
4974
ev_io_start (EV_A_ &once->io);
4975
}
4976
4977
ev_init (&once->to, once_cb_to);
4978
if (timeout >= 0.)
4979
{
4980
ev_timer_set (&once->to, timeout, 0.);
4981
ev_timer_start (EV_A_ &once->to);
4982
}
4983
}
4984
4985
/*****************************************************************************/
4986
4987
#if EV_WALK_ENABLE
4988
void ecb_cold
4989
ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w)) EV_THROW
4990
{
4991
int i, j;
4992
ev_watcher_list *wl, *wn;
4993
4994
if (types & (EV_IO | EV_EMBED))
4995
for (i = 0; i < anfdmax; ++i)
4996
for (wl = anfds [i].head; wl; )
4997
{
4998
wn = wl->next;
4999
5000
#if EV_EMBED_ENABLE
5001
if (ev_cb ((ev_io *)wl) == embed_io_cb)
5002
{
5003
if (types & EV_EMBED)
5004
cb (EV_A_ EV_EMBED, ((char *)wl) - offsetof (struct ev_embed, io));
5005
}
5006
else
5007
#endif
5008
#if EV_USE_INOTIFY
5009
if (ev_cb ((ev_io *)wl) == infy_cb)
5010
;
5011
else
5012
#endif
5013
if ((ev_io *)wl != &pipe_w)
5014
if (types & EV_IO)
5015
cb (EV_A_ EV_IO, wl);
5016
5017
wl = wn;
5018
}
5019
5020
if (types & (EV_TIMER | EV_STAT))
5021
for (i = timercnt + HEAP0; i-- > HEAP0; )
5022
#if EV_STAT_ENABLE
5023
/*TODO: timer is not always active*/
5024
if (ev_cb ((ev_timer *)ANHE_w (timers [i])) == stat_timer_cb)
5025
{
5026
if (types & EV_STAT)
5027
cb (EV_A_ EV_STAT, ((char *)ANHE_w (timers [i])) - offsetof (struct ev_stat, timer));
5028
}
5029
else
5030
#endif
5031
if (types & EV_TIMER)
5032
cb (EV_A_ EV_TIMER, ANHE_w (timers [i]));
5033
5034
#if EV_PERIODIC_ENABLE
5035
if (types & EV_PERIODIC)
5036
for (i = periodiccnt + HEAP0; i-- > HEAP0; )
5037
cb (EV_A_ EV_PERIODIC, ANHE_w (periodics [i]));
5038
#endif
5039
5040
#if EV_IDLE_ENABLE
5041
if (types & EV_IDLE)
5042
for (j = NUMPRI; j--; )
5043
for (i = idlecnt [j]; i--; )
5044
cb (EV_A_ EV_IDLE, idles [j][i]);
5045
#endif
5046
5047
#if EV_FORK_ENABLE
5048
if (types & EV_FORK)
5049
for (i = forkcnt; i--; )
5050
if (ev_cb (forks [i]) != embed_fork_cb)
5051
cb (EV_A_ EV_FORK, forks [i]);
5052
#endif
5053
5054
#if EV_ASYNC_ENABLE
5055
if (types & EV_ASYNC)
5056
for (i = asynccnt; i--; )
5057
cb (EV_A_ EV_ASYNC, asyncs [i]);
5058
#endif
5059
5060
#if EV_PREPARE_ENABLE
5061
if (types & EV_PREPARE)
5062
for (i = preparecnt; i--; )
5063
# if EV_EMBED_ENABLE
5064
if (ev_cb (prepares [i]) != embed_prepare_cb)
5065
# endif
5066
cb (EV_A_ EV_PREPARE, prepares [i]);
5067
#endif
5068
5069
#if EV_CHECK_ENABLE
5070
if (types & EV_CHECK)
5071
for (i = checkcnt; i--; )
5072
cb (EV_A_ EV_CHECK, checks [i]);
5073
#endif
5074
5075
#if EV_SIGNAL_ENABLE
5076
if (types & EV_SIGNAL)
5077
for (i = 0; i < EV_NSIG - 1; ++i)
5078
for (wl = signals [i].head; wl; )
5079
{
5080
wn = wl->next;
5081
cb (EV_A_ EV_SIGNAL, wl);
5082
wl = wn;
5083
}
5084
#endif
5085
5086
#if EV_CHILD_ENABLE
5087
if (types & EV_CHILD)
5088
for (i = (EV_PID_HASHSIZE); i--; )
5089
for (wl = childs [i]; wl; )
5090
{
5091
wn = wl->next;
5092
cb (EV_A_ EV_CHILD, wl);
5093
wl = wn;
5094
}
5095
#endif
5096
/* EV_STAT 0x00001000 /* stat data changed */
5097
/* EV_EMBED 0x00010000 /* embedded event loop needs sweep */
5098
}
5099
#endif
5100
5101
#if EV_MULTIPLICITY
5102
#include "ev_wrap.h"
5103
#endif
5104
5105
5106