"Fossies" - the Fresh Open Source Software Archive

Member "libev-4.33/ev.c" (18 Mar 2020, 151725 Bytes) of package /linux/misc/libev-4.33.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "ev.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 4.31_vs_4.33.

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