@@ -0,0 +1,203 @@
/*
* loop member variable declarations
*
* Copyright (c) 2007,2008,2009,2010,2011 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License ("GPL") version 2 or any later version,
* in which case the provisions of the GPL are applicable instead of
* the above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the BSD license, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file under
* either the BSD or the GPL.
*/

#define VARx(type,name) VAR(name, type name)

VARx(ev_tstamp, now_floor) /* last time we refreshed rt_time */
VARx(ev_tstamp, mn_now) /* monotonic clock "now" */
VARx(ev_tstamp, rtmn_diff) /* difference realtime - monotonic time */

VARx(ev_tstamp, io_blocktime)
VARx(ev_tstamp, timeout_blocktime)

VARx(int, backend)
VARx(int, activecnt) /* total number of active events ("refcount") */
VARx(EV_ATOMIC_T, loop_done) /* signal by ev_break */

VARx(int, backend_fd)
VARx(ev_tstamp, backend_fudge) /* assumed typical timer resolution */
VAR (backend_modify, void (*backend_modify)(EV_P_ int fd, int oev, int nev))
VAR (backend_poll , void (*backend_poll)(EV_P_ ev_tstamp timeout))

VARx(ANFD *, anfds)
VARx(int, anfdmax)

VAR (pendings, ANPENDING *pendings [NUMPRI])
VAR (pendingmax, int pendingmax [NUMPRI])
VAR (pendingcnt, int pendingcnt [NUMPRI])
VARx(ev_prepare, pending_w) /* dummy pending watcher */

/* for reverse feeding of events */
VARx(W *, rfeeds)
VARx(int, rfeedmax)
VARx(int, rfeedcnt)

#if EV_USE_EVENTFD || EV_GENWRAP
VARx(int, evfd)
#endif
VAR (evpipe, int evpipe [2])
VARx(ev_io, pipe_w)

#if !defined(_WIN32) || EV_GENWRAP
VARx(pid_t, curpid)
#endif

VARx(char, postfork) /* true if we need to recreate kernel state after fork */

#if EV_USE_SELECT || EV_GENWRAP
VARx(void *, vec_ri)
VARx(void *, vec_ro)
VARx(void *, vec_wi)
VARx(void *, vec_wo)
#if defined(_WIN32) || EV_GENWRAP
VARx(void *, vec_eo)
#endif
VARx(int, vec_max)
#endif

#if EV_USE_POLL || EV_GENWRAP
VARx(struct pollfd *, polls)
VARx(int, pollmax)
VARx(int, pollcnt)
VARx(int *, pollidxs) /* maps fds into structure indices */
VARx(int, pollidxmax)
#endif

#if EV_USE_EPOLL || EV_GENWRAP
VARx(struct epoll_event *, epoll_events)
VARx(int, epoll_eventmax)
VARx(int *, epoll_eperms)
VARx(int, epoll_epermcnt)
VARx(int, epoll_epermmax)
#endif

#if EV_USE_KQUEUE || EV_GENWRAP
VARx(struct kevent *, kqueue_changes)
VARx(int, kqueue_changemax)
VARx(int, kqueue_changecnt)
VARx(struct kevent *, kqueue_events)
VARx(int, kqueue_eventmax)
#endif

#if EV_USE_PORT || EV_GENWRAP
VARx(struct port_event *, port_events)
VARx(int, port_eventmax)
#endif

#if EV_USE_IOCP || EV_GENWRAP
VARx(HANDLE, iocp)
#endif

VARx(int *, fdchanges)
VARx(int, fdchangemax)
VARx(int, fdchangecnt)

VARx(ANHE *, timers)
VARx(int, timermax)
VARx(int, timercnt)

#if EV_PERIODIC_ENABLE || EV_GENWRAP
VARx(ANHE *, periodics)
VARx(int, periodicmax)
VARx(int, periodiccnt)
#endif

#if EV_IDLE_ENABLE || EV_GENWRAP
VAR (idles, ev_idle **idles [NUMPRI])
VAR (idlemax, int idlemax [NUMPRI])
VAR (idlecnt, int idlecnt [NUMPRI])
#endif
VARx(int, idleall) /* total number */

VARx(struct ev_prepare **, prepares)
VARx(int, preparemax)
VARx(int, preparecnt)

VARx(struct ev_check **, checks)
VARx(int, checkmax)
VARx(int, checkcnt)

#if EV_FORK_ENABLE || EV_GENWRAP
VARx(struct ev_fork **, forks)
VARx(int, forkmax)
VARx(int, forkcnt)
#endif

#if EV_CLEANUP_ENABLE || EV_GENWRAP
VARx(struct ev_cleanup **, cleanups)
VARx(int, cleanupmax)
VARx(int, cleanupcnt)
#endif

#if EV_ASYNC_ENABLE || EV_GENWRAP
VARx(EV_ATOMIC_T, async_pending)
VARx(struct ev_async **, asyncs)
VARx(int, asyncmax)
VARx(int, asynccnt)
#endif

#if EV_USE_INOTIFY || EV_GENWRAP
VARx(int, fs_fd)
VARx(ev_io, fs_w)
VARx(char, fs_2625) /* whether we are running in linux 2.6.25 or newer */
VAR (fs_hash, ANFS fs_hash [EV_INOTIFY_HASHSIZE])
#endif

VARx(EV_ATOMIC_T, sig_pending)
VARx(int, nosigmask)
#if EV_USE_SIGNALFD || EV_GENWRAP
VARx(int, sigfd)
VARx(ev_io, sigfd_w)
VARx(sigset_t, sigfd_set)
#endif

VARx(unsigned int, origflags) /* original loop flags */

#if EV_FEATURE_API || EV_GENWRAP
VARx(unsigned int, loop_count) /* total number of loop iterations/blocks */
VARx(unsigned int, loop_depth) /* #ev_run enters - #ev_run leaves */

VARx(void *, userdata)
VAR (release_cb, void (*release_cb)(EV_P))
VAR (acquire_cb, void (*acquire_cb)(EV_P))
VAR (invoke_cb , void (*invoke_cb) (EV_P))
#endif

#undef VARx

@@ -0,0 +1,153 @@
/*
* libev win32 compatibility cruft (_not_ a backend)
*
* Copyright (c) 2007,2008,2009 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License ("GPL") version 2 or any later version,
* in which case the provisions of the GPL are applicable instead of
* the above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the BSD license, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file under
* either the BSD or the GPL.
*/

#ifdef _WIN32

/* timeb.h is actually xsi legacy functionality */
#include <sys/timeb.h>

/* note: the comment below could not be substantiated, but what would I care */
/* MSDN says this is required to handle SIGFPE */
/* my wild guess would be that using something floating-pointy is required */
/* for the crt to do something about it */
volatile double SIGFPE_REQ = 0.0f;

/* oh, the humanity! */
static int
ev_pipe (int filedes [2])
{
struct sockaddr_in addr = { 0 };
int addr_size = sizeof (addr);
struct sockaddr_in adr2;
int adr2_size = sizeof (adr2);
SOCKET listener;
SOCKET sock [2] = { -1, -1 };

if ((listener = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
return -1;

addr.sin_family = AF_INET;
addr.sin_addr.s_addr = htonl (INADDR_LOOPBACK);
addr.sin_port = 0;

if (bind (listener, (struct sockaddr *)&addr, addr_size))
goto fail;

if (getsockname (listener, (struct sockaddr *)&addr, &addr_size))
goto fail;

if (listen (listener, 1))
goto fail;

if ((sock [0] = socket (AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET)
goto fail;

if (connect (sock [0], (struct sockaddr *)&addr, addr_size))
goto fail;

if ((sock [1] = accept (listener, 0, 0)) < 0)
goto fail;

/* windows vista returns fantasy port numbers for sockets:
* example for two interconnected tcp sockets:
*
* (Socket::unpack_sockaddr_in getsockname $sock0)[0] == 53364
* (Socket::unpack_sockaddr_in getpeername $sock0)[0] == 53363
* (Socket::unpack_sockaddr_in getsockname $sock1)[0] == 53363
* (Socket::unpack_sockaddr_in getpeername $sock1)[0] == 53365
*
* wow! tridirectional sockets!
*
* this way of checking ports seems to work:
*/
if (getpeername (sock [0], (struct sockaddr *)&addr, &addr_size))
goto fail;

if (getsockname (sock [1], (struct sockaddr *)&adr2, &adr2_size))
goto fail;

errno = WSAEINVAL;
if (addr_size != adr2_size
|| addr.sin_addr.s_addr != adr2.sin_addr.s_addr /* just to be sure, I mean, it's windows */
|| addr.sin_port != adr2.sin_port)
goto fail;

closesocket (listener);

#if EV_SELECT_IS_WINSOCKET
filedes [0] = EV_WIN32_HANDLE_TO_FD (sock [0]);
filedes [1] = EV_WIN32_HANDLE_TO_FD (sock [1]);
#else
/* when select isn't winsocket, we also expect socket, connect, accept etc.
* to work on fds */
filedes [0] = sock [0];
filedes [1] = sock [1];
#endif

return 0;

fail:
closesocket (listener);

if (sock [0] != INVALID_SOCKET) closesocket (sock [0]);
if (sock [1] != INVALID_SOCKET) closesocket (sock [1]);

return -1;
}

#undef pipe
#define pipe(filedes) ev_pipe (filedes)

#define EV_HAVE_EV_TIME 1
ev_tstamp
ev_time (void)
{
FILETIME ft;
ULARGE_INTEGER ui;

GetSystemTimeAsFileTime (&ft);
ui.u.LowPart = ft.dwLowDateTime;
ui.u.HighPart = ft.dwHighDateTime;

/* msvc cannot convert ulonglong to double... yes, it is that sucky */
return (LONGLONG)(ui.QuadPart - 116444736000000000) * 1e-7;
}

#endif

@@ -0,0 +1,196 @@
/* DO NOT EDIT, automatically generated by update_ev_wrap */
#ifndef EV_WRAP_H
#define EV_WRAP_H
#define now_floor ((loop)->now_floor)
#define mn_now ((loop)->mn_now)
#define rtmn_diff ((loop)->rtmn_diff)
#define io_blocktime ((loop)->io_blocktime)
#define timeout_blocktime ((loop)->timeout_blocktime)
#define backend ((loop)->backend)
#define activecnt ((loop)->activecnt)
#define loop_done ((loop)->loop_done)
#define backend_fd ((loop)->backend_fd)
#define backend_fudge ((loop)->backend_fudge)
#define backend_modify ((loop)->backend_modify)
#define backend_poll ((loop)->backend_poll)
#define anfds ((loop)->anfds)
#define anfdmax ((loop)->anfdmax)
#define pendings ((loop)->pendings)
#define pendingmax ((loop)->pendingmax)
#define pendingcnt ((loop)->pendingcnt)
#define pending_w ((loop)->pending_w)
#define rfeeds ((loop)->rfeeds)
#define rfeedmax ((loop)->rfeedmax)
#define rfeedcnt ((loop)->rfeedcnt)
#define evfd ((loop)->evfd)
#define evpipe ((loop)->evpipe)
#define pipe_w ((loop)->pipe_w)
#define curpid ((loop)->curpid)
#define postfork ((loop)->postfork)
#define vec_ri ((loop)->vec_ri)
#define vec_ro ((loop)->vec_ro)
#define vec_wi ((loop)->vec_wi)
#define vec_wo ((loop)->vec_wo)
#define vec_eo ((loop)->vec_eo)
#define vec_max ((loop)->vec_max)
#define polls ((loop)->polls)
#define pollmax ((loop)->pollmax)
#define pollcnt ((loop)->pollcnt)
#define pollidxs ((loop)->pollidxs)
#define pollidxmax ((loop)->pollidxmax)
#define epoll_events ((loop)->epoll_events)
#define epoll_eventmax ((loop)->epoll_eventmax)
#define epoll_eperms ((loop)->epoll_eperms)
#define epoll_epermcnt ((loop)->epoll_epermcnt)
#define epoll_epermmax ((loop)->epoll_epermmax)
#define kqueue_changes ((loop)->kqueue_changes)
#define kqueue_changemax ((loop)->kqueue_changemax)
#define kqueue_changecnt ((loop)->kqueue_changecnt)
#define kqueue_events ((loop)->kqueue_events)
#define kqueue_eventmax ((loop)->kqueue_eventmax)
#define port_events ((loop)->port_events)
#define port_eventmax ((loop)->port_eventmax)
#define iocp ((loop)->iocp)
#define fdchanges ((loop)->fdchanges)
#define fdchangemax ((loop)->fdchangemax)
#define fdchangecnt ((loop)->fdchangecnt)
#define timers ((loop)->timers)
#define timermax ((loop)->timermax)
#define timercnt ((loop)->timercnt)
#define periodics ((loop)->periodics)
#define periodicmax ((loop)->periodicmax)
#define periodiccnt ((loop)->periodiccnt)
#define idles ((loop)->idles)
#define idlemax ((loop)->idlemax)
#define idlecnt ((loop)->idlecnt)
#define idleall ((loop)->idleall)
#define prepares ((loop)->prepares)
#define preparemax ((loop)->preparemax)
#define preparecnt ((loop)->preparecnt)
#define checks ((loop)->checks)
#define checkmax ((loop)->checkmax)
#define checkcnt ((loop)->checkcnt)
#define forks ((loop)->forks)
#define forkmax ((loop)->forkmax)
#define forkcnt ((loop)->forkcnt)
#define cleanups ((loop)->cleanups)
#define cleanupmax ((loop)->cleanupmax)
#define cleanupcnt ((loop)->cleanupcnt)
#define async_pending ((loop)->async_pending)
#define asyncs ((loop)->asyncs)
#define asyncmax ((loop)->asyncmax)
#define asynccnt ((loop)->asynccnt)
#define fs_fd ((loop)->fs_fd)
#define fs_w ((loop)->fs_w)
#define fs_2625 ((loop)->fs_2625)
#define fs_hash ((loop)->fs_hash)
#define sig_pending ((loop)->sig_pending)
#define nosigmask ((loop)->nosigmask)
#define sigfd ((loop)->sigfd)
#define sigfd_w ((loop)->sigfd_w)
#define sigfd_set ((loop)->sigfd_set)
#define origflags ((loop)->origflags)
#define loop_count ((loop)->loop_count)
#define loop_depth ((loop)->loop_depth)
#define userdata ((loop)->userdata)
#define release_cb ((loop)->release_cb)
#define acquire_cb ((loop)->acquire_cb)
#define invoke_cb ((loop)->invoke_cb)
#else
#undef EV_WRAP_H
#undef now_floor
#undef mn_now
#undef rtmn_diff
#undef io_blocktime
#undef timeout_blocktime
#undef backend
#undef activecnt
#undef loop_done
#undef backend_fd
#undef backend_fudge
#undef backend_modify
#undef backend_poll
#undef anfds
#undef anfdmax
#undef pendings
#undef pendingmax
#undef pendingcnt
#undef pending_w
#undef rfeeds
#undef rfeedmax
#undef rfeedcnt
#undef evfd
#undef evpipe
#undef pipe_w
#undef curpid
#undef postfork
#undef vec_ri
#undef vec_ro
#undef vec_wi
#undef vec_wo
#undef vec_eo
#undef vec_max
#undef polls
#undef pollmax
#undef pollcnt
#undef pollidxs
#undef pollidxmax
#undef epoll_events
#undef epoll_eventmax
#undef epoll_eperms
#undef epoll_epermcnt
#undef epoll_epermmax
#undef kqueue_changes
#undef kqueue_changemax
#undef kqueue_changecnt
#undef kqueue_events
#undef kqueue_eventmax
#undef port_events
#undef port_eventmax
#undef iocp
#undef fdchanges
#undef fdchangemax
#undef fdchangecnt
#undef timers
#undef timermax
#undef timercnt
#undef periodics
#undef periodicmax
#undef periodiccnt
#undef idles
#undef idlemax
#undef idlecnt
#undef idleall
#undef prepares
#undef preparemax
#undef preparecnt
#undef checks
#undef checkmax
#undef checkcnt
#undef forks
#undef forkmax
#undef forkcnt
#undef cleanups
#undef cleanupmax
#undef cleanupcnt
#undef async_pending
#undef asyncs
#undef asyncmax
#undef asynccnt
#undef fs_fd
#undef fs_w
#undef fs_2625
#undef fs_hash
#undef sig_pending
#undef nosigmask
#undef sigfd
#undef sigfd_w
#undef sigfd_set
#undef origflags
#undef loop_count
#undef loop_depth
#undef userdata
#undef release_cb
#undef acquire_cb
#undef invoke_cb
#endif

Large diffs are not rendered by default.

@@ -0,0 +1,170 @@
/*
* libevent compatibility header, only core events supported
*
* Copyright (c) 2007,2008,2010 Marc Alexander Lehmann <libev@schmorp.de>
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modifica-
* tion, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MER-
* CHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
* EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPE-
* CIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTH-
* ERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
* OF THE POSSIBILITY OF SUCH DAMAGE.
*
* Alternatively, the contents of this file may be used under the terms of
* the GNU General Public License ("GPL") version 2 or any later version,
* in which case the provisions of the GPL are applicable instead of
* the above. If you wish to allow the use of your version of this file
* only under the terms of the GPL and not to allow others to use your
* version of this file under the BSD license, indicate your decision
* by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL. If you do not delete the
* provisions above, a recipient may use your version of this file under
* either the BSD or the GPL.
*/

#ifndef EVENT_H_
#define EVENT_H_

#ifdef EV_H
# include EV_H
#else
# include "ev.h"
#endif

#ifndef EVLOOP_NONBLOCK
# define EVLOOP_NONBLOCK EVRUN_NOWAIT
#endif
#ifndef EVLOOP_ONESHOT
# define EVLOOP_ONESHOT EVRUN_ONCE
#endif
#ifndef EV_TIMEOUT
# define EV_TIMEOUT EV_TIMER
#endif

#ifdef __cplusplus
extern "C" {
#endif

/* we need sys/time.h for struct timeval only */
#if !defined (WIN32) || defined (__MINGW32__)
# include <time.h> /* mingw seems to need this, for whatever reason */
# include <sys/time.h>
#endif

struct event_base;

#define EVLIST_TIMEOUT 0x01
#define EVLIST_INSERTED 0x02
#define EVLIST_SIGNAL 0x04
#define EVLIST_ACTIVE 0x08
#define EVLIST_INTERNAL 0x10
#define EVLIST_INIT 0x80

struct event
{
/* libev watchers we map onto */
union {
struct ev_io io;
struct ev_signal sig;
} iosig;
struct ev_timer to;

/* compatibility slots */
struct event_base *ev_base;
void (*ev_callback)(int, short, void *arg);
void *ev_arg;
int ev_fd;
int ev_pri;
int ev_res;
int ev_flags;
short ev_events;
};

#define EV_READ EV_READ
#define EV_WRITE EV_WRITE
#define EV_PERSIST 0x10

#define EVENT_SIGNAL(ev) ((int) (ev)->ev_fd)
#define EVENT_FD(ev) ((int) (ev)->ev_fd)

#define event_initialized(ev) ((ev)->ev_flags & EVLIST_INIT)

#define evtimer_add(ev,tv) event_add (ev, tv)
#define evtimer_set(ev,cb,data) event_set (ev, -1, 0, cb, data)
#define evtimer_del(ev) event_del (ev)
#define evtimer_pending(ev,tv) event_pending (ev, EV_TIMEOUT, tv)
#define evtimer_initialized(ev) event_initialized (ev)

#define timeout_add(ev,tv) evtimer_add (ev, tv)
#define timeout_set(ev,cb,data) evtimer_set (ev, cb, data)
#define timeout_del(ev) evtimer_del (ev)
#define timeout_pending(ev,tv) evtimer_pending (ev, tv)
#define timeout_initialized(ev) evtimer_initialized (ev)

#define signal_add(ev,tv) event_add (ev, tv)
#define signal_set(ev,sig,cb,data) event_set (ev, sig, EV_SIGNAL | EV_PERSIST, cb, data)
#define signal_del(ev) event_del (ev)
#define signal_pending(ev,tv) event_pending (ev, EV_SIGNAL, tv)
#define signal_initialized(ev) event_initialized (ev)

const char *event_get_version (void);
const char *event_get_method (void);

void *event_init (void);
void event_base_free (struct event_base *base);

#define EVLOOP_ONCE EVLOOP_ONESHOT
int event_loop (int);
int event_loopexit (struct timeval *tv);
int event_dispatch (void);

#define _EVENT_LOG_DEBUG 0
#define _EVENT_LOG_MSG 1
#define _EVENT_LOG_WARN 2
#define _EVENT_LOG_ERR 3
typedef void (*event_log_cb)(int severity, const char *msg);
void event_set_log_callback(event_log_cb cb);

void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg);
int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);

int event_add (struct event *ev, struct timeval *tv);
int event_del (struct event *ev);
void event_active (struct event *ev, int res, short ncalls); /* ncalls is being ignored */

int event_pending (struct event *ev, short, struct timeval *tv);

int event_priority_init (int npri);
int event_priority_set (struct event *ev, int pri);

int event_base_set (struct event_base *base, struct event *ev);
int event_base_loop (struct event_base *base, int);
int event_base_loopexit (struct event_base *base, struct timeval *tv);
int event_base_dispatch (struct event_base *base);
int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv);
int event_base_priority_init (struct event_base *base, int fd);

/* next line is different in the libevent+libev version */
/*libevent-include*/

#ifdef __cplusplus
}
#endif

#endif

@@ -0,0 +1,294 @@
#!/bin/sh
#
# install - install a program, script, or datafile
#
# This originates from X11R5 (mit/util/scripts/install.sh), which was
# later released in X11R6 (xc/config/util/install.sh) with the
# following copyright and license.
#
# Copyright (C) 1994 X Consortium
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
#
# Except as contained in this notice, the name of the X Consortium shall not
# be used in advertising or otherwise to promote the sale, use or other deal-
# ings in this Software without prior written authorization from the X Consor-
# tium.
#
#
# FSF changes to this file are in the public domain.
#
# Calling this script install-sh is preferred over install.sh, to prevent
# `make' implicit rules from creating a file called install from it
# when there is no Makefile.
#
# This script is compatible with the BSD install script, but was written
# from scratch. It can only install one file at a time, a restriction
# shared with many OS's install programs.


# set DOITPROG to echo to test this script

# Don't use :- since 4.3BSD and earlier shells don't like it.
doit="${DOITPROG-}"


# put in absolute paths if you don't have them in your path; or use env. vars.

mvprog="${MVPROG-mv}"
cpprog="${CPPROG-cp}"
chmodprog="${CHMODPROG-chmod}"
chownprog="${CHOWNPROG-chown}"
chgrpprog="${CHGRPPROG-chgrp}"
stripprog="${STRIPPROG-strip}"
rmprog="${RMPROG-rm}"
mkdirprog="${MKDIRPROG-mkdir}"

transformbasename=""
transform_arg=""
instcmd="$mvprog"
chmodcmd="$chmodprog 0755"
chowncmd=""
chgrpcmd=""
stripcmd=""
rmcmd="$rmprog -f"
mvcmd="$mvprog"
src=""
dst=""
dir_arg=""

while [ x"$1" != x ]; do
case $1 in
-c) instcmd=$cpprog
shift
continue;;

-d) dir_arg=true
shift
continue;;

-m) chmodcmd="$chmodprog $2"
shift
shift
continue;;

-o) chowncmd="$chownprog $2"
shift
shift
continue;;

-g) chgrpcmd="$chgrpprog $2"
shift
shift
continue;;

-s) stripcmd=$stripprog
shift
continue;;

-t=*) transformarg=`echo $1 | sed 's/-t=//'`
shift
continue;;

-b=*) transformbasename=`echo $1 | sed 's/-b=//'`
shift
continue;;

*) if [ x"$src" = x ]
then
src=$1
else
# this colon is to work around a 386BSD /bin/sh bug
:
dst=$1
fi
shift
continue;;
esac
done

if [ x"$src" = x ]
then
echo "$0: no input file specified" >&2
exit 1
else
:
fi

if [ x"$dir_arg" != x ]; then
dst=$src
src=""

if [ -d "$dst" ]; then
instcmd=:
chmodcmd=""
else
instcmd=$mkdirprog
fi
else

# Waiting for this to be detected by the "$instcmd $src $dsttmp" command
# might cause directories to be created, which would be especially bad
# if $src (and thus $dsttmp) contains '*'.

if [ -f "$src" ] || [ -d "$src" ]
then
:
else
echo "$0: $src does not exist" >&2
exit 1
fi

if [ x"$dst" = x ]
then
echo "$0: no destination specified" >&2
exit 1
else
:
fi

# If destination is a directory, append the input filename; if your system
# does not like double slashes in filenames, you may need to add some logic

if [ -d "$dst" ]
then
dst=$dst/`basename "$src"`
else
:
fi
fi

## this sed command emulates the dirname command
dstdir=`echo "$dst" | sed -e 's,[^/]*$,,;s,/$,,;s,^$,.,'`

# Make sure that the destination directory exists.
# this part is taken from Noah Friedman's mkinstalldirs script

# Skip lots of stat calls in the usual case.
if [ ! -d "$dstdir" ]; then
defaultIFS='
'
IFS="${IFS-$defaultIFS}"

oIFS=$IFS
# Some sh's can't handle IFS=/ for some reason.
IFS='%'
set - `echo "$dstdir" | sed -e 's@/@%@g' -e 's@^%@/@'`
IFS=$oIFS

pathcomp=''

while [ $# -ne 0 ] ; do
pathcomp=$pathcomp$1
shift

if [ ! -d "$pathcomp" ] ;
then
$mkdirprog "$pathcomp"
else
:
fi

pathcomp=$pathcomp/
done
fi

if [ x"$dir_arg" != x ]
then
$doit $instcmd "$dst" &&

if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dst"; else : ; fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dst"; else : ; fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dst"; else : ; fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dst"; else : ; fi
else

# If we're going to rename the final executable, determine the name now.

if [ x"$transformarg" = x ]
then
dstfile=`basename "$dst"`
else
dstfile=`basename "$dst" $transformbasename |
sed $transformarg`$transformbasename
fi

# don't allow the sed command to completely eliminate the filename

if [ x"$dstfile" = x ]
then
dstfile=`basename "$dst"`
else
:
fi

# Make a couple of temp file names in the proper directory.

dsttmp=$dstdir/_inst.$$_
rmtmp=$dstdir/_rm.$$_

# Trap to clean up temp files at exit.

trap 'status=$?; rm -f "$dsttmp" "$rmtmp" && exit $status' 0
trap '(exit $?); exit' 1 2 13 15

# Move or copy the file name to the temp name

$doit $instcmd "$src" "$dsttmp" &&

# and set any options; do chmod last to preserve setuid bits

# If any of these fail, we abort the whole thing. If we want to
# ignore errors from any of these, just make sure not to ignore
# errors from the above "$doit $instcmd $src $dsttmp" command.

if [ x"$chowncmd" != x ]; then $doit $chowncmd "$dsttmp"; else :;fi &&
if [ x"$chgrpcmd" != x ]; then $doit $chgrpcmd "$dsttmp"; else :;fi &&
if [ x"$stripcmd" != x ]; then $doit $stripcmd "$dsttmp"; else :;fi &&
if [ x"$chmodcmd" != x ]; then $doit $chmodcmd "$dsttmp"; else :;fi &&

# Now remove or move aside any old file at destination location. We try this
# two ways since rm can't unlink itself on some systems and the destination
# file might be busy for other reasons. In this case, the final cleanup
# might fail but the new file should still install successfully.

{
if [ -f "$dstdir/$dstfile" ]
then
$doit $rmcmd -f "$dstdir/$dstfile" 2>/dev/null ||
$doit $mvcmd -f "$dstdir/$dstfile" "$rmtmp" 2>/dev/null ||
{
echo "$0: cannot unlink or rename $dstdir/$dstfile" >&2
(exit 1); exit
}
else
:
fi
} &&

# Now rename the file to the real destination.

$doit $mvcmd "$dsttmp" "$dstdir/$dstfile"

fi &&

# The final little trick to "correctly" pass the exit status to the exit trap.

{
(exit 0); exit
}
@@ -0,0 +1,39 @@
dnl this file is part of libev, do not make local modifications
dnl http://software.schmorp.de/pkg/libev

dnl libev support
AC_CHECK_HEADERS(sys/inotify.h sys/epoll.h sys/event.h port.h poll.h sys/select.h sys/eventfd.h sys/signalfd.h)

AC_CHECK_FUNCS(inotify_init epoll_ctl kqueue port_create poll select eventfd signalfd)

AC_CHECK_FUNCS(clock_gettime, [], [
dnl on linux, try syscall wrapper first
if test $(uname) = Linux; then
AC_MSG_CHECKING(for clock_gettime syscall)
AC_LINK_IFELSE([AC_LANG_PROGRAM(
[#include <unistd.h>
#include <sys/syscall.h>
#include <time.h>],
[struct timespec ts; int status = syscall (SYS_clock_gettime, CLOCK_REALTIME, &ts)])],
[ac_have_clock_syscall=1
AC_DEFINE(HAVE_CLOCK_SYSCALL, 1, "use syscall interface for clock_gettime")
AC_MSG_RESULT(yes)],
[AC_MSG_RESULT(no)])
fi
if test -z "$LIBEV_M4_AVOID_LIBRT" && test -z "$ac_have_clock_syscall"; then
AC_CHECK_LIB(rt, clock_gettime)
unset ac_cv_func_clock_gettime
AC_CHECK_FUNCS(clock_gettime)
fi
])

AC_CHECK_FUNCS(nanosleep, [], [
if test -z "$LIBEV_M4_AVOID_LIBRT"; then
AC_CHECK_LIB(rt, nanosleep)
unset ac_cv_func_nanosleep
AC_CHECK_FUNCS(nanosleep)
fi
])

AC_CHECK_LIB(m, ceil)

Large diffs are not rendered by default.

@@ -0,0 +1,336 @@
#! /bin/sh
# Common stub for a few missing GNU programs while installing.
# Copyright (C) 1996, 1997, 1999, 2000, 2002, 2003 Free Software Foundation, Inc.
# Originally by Fran,cois Pinard <pinard@iro.umontreal.ca>, 1996.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2, or (at your option)
# any later version.

# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.

# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
# 02111-1307, USA.

# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
# configuration script generated by Autoconf, you may include it under
# the same distribution terms that you use for the rest of that program.

if test $# -eq 0; then
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
fi

run=:

# In the cases where this matters, `missing' is being run in the
# srcdir already.
if test -f configure.ac; then
configure_ac=configure.ac
else
configure_ac=configure.in
fi

case "$1" in
--run)
# Try to run requested program, and just exit if it succeeds.
run=
shift
"$@" && exit 0
;;
esac

# If it does not exist, or fails to run (possibly an outdated version),
# try to emulate it.
case "$1" in

-h|--h|--he|--hel|--help)
echo "\
$0 [OPTION]... PROGRAM [ARGUMENT]...
Handle \`PROGRAM [ARGUMENT]...' for when PROGRAM is missing, or return an
error status if there is no known handling for PROGRAM.
Options:
-h, --help display this help and exit
-v, --version output version information and exit
--run try to run the given command, and emulate it if it fails
Supported PROGRAM values:
aclocal touch file \`aclocal.m4'
autoconf touch file \`configure'
autoheader touch file \`config.h.in'
automake touch all \`Makefile.in' files
bison create \`y.tab.[ch]', if possible, from existing .[ch]
flex create \`lex.yy.c', if possible, from existing .c
help2man touch the output file
lex create \`lex.yy.c', if possible, from existing .c
makeinfo touch the output file
tar try tar, gnutar, gtar, then tar without non-portable flags
yacc create \`y.tab.[ch]', if possible, from existing .[ch]"
;;

-v|--v|--ve|--ver|--vers|--versi|--versio|--version)
echo "missing 0.4 - GNU automake"
;;

-*)
echo 1>&2 "$0: Unknown \`$1' option"
echo 1>&2 "Try \`$0 --help' for more information"
exit 1
;;

aclocal*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi

echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acinclude.m4' or \`${configure_ac}'. You might want
to install the \`Automake' and \`Perl' packages. Grab them from
any GNU archive site."
touch aclocal.m4
;;

autoconf)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi

echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`${configure_ac}'. You might want to install the
\`Autoconf' and \`GNU m4' packages. Grab them from any GNU
archive site."
touch configure
;;

autoheader)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi

echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`acconfig.h' or \`${configure_ac}'. You might want
to install the \`Autoconf' and \`GNU m4' packages. Grab them
from any GNU archive site."
files=`sed -n 's/^[ ]*A[CM]_CONFIG_HEADER(\([^)]*\)).*/\1/p' ${configure_ac}`
test -z "$files" && files="config.h"
touch_files=
for f in $files; do
case "$f" in
*:*) touch_files="$touch_files "`echo "$f" |
sed -e 's/^[^:]*://' -e 's/:.*//'`;;
*) touch_files="$touch_files $f.in";;
esac
done
touch $touch_files
;;

automake*)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi

echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified \`Makefile.am', \`acinclude.m4' or \`${configure_ac}'.
You might want to install the \`Automake' and \`Perl' packages.
Grab them from any GNU archive site."
find . -type f -name Makefile.am -print |
sed 's/\.am$/.in/' |
while read f; do touch "$f"; done
;;

autom4te)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi

echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them.
You can get \`$1' as part of \`Autoconf' from any GNU
archive site."

file=`echo "$*" | sed -n 's/.*--output[ =]*\([^ ]*\).*/\1/p'`
test -z "$file" && file=`echo "$*" | sed -n 's/.*-o[ ]*\([^ ]*\).*/\1/p'`
if test -f "$file"; then
touch $file
else
test -z "$file" || exec >$file
echo "#! /bin/sh"
echo "# Created by GNU Automake missing as a replacement of"
echo "# $ $@"
echo "exit 0"
chmod +x $file
exit 1
fi
;;

bison|yacc)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.y' file. You may need the \`Bison' package
in order for those modifications to take effect. You can get
\`Bison' from any GNU archive site."
rm -f y.tab.c y.tab.h
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.y)
SRCFILE=`echo "$LASTARG" | sed 's/y$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.c
fi
SRCFILE=`echo "$LASTARG" | sed 's/y$/h/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" y.tab.h
fi
;;
esac
fi
if [ ! -f y.tab.h ]; then
echo >y.tab.h
fi
if [ ! -f y.tab.c ]; then
echo 'main() { return 0; }' >y.tab.c
fi
;;

lex|flex)
echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.l' file. You may need the \`Flex' package
in order for those modifications to take effect. You can get
\`Flex' from any GNU archive site."
rm -f lex.yy.c
if [ $# -ne 1 ]; then
eval LASTARG="\${$#}"
case "$LASTARG" in
*.l)
SRCFILE=`echo "$LASTARG" | sed 's/l$/c/'`
if [ -f "$SRCFILE" ]; then
cp "$SRCFILE" lex.yy.c
fi
;;
esac
fi
if [ ! -f lex.yy.c ]; then
echo 'main() { return 0; }' >lex.yy.c
fi
;;

help2man)
if test -z "$run" && ($1 --version) > /dev/null 2>&1; then
# We have it, but it failed.
exit 1
fi

echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a dependency of a manual page. You may need the
\`Help2man' package in order for those modifications to take
effect. You can get \`Help2man' from any GNU archive site."

file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed -n 's/.*--output=\([^ ]*\).*/\1/p'`
fi
if [ -f "$file" ]; then
touch $file
else
test -z "$file" || exec >$file
echo ".ab help2man is required to generate this page"
exit 1
fi
;;

makeinfo)
if test -z "$run" && (makeinfo --version) > /dev/null 2>&1; then
# We have makeinfo, but it failed.
exit 1
fi

echo 1>&2 "\
WARNING: \`$1' is missing on your system. You should only need it if
you modified a \`.texi' or \`.texinfo' file, or any other file
indirectly affecting the aspect of the manual. The spurious
call might also be the consequence of using a buggy \`make' (AIX,
DU, IRIX). You might want to install the \`Texinfo' package or
the \`GNU make' package. Grab either from any GNU archive site."
file=`echo "$*" | sed -n 's/.*-o \([^ ]*\).*/\1/p'`
if test -z "$file"; then
file=`echo "$*" | sed 's/.* \([^ ]*\) *$/\1/'`
file=`sed -n '/^@setfilename/ { s/.* \([^ ]*\) *$/\1/; p; q; }' $file`
fi
touch $file
;;

tar)
shift
if test -n "$run"; then
echo 1>&2 "ERROR: \`tar' requires --run"
exit 1
fi

# We have already tried tar in the generic part.
# Look for gnutar/gtar before invocation to avoid ugly error
# messages.
if (gnutar --version > /dev/null 2>&1); then
gnutar "$@" && exit 0
fi
if (gtar --version > /dev/null 2>&1); then
gtar "$@" && exit 0
fi
firstarg="$1"
if shift; then
case "$firstarg" in
*o*)
firstarg=`echo "$firstarg" | sed s/o//`
tar "$firstarg" "$@" && exit 0
;;
esac
case "$firstarg" in
*h*)
firstarg=`echo "$firstarg" | sed s/h//`
tar "$firstarg" "$@" && exit 0
;;
esac
fi

echo 1>&2 "\
WARNING: I can't seem to be able to run \`tar' with the given arguments.
You may want to install GNU tar or Free paxutils, or check the
command line arguments."
exit 1
;;

*)
echo 1>&2 "\
WARNING: \`$1' is needed, and you do not seem to have it handy on your
system. You might have modified some files without having the
proper tools for further handling them. Check the \`README' file,
it often tells you about the needed prerequisites for installing
this package. You may also peek at any GNU archive site, in case
some other package would contain this missing \`$1' program."
exit 1
;;
esac

exit 0
@@ -0,0 +1,111 @@
#! /bin/sh
# mkinstalldirs --- make directory hierarchy
# Author: Noah Friedman <friedman@prep.ai.mit.edu>
# Created: 1993-05-16
# Public domain

errstatus=0
dirmode=""

usage="\
Usage: mkinstalldirs [-h] [--help] [-m mode] dir ..."

# process command line arguments
while test $# -gt 0 ; do
case $1 in
-h | --help | --h*) # -h for help
echo "$usage" 1>&2
exit 0
;;
-m) # -m PERM arg
shift
test $# -eq 0 && { echo "$usage" 1>&2; exit 1; }
dirmode=$1
shift
;;
--) # stop option processing
shift
break
;;
-*) # unknown option
echo "$usage" 1>&2
exit 1
;;
*) # first non-opt arg
break
;;
esac
done

for file
do
if test -d "$file"; then
shift
else
break
fi
done

case $# in
0) exit 0 ;;
esac

case $dirmode in
'')
if mkdir -p -- . 2>/dev/null; then
echo "mkdir -p -- $*"
exec mkdir -p -- "$@"
fi
;;
*)
if mkdir -m "$dirmode" -p -- . 2>/dev/null; then
echo "mkdir -m $dirmode -p -- $*"
exec mkdir -m "$dirmode" -p -- "$@"
fi
;;
esac

for file
do
set fnord `echo ":$file" | sed -ne 's/^:\//#/;s/^://;s/\// /g;s/^#/\//;p'`
shift

pathcomp=
for d
do
pathcomp="$pathcomp$d"
case $pathcomp in
-*) pathcomp=./$pathcomp ;;
esac

if test ! -d "$pathcomp"; then
echo "mkdir $pathcomp"

mkdir "$pathcomp" || lasterr=$?

if test ! -d "$pathcomp"; then
errstatus=$lasterr
else
if test ! -z "$dirmode"; then
echo "chmod $dirmode $pathcomp"
lasterr=""
chmod "$dirmode" "$pathcomp" || lasterr=$?

if test ! -z "$lasterr"; then
errstatus=$lasterr
fi
fi
fi
fi

pathcomp="$pathcomp/"
done
done

exit $errstatus

# Local Variables:
# mode: shell-script
# sh-indentation: 2
# End:
# mkinstalldirs ends here
@@ -55,7 +55,7 @@ static char *process_title;


int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
return uv__kqueue_init(loop);
return 0;
}


@@ -235,26 +235,12 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
multiplier = ((uint64_t)1000L / ticks), cpuspeed, maxcpus,
cur = 0;
uv_cpu_info_t* cpu_info;
const char* maxcpus_key;
const char* cptimes_key;
char model[512];
long* cp_times;
int numcpus;
size_t size;
int i;

#if defined(__DragonFly__)
/* This is not quite correct but DragonFlyBSD doesn't seem to have anything
* comparable to kern.smp.maxcpus or kern.cp_times (kern.cp_time is a total,
* not per CPU). At least this stops uv_cpu_info() from failing completely.
*/
maxcpus_key = "hw.ncpu";
cptimes_key = "kern.cp_time";
#else
maxcpus_key = "kern.smp.maxcpus";
cptimes_key = "kern.cp_times";
#endif

size = sizeof(model);
if (sysctlbyname("hw.model", &model, &size, NULL, 0) < 0) {
return uv__new_sys_error(errno);
@@ -276,13 +262,19 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
free(*cpu_infos);
return uv__new_sys_error(errno);
}

/* kern.cp_times on FreeBSD i386 gives an array up to maxcpus instead of ncpu */
size = sizeof(maxcpus);
if (sysctlbyname(maxcpus_key, &maxcpus, &size, NULL, 0) < 0) {
#ifdef __DragonFly__
if (sysctlbyname("hw.ncpu", &maxcpus, &size, NULL, 0) < 0) {
free(*cpu_infos);
return uv__new_sys_error(errno);
}
#else
if (sysctlbyname("kern.smp.maxcpus", &maxcpus, &size, NULL, 0) < 0) {
free(*cpu_infos);
return uv__new_sys_error(errno);
}
#endif

size = maxcpus * CPUSTATES * sizeof(long);

@@ -292,7 +284,7 @@ uv_err_t uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
return uv__new_sys_error(ENOMEM);
}

if (sysctlbyname(cptimes_key, cp_times, &size, NULL, 0) < 0) {
if (sysctlbyname("kern.cp_times", cp_times, &size, NULL, 0) < 0) {
free(cp_times);
free(*cpu_infos);
return uv__new_sys_error(errno);
@@ -119,17 +119,14 @@ static ssize_t uv__fs_futime(uv_fs_t* req) {
ts[1].tv_sec = req->mtime;
ts[1].tv_nsec = (unsigned long)(req->mtime * 1000000) % 1000000 * 1000;
return uv__utimesat(req->file, NULL, ts, 0);
#elif defined(__APPLE__) \
|| defined(__DragonFly__) \
|| defined(__FreeBSD__) \
|| defined(__sun)
#elif HAVE_FUTIMES
struct timeval tv[2];
tv[0].tv_sec = req->atime;
tv[0].tv_usec = (unsigned long)(req->atime * 1000000) % 1000000;
tv[1].tv_sec = req->mtime;
tv[1].tv_usec = (unsigned long)(req->mtime * 1000000) % 1000000;
return futimes(req->file, tv);
#else
#else /* !HAVE_FUTIMES */
errno = ENOSYS;
return -1;
#endif
@@ -81,14 +81,12 @@ void uv__fsevents_cb(uv_async_t* cb, int status) {
handle = cb->data;

UV__FSEVENTS_WALK(handle, {
if (handle->event_watcher.fd != -1)
if (handle->fd != -1)
handle->cb(handle, event->path[0] ? event->path : NULL, event->events, 0);
});

if ((handle->flags & (UV_CLOSING | UV_CLOSED)) == 0 &&
handle->event_watcher.fd == -1) {
if ((handle->flags & (UV_CLOSING | UV_CLOSED)) == 0 && handle->fd == -1)
uv__fsevents_close(handle);
}
}


@@ -31,10 +31,13 @@
# define inline __inline
#endif

#undef HAVE_FUTIMES
#undef HAVE_KQUEUE
#undef HAVE_PORTS_FS

#if __linux__
# include "linux/syscalls.h"
# define HAVE_FUTIMES 1 /* emulated with utimesat() */
#endif /* __linux__ */

#if defined(__sun)
@@ -43,9 +46,22 @@
# ifdef PORT_SOURCE_FILE
# define HAVE_PORTS_FS 1
# endif
# define HAVE_FUTIMES 1
# define futimes(fd, tv) futimesat(fd, (void*)0, tv)
#endif /* __sun */

#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__sun)
# define HAVE_FUTIMES 1
#endif

/* FIXME exact copy of the #ifdef guard in uv-unix.h */
#if defined(__APPLE__) \
|| defined(__FreeBSD__) \
|| defined(__OpenBSD__) \
|| defined(__NetBSD__)
# define HAVE_KQUEUE 1
#endif

#if defined(__APPLE__) && !TARGET_OS_IPHONE
# include <CoreServices/CoreServices.h>
#endif
@@ -65,35 +81,9 @@
} \
while (0)

#if defined(__linux__)
# define UV__POLLIN UV__EPOLLIN
# define UV__POLLOUT UV__EPOLLOUT
# define UV__POLLERR UV__EPOLLERR
# define UV__POLLHUP UV__EPOLLHUP
#endif

#if defined(__sun)
# define UV__POLLIN POLLIN
# define UV__POLLOUT POLLOUT
# define UV__POLLERR POLLERR
# define UV__POLLHUP POLLHUP
#endif

#ifndef UV__POLLIN
# define UV__POLLIN 1
#endif

#ifndef UV__POLLOUT
# define UV__POLLOUT 2
#endif

#ifndef UV__POLLERR
# define UV__POLLERR 4
#endif

#ifndef UV__POLLHUP
# define UV__POLLHUP 8
#endif
#define UV__IO_READ EV_READ
#define UV__IO_WRITE EV_WRITE
#define UV__IO_ERROR EV_ERROR

/* handle flags */
enum {
@@ -127,12 +117,12 @@ int uv__dup(int fd);
int uv_async_stop(uv_async_t* handle);
void uv__make_close_pending(uv_handle_t* handle);

void uv__io_init(uv__io_t* w, uv__io_cb cb, int fd);
void uv__io_start(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__io_stop(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__io_feed(uv_loop_t* loop, uv__io_t* w);
int uv__io_active(const uv__io_t* w, unsigned int events);
void uv__io_poll(uv_loop_t* loop, int timeout); /* in milliseconds or -1 */
void uv__io_init(uv__io_t* handle, uv__io_cb cb, int fd, int events);
void uv__io_set(uv__io_t* handle, uv__io_cb cb, int fd, int events);
void uv__io_start(uv_loop_t* loop, uv__io_t* handle);
void uv__io_stop(uv_loop_t* loop, uv__io_t* handle);
void uv__io_feed(uv_loop_t* loop, uv__io_t* handle, int event);
int uv__io_active(uv__io_t* handle);

/* loop */
int uv__loop_init(uv_loop_t* loop, int default_loop);
@@ -150,13 +140,13 @@ void uv__stream_init(uv_loop_t* loop, uv_stream_t* stream,
uv_handle_type type);
int uv__stream_open(uv_stream_t*, int fd, int flags);
void uv__stream_destroy(uv_stream_t* stream);
void uv__server_io(uv_loop_t* loop, uv__io_t* w, unsigned int events);
void uv__server_io(uv_loop_t* loop, uv__io_t* watcher, int events);
int uv__accept(int sockfd);

/* tcp */
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb);
int uv__tcp_nodelay(int fd, int on);
int uv__tcp_keepalive(int fd, int on, unsigned int delay);
int uv__tcp_nodelay(uv_tcp_t* handle, int enable);
int uv__tcp_keepalive(uv_tcp_t* handle, int enable, unsigned int delay);

/* pipe */
int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb);
@@ -178,7 +168,6 @@ void uv__work_submit(uv_loop_t* loop,
void uv__work_done(uv_async_t* handle, int status);

/* platform specific */
int uv__kqueue_init(uv_loop_t* loop);
int uv__platform_loop_init(uv_loop_t* loop, int default_loop);
void uv__platform_loop_delete(uv_loop_t* loop);

@@ -29,254 +29,57 @@
#include <sys/sysctl.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <unistd.h>
#include <fcntl.h>
#include <time.h>

static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags);
static void uv__fs_event(EV_P_ ev_io* w, int revents);


int uv__kqueue_init(uv_loop_t* loop) {
loop->backend_fd = kqueue();

if (loop->backend_fd == -1)
return -1;

uv__cloexec(loop->backend_fd, 1);

return 0;
static void uv__fs_event_start(uv_fs_event_t* handle) {
ev_io_init(&handle->event_watcher,
uv__fs_event,
handle->fd,
EV_LIBUV_KQUEUE_HACK);
ev_io_start(handle->loop->ev, &handle->event_watcher);
}


void uv__io_poll(uv_loop_t* loop, int timeout) {
struct kevent events[1024];
struct kevent* ev;
struct timespec spec;
unsigned int nevents;
unsigned int revents;
ngx_queue_t* q;
uint64_t base;
uint64_t diff;
uv__io_t* w;
int filter;
int fflags;
int count;
int nfds;
int fd;
int op;
int i;

if (loop->nfds == 0) {
assert(ngx_queue_empty(&loop->watcher_queue));
return;
}

nevents = 0;

while (!ngx_queue_empty(&loop->watcher_queue)) {
q = ngx_queue_head(&loop->watcher_queue);
ngx_queue_remove(q);
ngx_queue_init(q);

w = ngx_queue_data(q, uv__io_t, watcher_queue);
assert(w->pevents != 0);
assert(w->fd >= 0);
assert(w->fd < (int) loop->nwatchers);

/* Filter out no-op changes. This is for compatibility with the event ports
* backend, see uv__io_start().
*/
if (w->events == w->pevents)
continue;

if ((w->events & UV__POLLIN) == 0 && (w->pevents & UV__POLLIN) != 0) {
filter = EVFILT_READ;
fflags = 0;
op = EV_ADD;

if (w->cb == uv__fs_event) {
filter = EVFILT_VNODE;
fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
| NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
op = EV_ADD | EV_ONESHOT; /* Stop the event from firing repeatedly. */
}

EV_SET(events + nevents, w->fd, filter, op, fflags, 0, 0);

if (++nevents == ARRAY_SIZE(events)) {
if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
abort();
nevents = 0;
}
}

if ((w->events & UV__POLLOUT) == 0 && (w->pevents & UV__POLLOUT) != 0) {
EV_SET(events + nevents, w->fd, EVFILT_WRITE, EV_ADD, 0, 0, 0);

if (++nevents == ARRAY_SIZE(events)) {
if (kevent(loop->backend_fd, events, nevents, NULL, 0, NULL))
abort();
nevents = 0;
}
}

w->events = w->pevents;
}

assert(timeout >= -1);
base = loop->time;
count = 48; /* Benchmarks suggest this gives the best throughput. */

for (;; nevents = 0) {
if (timeout != -1) {
spec.tv_sec = timeout / 1000;
spec.tv_nsec = (timeout % 1000) * 1000000;
}

nfds = kevent(loop->backend_fd,
events,
nevents,
events,
ARRAY_SIZE(events),
timeout == -1 ? NULL : &spec);

if (nfds == 0) {
assert(timeout != -1);
return;
}

if (nfds == -1) {
if (errno != EINTR)
abort();

if (timeout == 0)
return;

if (timeout == -1)
continue;

/* Interrupted by a signal. Update timeout and poll again. */
goto update_timeout;
}

nevents = 0;

for (i = 0; i < nfds; i++) {
ev = events + i;
fd = ev->ident;
w = loop->watchers[fd];

if (w == NULL) {
/* File descriptor that we've stopped watching, disarm it. */
/* TODO batch up */
struct kevent events[1];

EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL))
if (errno != EBADF && errno != ENOENT)
abort();

continue;
}

if (ev->filter == EVFILT_VNODE) {
assert(w->events == UV__POLLIN);
assert(w->pevents == UV__POLLIN);
w->cb(loop, w, ev->fflags); /* XXX always uv__fs_event() */
nevents++;
continue;
}

revents = 0;

if (ev->filter == EVFILT_READ) {
if (w->events & UV__POLLIN)
revents |= UV__POLLIN;
else {
/* TODO batch up */
struct kevent events[1];
EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) abort();
}
}

if (ev->filter == EVFILT_WRITE) {
if (w->events & UV__POLLOUT)
revents |= UV__POLLOUT;
else {
/* TODO batch up */
struct kevent events[1];
EV_SET(events + 0, fd, ev->filter, EV_DELETE, 0, 0, 0);
if (kevent(loop->backend_fd, events, 1, NULL, 0, NULL)) abort();
}
}

if (ev->flags & EV_ERROR)
revents |= UV__POLLERR;

if (revents == 0)
continue;

w->cb(loop, w, revents);
nevents++;
}

if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
/* Poll for more events but don't block this time. */
timeout = 0;
continue;
}
return;
}

if (timeout == 0)
return;

if (timeout == -1)
continue;

update_timeout:
assert(timeout > 0);

diff = uv_hrtime() / 1000000;
assert(diff >= base);
diff -= base;

if (diff >= (uint64_t) timeout)
return;

timeout -= diff;
}
static void uv__fs_event_stop(uv_fs_event_t* handle) {
ev_io_stop(handle->loop->ev, &handle->event_watcher);
}


static void uv__fs_event(uv_loop_t* loop, uv__io_t* w, unsigned int fflags) {
static void uv__fs_event(EV_P_ ev_io* w, int revents) {
uv_fs_event_t* handle;
struct kevent ev;
int events;

assert(revents == EV_LIBUV_KQUEUE_HACK);

handle = container_of(w, uv_fs_event_t, event_watcher);

if (fflags & (NOTE_ATTRIB | NOTE_EXTEND))
if (handle->fflags & (NOTE_ATTRIB | NOTE_EXTEND))
events = UV_CHANGE;
else
events = UV_RENAME;

handle->cb(handle, NULL, events, 0);

if (handle->event_watcher.fd == -1)
if (handle->fd == -1)
return;

/* Watcher operates in one-shot mode, re-arm it. */
fflags = NOTE_ATTRIB | NOTE_WRITE | NOTE_RENAME
| NOTE_DELETE | NOTE_EXTEND | NOTE_REVOKE;
/* File watcher operates in one-shot mode, re-arm it. */
uv__fs_event_stop(handle);
uv__fs_event_start(handle);
}


EV_SET(&ev, w->fd, EVFILT_VNODE, EV_ADD | EV_ONESHOT, fflags, 0, 0);
/* Called by libev, don't touch. */
void uv__kqueue_hack(EV_P_ int fflags, ev_io *w) {
uv_fs_event_t* handle;

if (kevent(loop->backend_fd, &ev, 1, NULL, 0, NULL))
abort();
handle = container_of(w, uv_fs_event_t, event_watcher);
handle->fflags = fflags;
}


@@ -285,10 +88,10 @@ int uv_fs_event_init(uv_loop_t* loop,
const char* filename,
uv_fs_event_cb cb,
int flags) {
int fd;
#if defined(__APPLE__)
struct stat statbuf;
#endif /* defined(__APPLE__) */
int fd;

/* TODO open asynchronously - but how do we report back errors? */
if ((fd = open(filename, O_RDONLY)) == -1) {
@@ -298,9 +101,10 @@ int uv_fs_event_init(uv_loop_t* loop,

uv__handle_init(loop, (uv_handle_t*)handle, UV_FS_EVENT);
uv__handle_start(handle); /* FIXME shouldn't start automatically */
uv__io_init(&handle->event_watcher, uv__fs_event, fd);
handle->filename = strdup(filename);
handle->fflags = 0;
handle->cb = cb;
handle->fd = fd;

#if defined(__APPLE__)
/* Nullify field to perform checks later */
@@ -320,7 +124,7 @@ int uv_fs_event_init(uv_loop_t* loop,
fallback:
#endif /* defined(__APPLE__) */

uv__io_start(loop, &handle->event_watcher, UV__POLLIN);
uv__fs_event_start(handle);

return 0;
}
@@ -329,16 +133,13 @@ int uv_fs_event_init(uv_loop_t* loop,
void uv__fs_event_close(uv_fs_event_t* handle) {
#if defined(__APPLE__)
if (uv__fsevents_close(handle))
uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
uv__fs_event_stop(handle);
#else
uv__io_stop(handle->loop, &handle->event_watcher, UV__POLLIN);
uv__fs_event_stop(handle);
#endif /* defined(__APPLE__) */

uv__handle_stop(handle);

free(handle->filename);
handle->filename = NULL;

close(handle->event_watcher.fd);
handle->event_watcher.fd = -1;
close(handle->fd);
handle->fd = -1;
}
@@ -64,9 +64,7 @@ static int compare_watchers(const struct watcher_list* a,
RB_GENERATE_STATIC(watcher_root, watcher_list, entry, compare_watchers)


static void uv__inotify_read(uv_loop_t* loop,
uv__io_t* w,
unsigned int revents);
static void uv__inotify_read(uv_loop_t* loop, uv__io_t* w, int revents);


static int new_inotify_fd(void) {
@@ -100,8 +98,11 @@ static int init_inotify(uv_loop_t* loop) {
return -1;
}

uv__io_init(&loop->inotify_read_watcher, uv__inotify_read, loop->inotify_fd);
uv__io_start(loop, &loop->inotify_read_watcher, UV__POLLIN);
uv__io_init(&loop->inotify_read_watcher,
uv__inotify_read,
loop->inotify_fd,
UV__IO_READ);
uv__io_start(loop, &loop->inotify_read_watcher);

return 0;
}
@@ -114,9 +115,7 @@ static struct watcher_list* find_watcher(uv_loop_t* loop, int wd) {
}


static void uv__inotify_read(uv_loop_t* loop,
uv__io_t* dummy,
unsigned int events) {
static void uv__inotify_read(uv_loop_t* loop, uv__io_t* dummy, int events) {
const struct uv__inotify_event* e;
struct watcher_list* w;
uv_fs_event_t* h;
@@ -78,183 +78,20 @@ static void free_args_mem(void) {


int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
int fd;

fd = uv__epoll_create1(UV__EPOLL_CLOEXEC);

/* epoll_create1() can fail either because it's not implemented (old kernel)
* or because it doesn't understand the EPOLL_CLOEXEC flag.
*/
if (fd == -1 && (errno == ENOSYS || errno == EINVAL)) {
fd = uv__epoll_create(256);

if (fd != -1)
uv__cloexec(fd, 1);
}

loop->backend_fd = fd;
loop->inotify_fd = -1;
loop->inotify_watchers = NULL;

if (fd == -1)
return -1;

loop->inotify_fd = -1;
return 0;
}


void uv__platform_loop_delete(uv_loop_t* loop) {
if (loop->inotify_fd == -1) return;
uv__io_stop(loop, &loop->inotify_read_watcher, UV__POLLIN);
uv__io_stop(loop, &loop->inotify_read_watcher);
close(loop->inotify_fd);
loop->inotify_fd = -1;
}


void uv__io_poll(uv_loop_t* loop, int timeout) {
struct uv__epoll_event events[1024];
struct uv__epoll_event* pe;
struct uv__epoll_event e;
ngx_queue_t* q;
uv__io_t* w;
uint64_t base;
uint64_t diff;
int nevents;
int count;
int nfds;
int fd;
int op;
int i;

if (loop->nfds == 0) {
assert(ngx_queue_empty(&loop->watcher_queue));
return;
}

while (!ngx_queue_empty(&loop->watcher_queue)) {
q = ngx_queue_head(&loop->watcher_queue);
ngx_queue_remove(q);
ngx_queue_init(q);

w = ngx_queue_data(q, uv__io_t, watcher_queue);
assert(w->pevents != 0);
assert(w->fd >= 0);
assert(w->fd < (int) loop->nwatchers);

/* Filter out no-op changes. This is for compatibility with the event ports
* backend, see the comment in uv__io_start().
*/
if (w->events == w->pevents)
continue;

e.events = w->pevents;
e.data = w->fd;

if (w->events == 0)
op = UV__EPOLL_CTL_ADD;
else
op = UV__EPOLL_CTL_MOD;

/* XXX Future optimization: do EPOLL_CTL_MOD lazily if we stop watching
* events, skip the syscall and squelch the events after epoll_wait().
*/
if (uv__epoll_ctl(loop->backend_fd, op, w->fd, &e)) {
if (errno != EEXIST)
abort();

assert(op == UV__EPOLL_CTL_ADD);

/* We've reactivated a file descriptor that's been watched before. */
if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_MOD, w->fd, &e))
abort();
}

w->events = w->pevents;
}

assert(timeout >= -1);
base = loop->time;
count = 48; /* Benchmarks suggest this gives the best throughput. */

for (;;) {
nfds = uv__epoll_wait(loop->backend_fd,
events,
ARRAY_SIZE(events),
timeout);

if (nfds == 0) {
assert(timeout != -1);
return;
}

if (nfds == -1) {
if (errno != EINTR)
abort();

if (timeout == -1)
continue;

if (timeout == 0)
return;

/* Interrupted by a signal. Update timeout and poll again. */
goto update_timeout;
}

nevents = 0;

for (i = 0; i < nfds; i++) {
pe = events + i;
fd = pe->data;

assert(fd >= 0);
assert((unsigned) fd < loop->nwatchers);

w = loop->watchers[fd];

if (w == NULL) {
/* File descriptor that we've stopped watching, disarm it. */
if (uv__epoll_ctl(loop->backend_fd, UV__EPOLL_CTL_DEL, fd, pe))
if (errno != EBADF && errno != ENOENT)
abort();

continue;
}

w->cb(loop, w, pe->events);
nevents++;
}

if (nevents != 0) {
if (nfds == ARRAY_SIZE(events) && --count != 0) {
/* Poll for more events but don't block this time. */
timeout = 0;
continue;
}
return;
}

if (timeout == 0)
return;

if (timeout == -1)
continue;

update_timeout:
assert(timeout > 0);

diff = uv_hrtime() / 1000000;
assert(diff >= base);
diff -= base;

if (diff >= (uint64_t) timeout)
return;

timeout -= diff;
}
}


uint64_t uv_hrtime() {
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC, &ts);
@@ -29,9 +29,16 @@

int uv__loop_init(uv_loop_t* loop, int default_loop) {
unsigned int i;
int flags;

uv__signal_global_once_init();

#if HAVE_KQUEUE
flags = EVBACKEND_KQUEUE;
#else
flags = EVFLAG_AUTO;
#endif

memset(loop, 0, sizeof(*loop));
RB_INIT(&loop->timer_handles);
ngx_queue_init(&loop->wq);
@@ -41,24 +48,15 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
ngx_queue_init(&loop->check_handles);
ngx_queue_init(&loop->prepare_handles);
ngx_queue_init(&loop->handle_queue);

loop->nfds = 0;
loop->watchers = NULL;
loop->nwatchers = 0;
ngx_queue_init(&loop->pending_queue);
ngx_queue_init(&loop->watcher_queue);

loop->closing_handles = NULL;
loop->time = uv_hrtime() / 1000000;
loop->async_pipefd[0] = -1;
loop->async_pipefd[1] = -1;
loop->signal_pipefd[0] = -1;
loop->signal_pipefd[1] = -1;
loop->backend_fd = -1;
loop->emfile_fd = -1;

if (uv__platform_loop_init(loop, default_loop))
return -1;
loop->ev = (default_loop ? ev_default_loop : ev_loop_new)(flags);
ev_set_userdata(loop->ev, loop);

uv_signal_init(loop, &loop->child_watcher);
uv__handle_unref(&loop->child_watcher);
@@ -76,13 +74,17 @@ int uv__loop_init(uv_loop_t* loop, int default_loop) {
uv__handle_unref(&loop->wq_async);
loop->wq_async.flags |= UV__HANDLE_INTERNAL;

if (uv__platform_loop_init(loop, default_loop))
return -1;

return 0;
}


void uv__loop_delete(uv_loop_t* loop) {
uv__signal_loop_cleanup(loop);
uv__platform_loop_delete(loop);
ev_loop_destroy(loop->ev);

if (loop->async_pipefd[0] != -1) {
close(loop->async_pipefd[0]);
@@ -99,23 +101,8 @@ void uv__loop_delete(uv_loop_t* loop) {
loop->emfile_fd = -1;
}

if (loop->backend_fd != -1) {
close(loop->backend_fd);
loop->backend_fd = -1;
}

uv_mutex_lock(&loop->wq_mutex);
assert(ngx_queue_empty(&loop->wq) && "thread pool work queue not empty!");
uv_mutex_unlock(&loop->wq_mutex);
uv_mutex_destroy(&loop->wq_mutex);

#if 0
assert(ngx_queue_empty(&loop->pending_queue));
assert(ngx_queue_empty(&loop->watcher_queue));
assert(loop->nfds == 0);
#endif

free(loop->watchers);
loop->watchers = NULL;
loop->nwatchers = 0;
}
@@ -48,7 +48,7 @@ static char *process_title;


int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
return uv__kqueue_init(loop);
return 0;
}


@@ -44,7 +44,7 @@ static char *process_title;


int uv__platform_loop_init(uv_loop_t* loop, int default_loop) {
return uv__kqueue_init(loop);
return 0;
}


@@ -29,7 +29,7 @@
#include <unistd.h>
#include <stdlib.h>

static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, unsigned int events);
static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events);


int uv_pipe_init(uv_loop_t* loop, uv_pipe_t* handle, int ipc) {
@@ -57,7 +57,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {
bound = 0;

/* Already bound? */
if (handle->io_watcher.fd >= 0) {
if (handle->fd >= 0) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
goto out;
}
@@ -89,7 +89,7 @@ int uv_pipe_bind(uv_pipe_t* handle, const char* name) {

/* Success. */
handle->pipe_fname = pipe_fname; /* Is a strdup'ed copy. */
handle->io_watcher.fd = sockfd;
handle->fd = sockfd;
status = 0;

out:
@@ -117,18 +117,21 @@ int uv_pipe_listen(uv_pipe_t* handle, int backlog, uv_connection_cb cb) {
saved_errno = errno;
status = -1;

if (handle->io_watcher.fd == -1) {
if (handle->fd == -1) {
uv__set_artificial_error(handle->loop, UV_EINVAL);
goto out;
}
assert(handle->io_watcher.fd >= 0);
assert(handle->fd >= 0);

if ((status = listen(handle->io_watcher.fd, backlog)) == -1) {
if ((status = listen(handle->fd, backlog)) == -1) {
uv__set_sys_error(handle->loop, errno);
} else {
handle->connection_cb = cb;
handle->io_watcher.cb = uv__pipe_accept;
uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN);
uv__io_init(&handle->read_watcher,
uv__pipe_accept,
handle->fd,
UV__IO_READ);
uv__io_start(handle->loop, &handle->read_watcher);
}

out:
@@ -172,11 +175,11 @@ void uv_pipe_connect(uv_connect_t* req,
int r;

saved_errno = errno;
new_sock = (handle->io_watcher.fd == -1);
new_sock = (handle->fd == -1);
err = -1;

if (new_sock)
if ((handle->io_watcher.fd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
if ((handle->fd = uv__socket(AF_UNIX, SOCK_STREAM, 0)) == -1)
goto out;

memset(&saddr, 0, sizeof saddr);
@@ -187,7 +190,7 @@ void uv_pipe_connect(uv_connect_t* req,
* is either there or not.
*/
do {
r = connect(handle->io_watcher.fd, (struct sockaddr*)&saddr, sizeof saddr);
r = connect(handle->fd, (struct sockaddr*)&saddr, sizeof saddr);
}
while (r == -1 && errno == EINTR);

@@ -196,11 +199,12 @@ void uv_pipe_connect(uv_connect_t* req,

if (new_sock)
if (uv__stream_open((uv_stream_t*)handle,
handle->io_watcher.fd,
handle->fd,
UV_STREAM_READABLE | UV_STREAM_WRITABLE))
goto out;

uv__io_start(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
uv__io_start(handle->loop, &handle->read_watcher);
uv__io_start(handle->loop, &handle->write_watcher);
err = 0;

out:
@@ -213,7 +217,7 @@ void uv_pipe_connect(uv_connect_t* req,
ngx_queue_init(&req->queue);

/* Run callback on next tick. */
uv__io_feed(handle->loop, &handle->io_watcher);
uv__io_feed(handle->loop, &handle->write_watcher, UV__IO_WRITE);

/* Mimic the Windows pipe implementation, always
* return 0 and let the callback handle errors.
@@ -223,17 +227,17 @@ void uv_pipe_connect(uv_connect_t* req,


/* TODO merge with uv__server_io()? */
static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, int events) {
uv_pipe_t* pipe;
int saved_errno;
int sockfd;

saved_errno = errno;
pipe = container_of(w, uv_pipe_t, io_watcher);
pipe = container_of(w, uv_pipe_t, read_watcher);

assert(pipe->type == UV_NAMED_PIPE);

sockfd = uv__accept(pipe->io_watcher.fd);
sockfd = uv__accept(pipe->fd);
if (sockfd == -1) {
if (errno != EAGAIN && errno != EWOULDBLOCK) {
uv__set_sys_error(pipe->loop, errno);
@@ -244,7 +248,7 @@ static void uv__pipe_accept(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
pipe->connection_cb((uv_stream_t*)pipe, 0);
if (pipe->accepted_fd == sockfd) {
/* The user hasn't called uv_accept() yet */
uv__io_stop(pipe->loop, &pipe->io_watcher, UV__POLLIN);
uv__io_stop(pipe->loop, &pipe->read_watcher);
}
}

@@ -27,24 +27,25 @@
#include <errno.h>


static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, int events) {
uv_poll_t* handle;
int pevents;

handle = container_of(w, uv_poll_t, io_watcher);

if (events & UV__POLLERR) {
uv__io_stop(loop, w, UV__POLLIN | UV__POLLOUT);
if (events & UV__IO_ERROR) {
/* An error happened. Libev has implicitly stopped the watcher, but we */
/* need to fix the refcount. */
uv__handle_stop(handle);
uv__set_sys_error(handle->loop, EBADF);
handle->poll_cb(handle, -1, 0);
return;
}

pevents = 0;
if (events & UV__POLLIN)
if (events & UV__IO_READ)
pevents |= UV_READABLE;
if (events & UV__POLLOUT)
if (events & UV__IO_WRITE)
pevents |= UV_WRITABLE;

handle->poll_cb(handle, 0, pevents);
@@ -53,8 +54,10 @@ static void uv__poll_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {

int uv_poll_init(uv_loop_t* loop, uv_poll_t* handle, int fd) {
uv__handle_init(loop, (uv_handle_t*) handle, UV_POLL);
uv__io_init(&handle->io_watcher, uv__poll_io, fd);
handle->fd = fd;
handle->poll_cb = NULL;
uv__io_init(&handle->io_watcher, uv__poll_io, fd, 0);

return 0;
}

@@ -66,7 +69,7 @@ int uv_poll_init_socket(uv_loop_t* loop, uv_poll_t* handle,


static void uv__poll_stop(uv_poll_t* handle) {
uv__io_stop(handle->loop, &handle->io_watcher, UV__POLLIN | UV__POLLOUT);
uv__io_stop(handle->loop, &handle->io_watcher);
uv__handle_stop(handle);
}

@@ -84,20 +87,23 @@ int uv_poll_start(uv_poll_t* handle, int pevents, uv_poll_cb poll_cb) {
assert((pevents & ~(UV_READABLE | UV_WRITABLE)) == 0);
assert(!(handle->flags & (UV_CLOSING | UV_CLOSED)));

uv__poll_stop(handle);

if (pevents == 0)
if (pevents == 0) {
uv__poll_stop(handle);
return 0;
}

events = 0;
if (pevents & UV_READABLE)
events |= UV__POLLIN;
events |= UV__IO_READ;
if (pevents & UV_WRITABLE)
events |= UV__POLLOUT;
events |= UV__IO_WRITE;

uv__io_stop(handle->loop, &handle->io_watcher);
uv__io_set(&handle->io_watcher, uv__poll_io, handle->fd, events);
uv__io_start(handle->loop, &handle->io_watcher);

uv__io_start(handle->loop, &handle->io_watcher, events);
uv__handle_start(handle);
handle->poll_cb = poll_cb;
uv__handle_start(handle);

return 0;
}
@@ -204,7 +204,7 @@ static int uv__process_init_stdio(uv_stdio_container_t* container, int fds[2]) {
if (container->flags & UV_INHERIT_FD) {
fd = container->data.fd;
} else {
fd = container->data.stream->io_watcher.fd;
fd = container->data.stream->fd;
}

if (fd == -1) {
@@ -38,7 +38,7 @@ RB_HEAD(uv__signal_tree_s, uv_signal_s);


static int uv__signal_unlock();
static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events);
static void uv__signal_event(uv_loop_t* loop, uv__io_t* watcher, int events);
static int uv__signal_compare(uv_signal_t* w1, uv_signal_t* w2);
static void uv__signal_stop(uv_signal_t* handle);

@@ -189,16 +189,17 @@ static uv_err_t uv__signal_register_handler(int signum) {
static void uv__signal_unregister_handler(int signum) {
/* When this function is called, the signal lock must be held. */
struct sigaction sa;
int r;

memset(&sa, 0, sizeof(sa));
sa.sa_handler = SIG_DFL;

r = sigaction(signum, &sa, NULL);
/* sigaction can only fail with EINVAL or EFAULT; an attempt to deregister a
* signal implies that it was successfully registered earlier, so EINVAL
* should never happen.
*/
if (sigaction(signum, &sa, NULL))
abort();
assert(r == 0);
}


@@ -212,8 +213,9 @@ static int uv__signal_loop_once_init(uv_loop_t* loop) {

uv__io_init(&loop->signal_io_watcher,
uv__signal_event,
loop->signal_pipefd[0]);
uv__io_start(loop, &loop->signal_io_watcher, UV__POLLIN);
loop->signal_pipefd[0],
UV__IO_READ);
uv__io_start(loop, &loop->signal_io_watcher);

return 0;
}
@@ -328,7 +330,7 @@ int uv_signal_start(uv_signal_t* handle, uv_signal_cb signal_cb, int signum) {
}


static void uv__signal_event(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
static void uv__signal_event(uv_loop_t* loop, uv__io_t* watcher, int events) {
uv__signal_msg_t* msg;
uv_signal_t* handle;
char buf[sizeof(uv__signal_msg_t) * 32];
@@ -437,7 +439,6 @@ static void uv__signal_stop(uv_signal_t* handle) {

removed_handle = RB_REMOVE(uv__signal_tree_s, &uv__signal_tree, handle);
assert(removed_handle == handle);
(void) removed_handle;

/* Check if there are other active signal watchers observing this signal. If
* not, unregister the signal handler.