Drop in libuv rev 2b5707d834a6b85b8e589ac04cb61a6db2dab94b
This commit is contained in:
parent
b6be83885f
commit
904f443fa9
81 changed files with 64837 additions and 0 deletions
28
src/rt/libuv/.gitignore
vendored
Normal file
28
src/rt/libuv/.gitignore
vendored
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
*.swp
|
||||
*.o
|
||||
*.lo
|
||||
*.la
|
||||
*.a
|
||||
*.opensdf
|
||||
*.orig
|
||||
*.sdf
|
||||
*.suo
|
||||
*.vcxproj.filters
|
||||
*.vcxproj.user
|
||||
ev/.deps/
|
||||
ev/.libs/
|
||||
ev/Makefile
|
||||
ev/config.h
|
||||
ev/config.log
|
||||
ev/config.status
|
||||
ev/libtool
|
||||
ev/stamp-h1
|
||||
ev/autom4te.cache
|
||||
/msvs/ipch/
|
||||
/build/
|
||||
test/run-tests
|
||||
test/run-benchmarks
|
||||
test/run-tests.exe
|
||||
test/run-benchmarks.exe
|
||||
test/run-benchmarks.dSYM/
|
||||
test/run-tests.dSYM/
|
||||
6
src/rt/libuv/AUTHORS
Normal file
6
src/rt/libuv/AUTHORS
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
# Authors ordered by first contribution.
|
||||
Ryan Dahl <ryan@joyent.com>
|
||||
Bert Belder <bertbelder@gmail.com>
|
||||
Josh Roesslein <jroesslein@gmail.com>
|
||||
Alan Gutierrez <alan@prettyrobots.com>
|
||||
Vanilla Hsu <vanilla@fatpipi.com>
|
||||
37
src/rt/libuv/LICENSE
Normal file
37
src/rt/libuv/LICENSE
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
libuv is part of the Node project: http://nodejs.org/
|
||||
libuv may be distributed alone under Node's license:
|
||||
|
||||
====
|
||||
|
||||
Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
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
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
IN THE SOFTWARE.
|
||||
|
||||
====
|
||||
|
||||
This license applies to all parts of libuv that are not externally
|
||||
maintained libraries.
|
||||
|
||||
The externally maintained libraries used by libuv are:
|
||||
|
||||
- tree.h (from FreeBSD), copyright Niels Provos. Two clause BSD license.
|
||||
|
||||
- ngx_queue.h (from Nginx), copyright Igor Sysoev. Two clause BSD license.
|
||||
|
||||
- libev, located at ev/ is copyright Marc Alexander Lehmann, and
|
||||
dual-licensed under the MIT license and GPL2.
|
||||
16
src/rt/libuv/README
Normal file
16
src/rt/libuv/README
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
This is the new networking layer for Node. Its purpose is to abstract
|
||||
IOCP on windows and libev on Unix systems. We intend to eventually contain
|
||||
all platform differences in this library.
|
||||
|
||||
http://nodejs.org/
|
||||
|
||||
(This was previously called liboio)
|
||||
|
||||
Supported Platforms:
|
||||
|
||||
Microsoft Windows operating systems since Windows XP sp2. It can be built
|
||||
with either Visual Studio or MinGW.
|
||||
|
||||
Linux 2.6 and MacOS using the GCC toolchain.
|
||||
|
||||
Solaris 121 and later using GCC toolchain.
|
||||
45
src/rt/libuv/config-mingw.mk
Normal file
45
src/rt/libuv/config-mingw.mk
Normal file
|
|
@ -0,0 +1,45 @@
|
|||
# Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
#
|
||||
# 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
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
# Use make -f Makefile.gcc PREFIX=i686-w64-mingw32-
|
||||
# for cross compilation
|
||||
CC = $(PREFIX)gcc
|
||||
AR = $(PREFIX)ar
|
||||
E=.exe
|
||||
|
||||
CFLAGS=-g --std=gnu89 -Wno-variadic-macros
|
||||
LINKFLAGS=-lm
|
||||
|
||||
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE # Need _GNU_SOURCE for strdup?
|
||||
RUNNER_LINKFLAGS=$(LINKFLAGS)
|
||||
RUNNER_LIBS=-lws2_32
|
||||
RUNNER_SRC=test/runner-win.c
|
||||
|
||||
uv.a: uv-win.o uv-common.o
|
||||
$(AR) rcs uv.a uv-win.o uv-common.o
|
||||
|
||||
uv-win.o: uv-win.c uv.h uv-win.h
|
||||
$(CC) $(CFLAGS) -c uv-win.c -o uv-win.o
|
||||
|
||||
uv-common.o: uv-common.c uv.h uv-win.h
|
||||
$(CC) $(CFLAGS) -c uv-common.c -o uv-common.o
|
||||
|
||||
distclean-platform:
|
||||
clean-platform:
|
||||
57
src/rt/libuv/config-unix.mk
Normal file
57
src/rt/libuv/config-unix.mk
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
# Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
#
|
||||
# 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
|
||||
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
# IN THE SOFTWARE.
|
||||
|
||||
CC = $(PREFIX)gcc
|
||||
AR = $(PREFIX)ar
|
||||
E=
|
||||
CFLAGS=--std=gnu89 -Wno-variadic-macros -g
|
||||
LINKFLAGS=-lm
|
||||
|
||||
ifeq (SunOS,$(uname_S))
|
||||
LINKFLAGS+=-lsocket -lnsl
|
||||
endif
|
||||
|
||||
# Need _GNU_SOURCE for strdup?
|
||||
RUNNER_CFLAGS=$(CFLAGS) -D_GNU_SOURCE
|
||||
|
||||
RUNNER_LINKFLAGS=$(LINKFLAGS) -pthread
|
||||
RUNNER_LIBS=
|
||||
RUNNER_SRC=test/runner-unix.c
|
||||
|
||||
uv.a: uv-unix.o uv-common.o ev/ev.o
|
||||
$(AR) rcs uv.a uv-unix.o uv-common.o ev/ev.o
|
||||
|
||||
uv-unix.o: uv-unix.c uv.h uv-unix.h
|
||||
$(CC) $(CFLAGS) -c uv-unix.c -o uv-unix.o
|
||||
|
||||
uv-common.o: uv-common.c uv.h uv-unix.h
|
||||
$(CC) $(CFLAGS) -c uv-common.c -o uv-common.o
|
||||
|
||||
ev/ev.o: ev/config.h ev/ev.c
|
||||
$(MAKE) -C ev
|
||||
|
||||
ev/config.h:
|
||||
cd ev && ./configure
|
||||
|
||||
clean-platform:
|
||||
$(MAKE) -C ev clean
|
||||
|
||||
distclean-platform:
|
||||
$(MAKE) -C ev distclean
|
||||
159
src/rt/libuv/desired-api.md
Normal file
159
src/rt/libuv/desired-api.md
Normal file
|
|
@ -0,0 +1,159 @@
|
|||
Warning: this is not actual API but desired API.
|
||||
|
||||
# `uv_handle_t`
|
||||
|
||||
This is the abstract base class of all types of handles. All handles have in
|
||||
common:
|
||||
|
||||
* When handles are initialized, the reference count to the event loop is
|
||||
increased by one.
|
||||
|
||||
* The user owns the `uv_handle_t` memory and is in charge of freeing it.
|
||||
|
||||
* In order to free resources associated with a handle, one must `uv_close()`
|
||||
and wait for the `uv_close_cb` callback. After the close callback has been
|
||||
made, the user is allowed to the `uv_handle_t` object.
|
||||
|
||||
* The `uv_close_cb` is always made directly off the event loop. That is, it
|
||||
is not called from `uv_close()`.
|
||||
|
||||
|
||||
|
||||
# `uv_tcp_server_t`
|
||||
|
||||
A TCP server class that is a subclass of `uv_handle_t`. This can be bound to
|
||||
an address and begin accepting new TCP sockets.
|
||||
|
||||
int uv_bind4(uv_tcp_server_t* tcp_server, struct sockaddr_in* address);
|
||||
int uv_bind6(uv_tcp_server_t* tcp_server, struct sockaddr_in6* address);
|
||||
|
||||
Binds the TCP server to an address. The `address` can be created with
|
||||
`uv_ip4_addr()`. Call this before `uv_listen()`
|
||||
|
||||
Returns zero on success, -1 on failure. Errors in order of least-seriousness:
|
||||
|
||||
* `UV_EADDRINUSE` There is already another socket bound to the specified
|
||||
address.
|
||||
|
||||
* `UV_EADDRNOTAVAIL` The `address` parameter is an IP address that is not
|
||||
|
||||
* `UV_EINVAL` The server is already bound to an address.
|
||||
|
||||
* `UV_EFAULT` Memory of `address` parameter is unintelligible.
|
||||
|
||||
|
||||
int uv_listen(uv_tcp_server_t*, int backlog, uv_connection_cb cb);
|
||||
|
||||
Begins listening for connections. The accept callback is level-triggered.
|
||||
|
||||
|
||||
int uv_accept(uv_tcp_server_t* server,
|
||||
uv_tcp_t* client);
|
||||
|
||||
Accepts a connection. This should be called after the accept callback is
|
||||
made. The `client` parameter should be uninitialized memory; `uv_accept` is
|
||||
used instead of `uv_tcp_init` for server-side `uv_tcp_t` initialization.
|
||||
|
||||
Return value 0 indicates success, -1 failure. Possible errors:
|
||||
|
||||
* `UV_EAGAIN` There are no connections. Wait for the `uv_connection_cb` callback
|
||||
to be called again.
|
||||
|
||||
* `UV_EFAULT` The memory of either `server` is unintelligible.
|
||||
|
||||
|
||||
|
||||
# `uv_stream_t`
|
||||
|
||||
An abstract subclass of `uv_handle_t`. Streams represent something that
|
||||
reads and/or writes data. Streams can be half or full-duplex. TCP sockets
|
||||
are streams, files are streams with offsets.
|
||||
|
||||
int uv_read_start(uv_stream_t* stream,
|
||||
uv_alloc_cb alloc_cb,
|
||||
uv_read_cb read_cb);
|
||||
|
||||
Starts the stream reading continuously. The `alloc_cb` is used to allow the
|
||||
user to implement various means of supplying the stream with buffers to
|
||||
fill. The `read_cb` returns buffers to the user filled with data.
|
||||
|
||||
Sometimes the buffers returned to the user do not contain data. This does
|
||||
not indicate EOF as in other systems. EOF is made via the `uv_eof_cb` which
|
||||
can be set like this `uv_set_eof_cb(stream, eof_cb);`
|
||||
|
||||
|
||||
int uv_read_stop(uv_stream_t* stream);
|
||||
|
||||
Stops reading from the stream.
|
||||
|
||||
int uv_write_req_init(uv_write_req_t*,
|
||||
uv_stream_t*,
|
||||
uv_buf_t bufs[],
|
||||
int butcnf);
|
||||
|
||||
Initiates a write request on a stream.
|
||||
|
||||
int uv_shutdown_req_init(uv_shutdown_req_t*, uv_stream_t*)
|
||||
|
||||
Initiates a shutdown of outgoing data once the write queue drains.
|
||||
|
||||
|
||||
|
||||
# `uv_tcp_t`
|
||||
|
||||
The TCP handle class represents one endpoint of a duplex TCP stream.
|
||||
`uv_tcp_t` is a subclass of `uv_stream_t`. A TCP handle can represent a
|
||||
client side connection (one that has been used with uv_connect_req_init`)
|
||||
or a server-side connection (one that was initialized with `uv_accept`)
|
||||
|
||||
int uv_connect_req_init(uv_connect_req_t* req,
|
||||
uv_tcp_t* socket,
|
||||
struct sockaddr* addr);
|
||||
|
||||
Initiates a request to open a connection.
|
||||
|
||||
|
||||
|
||||
# `uv_req_t`
|
||||
|
||||
Abstract class represents an asynchronous request. This is a subclass of `uv_handle_t`.
|
||||
|
||||
|
||||
# `uv_connect_req_t`
|
||||
|
||||
Subclass of `uv_req_t`. Represents a request for a TCP connection. Operates
|
||||
on `uv_tcp_t` handles. Like other types of requests the `close_cb` indicates
|
||||
completion of the request.
|
||||
|
||||
int uv_connect_req_init(uv_connect_req_t* req,
|
||||
uv_tcp_t* socket,
|
||||
struct sockaddr* addr);
|
||||
|
||||
Initializes the connection request. Returning 0 indicates success, -1 if
|
||||
there was an error. The following values can be retrieved from
|
||||
`uv_last_error` in the case of an error:
|
||||
|
||||
* ???
|
||||
|
||||
|
||||
# `uv_shutdown_req_t`
|
||||
|
||||
Subclass of `uv_req_t`. Represents an ongoing shutdown request. Once the
|
||||
write queue of the parent `uv_stream_t` is drained, the outbound data
|
||||
channel is shutdown. Once a shutdown request is initiated on a stream, the
|
||||
stream will allow no more writes.
|
||||
|
||||
int uv_shutdown_req_init(uv_shutdown_req_t*,
|
||||
uv_stream_t* parent);
|
||||
|
||||
Initializes the shutdown request.
|
||||
|
||||
|
||||
# `uv_write_req_t`
|
||||
|
||||
int uv_write_req_init(uv_write_req_t*,
|
||||
uv_stream_t*,
|
||||
uv_buf_t bufs[],
|
||||
int butcnf);
|
||||
|
||||
Initiates a write request on a stream.
|
||||
388
src/rt/libuv/ev/Changes
Normal file
388
src/rt/libuv/ev/Changes
Normal file
|
|
@ -0,0 +1,388 @@
|
|||
Revision history for libev, a high-performance and full-featured event loop.
|
||||
|
||||
4.04 Wed Feb 16 09:01:51 CET 2011
|
||||
- fix two problems in the native win32 backend, where reuse of fd's
|
||||
with different underlying handles caused handles not to be removed
|
||||
or added to the select set (analyzed and tested by Bert Belder).
|
||||
- do no rely on ceil() in ev_e?poll.c.
|
||||
- backport libev to HP-UX versions before 11 v3.
|
||||
- configure did not detect nanosleep and clock_gettime properly when
|
||||
they are available in the libc (as opposed to -lrt).
|
||||
|
||||
4.03 Tue Jan 11 14:37:25 CET 2011
|
||||
- officially support polling files with all backends.
|
||||
- support files, /dev/zero etc. the same way as select in the epoll
|
||||
backend, by generating events on our own.
|
||||
- ports backend: work around solaris bug 6874410 and many related ones
|
||||
(EINTR, maybe more), with no performance loss (note that the solaris
|
||||
bug report is actually wrong, reality is far more bizarre and broken
|
||||
than that).
|
||||
- define EV_READ/EV_WRITE as macros in event.h, as some programs use
|
||||
#ifdef to test for them.
|
||||
- new (experimental) function: ev_feed_signal.
|
||||
- new (to become default) EVFLAG_NOSIGMASK flag.
|
||||
- new EVBACKEND_MASK symbol.
|
||||
- updated COMMON IDIOMS SECTION.
|
||||
|
||||
4.01 Fri Nov 5 21:51:29 CET 2010
|
||||
- automake fucked it up, apparently, --add-missing -f is not quite enough
|
||||
to make it update its files, so 4.00 didn't install ev++.h and
|
||||
event.h on make install. grrr.
|
||||
- ev_loop(count|depth) didn't return anything (Robin Haberkorn).
|
||||
- change EV_UNDEF to 0xffffffff to silence some overzealous compilers.
|
||||
- use "(libev) " prefix for all libev error messages now.
|
||||
|
||||
4.00 Mon Oct 25 12:32:12 CEST 2010
|
||||
- "PORTING FROM LIBEV 3.X TO 4.X" (in ev.pod) is recommended reading.
|
||||
- ev_embed_stop did not correctly stop the watcher (very good
|
||||
testcase by Vladimir Timofeev).
|
||||
- ev_run will now always update the current loop time - it erroneously
|
||||
didn't when idle watchers were active, causing timers not to fire.
|
||||
- fix a bug where a timeout of zero caused the timer not to fire
|
||||
in the libevent emulation (testcase by Péter Szabó).
|
||||
- applied win32 fixes by Michael Lenaghan (also James Mansion).
|
||||
- replace EV_MINIMAL by EV_FEATURES.
|
||||
- prefer EPOLL_CTL_ADD over EPOLL_CTL_MOD in some more cases, as it
|
||||
seems the former is *much* faster than the latter.
|
||||
- linux kernel version detection (for inotify bug workarounds)
|
||||
did not work properly.
|
||||
- reduce the number of spurious wake-ups with the ports backend.
|
||||
- remove dependency on sys/queue.h on freebsd (patch by Vanilla Hsu).
|
||||
- do async init within ev_async_start, not ev_async_set, which avoids
|
||||
an API quirk where the set function must be called in the C++ API
|
||||
even when there is nothing to set.
|
||||
- add (undocumented) EV_ENABLE when adding events with kqueue,
|
||||
this might help with OS X, which seems to need it despite documenting
|
||||
not to need it (helpfully pointed out by Tilghman Lesher).
|
||||
- do not use poll by default on freebsd, it's broken (what isn't
|
||||
on freebsd...).
|
||||
- allow to embed epoll on kernels >= 2.6.32.
|
||||
- configure now prepends -O3, not appends it, so one can still
|
||||
override it.
|
||||
- ev.pod: greatly expanded the portability section, added a porting
|
||||
section, a description of watcher states and made lots of minor fixes.
|
||||
- disable poll backend on AIX, the poll header spams the namespace
|
||||
and it's not worth working around dead platforms (reported
|
||||
and analyzed by Aivars Kalvans).
|
||||
- improve header file compatibility of the standalone eventfd code
|
||||
in an obscure case.
|
||||
- implement EV_AVOID_STDIO option.
|
||||
- do not use sscanf to parse linux version number (smaller, faster,
|
||||
no sscanf dependency).
|
||||
- new EV_CHILD_ENABLE and EV_SIGNAL_ENABLE configurable settings.
|
||||
- update libev.m4 HAVE_CLOCK_SYSCALL test for newer glibcs.
|
||||
- add section on accept() problems to the manpage.
|
||||
- rename EV_TIMEOUT to EV_TIMER.
|
||||
- rename ev_loop_count/depth/verify/loop/unloop.
|
||||
- remove ev_default_destroy and ev_default_fork.
|
||||
- switch to two-digit minor version.
|
||||
- work around an apparent gentoo compiler bug.
|
||||
- define _DARWIN_UNLIMITED_SELECT. just so.
|
||||
- use enum instead of #define for most constants.
|
||||
- improve compatibility to older C++ compilers.
|
||||
- (experimental) ev_run/ev_default_loop/ev_break/ev_loop_new have now
|
||||
default arguments when compiled as C++.
|
||||
- enable automake dependency tracking.
|
||||
- ev_loop_new no longer leaks memory when loop creation failed.
|
||||
- new ev_cleanup watcher type.
|
||||
|
||||
3.9 Thu Dec 31 07:59:59 CET 2009
|
||||
- signalfd is no longer used by default and has to be requested
|
||||
explicitly - this means that easy to catch bugs become hard to
|
||||
catch race conditions, but the users have spoken.
|
||||
- point out the unspecified signal mask in the documentation, and
|
||||
that this is a race condition regardless of EV_SIGNALFD.
|
||||
- backport inotify code to C89.
|
||||
- inotify file descriptors could leak into child processes.
|
||||
- ev_stat watchers could keep an errornous extra ref on the loop,
|
||||
preventing exit when unregistering all watchers (testcases
|
||||
provided by ry@tinyclouds.org).
|
||||
- implement EV_WIN32_HANDLE_TO_FD and EV_WIN32_CLOSE_FD configuration
|
||||
symbols to make it easier for apps to do their own fd management.
|
||||
- support EV_IDLE_ENABLE being disabled in ev++.h
|
||||
(patch by Didier Spezia).
|
||||
- take advantage of inotify_init1, if available, to set cloexec/nonblock
|
||||
on fd creation, to avoid races.
|
||||
- the signal handling pipe wasn't always initialised under windows
|
||||
(analysed by lekma).
|
||||
- changed minimum glibc requirement from glibc 2.9 to 2.7, for
|
||||
signalfd.
|
||||
- add missing string.h include (Denis F. Latypoff).
|
||||
- only replace ev_stat.prev when we detect an actual difference,
|
||||
so prev is (almost) always different to attr. this might
|
||||
have caused the problems with 04_stat.t.
|
||||
- add ev::timer->remaining () method to C++ API.
|
||||
|
||||
3.8 Sun Aug 9 14:30:45 CEST 2009
|
||||
- incompatible change: do not necessarily reset signal handler
|
||||
to SIG_DFL when a sighandler is stopped.
|
||||
- ev_default_destroy did not properly free or zero some members,
|
||||
potentially causing crashes and memory corruption on repeated
|
||||
ev_default_destroy/ev_default_loop calls.
|
||||
- take advantage of signalfd on GNU/Linux systems.
|
||||
- document that the signal mask might be in an unspecified
|
||||
state when using libev's signal handling.
|
||||
- take advantage of some GNU/Linux calls to set cloexec/nonblock
|
||||
on fd creation, to avoid race conditions.
|
||||
|
||||
3.7 Fri Jul 17 16:36:32 CEST 2009
|
||||
- ev_unloop and ev_loop wrongly used a global variable to exit loops,
|
||||
instead of using a per-loop variable (bug caught by accident...).
|
||||
- the ev_set_io_collect_interval interpretation has changed.
|
||||
- add new functionality: ev_set_userdata, ev_userdata,
|
||||
ev_set_invoke_pending_cb, ev_set_loop_release_cb,
|
||||
ev_invoke_pending, ev_pending_count, together with a long example
|
||||
about thread locking.
|
||||
- add ev_timer_remaining (as requested by Denis F. Latypoff).
|
||||
- add ev_loop_depth.
|
||||
- calling ev_unloop in fork/prepare watchers will no longer poll
|
||||
for new events.
|
||||
- Denis F. Latypoff corrected many typos in example code snippets.
|
||||
- honor autoconf detection of EV_USE_CLOCK_SYSCALL, also double-
|
||||
check that the syscall number is available before trying to
|
||||
use it (reported by ry@tinyclouds).
|
||||
- use GetSystemTimeAsFileTime instead of _timeb on windows, for
|
||||
slightly higher accuracy.
|
||||
- properly declare ev_loop_verify and ev_now_update even when
|
||||
!EV_MULTIPLICITY.
|
||||
- do not compile in any priority code when EV_MAXPRI == EV_MINPRI.
|
||||
- support EV_MINIMAL==2 for a reduced API.
|
||||
- actually 0-initialise struct sigaction when installing signals.
|
||||
- add section on hibernate and stopped processes to ev_timer docs.
|
||||
|
||||
3.6 Tue Apr 28 02:49:30 CEST 2009
|
||||
- multiple timers becoming ready within an event loop iteration
|
||||
will be invoked in the "correct" order now.
|
||||
- do not leave the event loop early just because we have no active
|
||||
watchers, fixing a problem when embedding a kqueue loop
|
||||
that has active kernel events but no registered watchers
|
||||
(reported by blacksand blacksand).
|
||||
- correctly zero the idx values for arrays, so destroying and
|
||||
reinitialising the default loop actually works (patch by
|
||||
Malek Hadj-Ali).
|
||||
- implement ev_suspend and ev_resume.
|
||||
- new EV_CUSTOM revents flag for use by applications.
|
||||
- add documentation section about priorites.
|
||||
- add a glossary to the dcoumentation.
|
||||
- extend the ev_fork description slightly.
|
||||
- optimize a jump out of call_pending.
|
||||
|
||||
3.53 Sun Feb 15 02:38:20 CET 2009
|
||||
- fix a bug in event pipe creation on win32 that would cause a
|
||||
failed assertion on event loop creation (patch by Malek Hadj-Ali).
|
||||
- probe for CLOCK_REALTIME support at runtime as well and fall
|
||||
back to gettimeofday if there is an error, to support older
|
||||
operating systems with newer header files/libraries.
|
||||
- prefer gettimeofday over clock_gettime with USE_CLOCK_SYSCALL
|
||||
(default most everywhere), otherwise not.
|
||||
|
||||
3.52 Wed Jan 7 21:43:02 CET 2009
|
||||
- fix compilation of select backend in fd_set mode when NFDBITS is
|
||||
missing (to get it to compile on QNX, reported by Rodrigo Campos).
|
||||
- better select-nfds handling when select backend is in fd_set mode.
|
||||
- diagnose fd_set overruns when select backend is in fd_set mode.
|
||||
- due to a thinko, instead of disabling everything but
|
||||
select on the borked OS X platform, everything but select was
|
||||
allowed (reported by Emanuele Giaquinta).
|
||||
- actually verify that local and remote port are matching in
|
||||
libev's socketpair emulation, which makes denial-of-service
|
||||
attacks harder (but not impossible - it's windows). Make sure
|
||||
it even works under vista, which thinks that getpeer/sockname
|
||||
should return fantasy port numbers.
|
||||
- include "libev" in all assertion messages for potentially
|
||||
clearer diagnostics.
|
||||
- event_get_version (libevent compatibility) returned
|
||||
a useless string instead of the expected version string
|
||||
(patch by W.C.A. Wijngaards).
|
||||
|
||||
3.51 Wed Dec 24 23:00:11 CET 2008
|
||||
- fix a bug where an inotify watcher was added twice, causing
|
||||
freezes on hash collisions (reported and analysed by Graham Leggett).
|
||||
- new config symbol, EV_USE_CLOCK_SYSCALL, to make libev use
|
||||
a direct syscall - slower, but no dependency on librt et al.
|
||||
- assume negative return values != -1 signals success of port_getn
|
||||
(http://cvs.epicsol.org/cgi/viewcvs.cgi/epic5/source/newio.c?rev=1.52)
|
||||
(no known failure reports, but it doesn't hurt).
|
||||
- fork detection in ev_embed now stops and restarts the watcher
|
||||
automatically.
|
||||
- EXPERIMENTAL: default the method to operator () in ev++.h,
|
||||
to make it nicer to use functors (requested by Benedek László).
|
||||
- fixed const object callbacks in ev++.h.
|
||||
- replaced loop_ref argument of watcher.set (loop) by a direct
|
||||
ev_loop * in ev++.h, to avoid clashes with functor patch.
|
||||
- do not try to watch the empty string via inotify.
|
||||
- inotify watchers could be leaked under certain circumstances.
|
||||
- OS X 10.5 is actually even more broken than earlier versions,
|
||||
so fall back to select on that piece of garbage.
|
||||
- fixed some weirdness in the ev_embed documentation.
|
||||
|
||||
3.49 Wed Nov 19 11:26:53 CET 2008
|
||||
- ev_stat watchers will now use inotify as a mere hint on
|
||||
kernels <2.6.25, or if the filesystem is not in the
|
||||
"known to be good" list.
|
||||
- better mingw32 compatibility (it's not as borked as native win32)
|
||||
(analysed by Roger Pack).
|
||||
- include stdio.h in the example program, as too many people are
|
||||
confused by the weird C language otherwise. I guess the next thing
|
||||
I get told is that the "..." ellipses in the examples don't compile
|
||||
with their C compiler.
|
||||
|
||||
3.48 Thu Oct 30 09:02:37 CET 2008
|
||||
- further optimise away the EPOLL_CTL_ADD/MOD combo in the epoll
|
||||
backend by assuming the kernel event mask hasn't changed if
|
||||
ADD fails with EEXIST.
|
||||
- work around spurious event notification bugs in epoll by using
|
||||
a 32-bit generation counter. recreate kernel state if we receive
|
||||
spurious notifications or unwanted events. this is very costly,
|
||||
but I didn't come up with this horrible design.
|
||||
- use memset to initialise most arrays now and do away with the
|
||||
init functions.
|
||||
- expand time-out strategies into a "Be smart about timeouts" section.
|
||||
- drop the "struct" from all ev_watcher declarations in the
|
||||
documentation and did other clarifications (yeah, it was a mistake
|
||||
to have a struct AND a function called ev_loop).
|
||||
- fix a bug where ev_default would not initialise the default
|
||||
loop again after it was destroyed with ev_default_destroy.
|
||||
- rename syserr to ev_syserr to avoid name clashes when embedding,
|
||||
do similar changes for event.c.
|
||||
|
||||
3.45 Tue Oct 21 21:59:26 CEST 2008
|
||||
- disable inotify usage on linux <2.6.25, as it is broken
|
||||
(reported by Yoann Vandoorselaere).
|
||||
- ev_stat erroneously would try to add inotify watchers
|
||||
even when inotify wasn't available (this should only
|
||||
have a performance impact).
|
||||
- ev_once now passes both timeout and io to the callback if both
|
||||
occur concurrently, instead of giving timeouts precedence.
|
||||
- disable EV_USE_INOTIFY when sys/inotify.h is too old.
|
||||
|
||||
3.44 Mon Sep 29 05:18:39 CEST 2008
|
||||
- embed watchers now automatically invoke ev_loop_fork on the
|
||||
embedded loop when the parent loop forks.
|
||||
- new function: ev_now_update (loop).
|
||||
- verify_watcher was not marked static.
|
||||
- improve the "associating..." manpage section.
|
||||
- documentation tweaks here and there.
|
||||
|
||||
3.43 Sun Jul 6 05:34:41 CEST 2008
|
||||
- include more include files on windows to get struct _stati64
|
||||
(reported by Chris Hulbert, but doesn't quite fix his issue).
|
||||
- add missing #include <io.h> in ev.c on windows (reported by
|
||||
Matt Tolton).
|
||||
|
||||
3.42 Tue Jun 17 12:12:07 CEST 2008
|
||||
- work around yet another windows bug: FD_SET actually adds fd's
|
||||
multiple times to the fd_*SET*, despite official MSN docs claiming
|
||||
otherwise. Reported and well-analysed by Matt Tolton.
|
||||
- define NFDBITS to 0 when EV_SELECT_IS_WINSOCKET to make it compile
|
||||
(reported any analysed by Chris Hulbert).
|
||||
- fix a bug in ev_ebadf (this function is only used to catch
|
||||
programming errors in the libev user). reported by Matt Tolton.
|
||||
- fix a bug in fd_intern on win32 (could lead to compile errors
|
||||
under some circumstances, but would work correctly if it compiles).
|
||||
reported by Matt Tolton.
|
||||
- (try to) work around missing lstat on windows.
|
||||
- pass in the write fd set as except fd set under windows. windows
|
||||
is so uncontrollably lame that it requires this. this means that
|
||||
switching off oobinline is not supported (but tcp/ip doesn't
|
||||
have oob, so that would be stupid anyways.
|
||||
- use posix module symbol to auto-detect monotonic clock presence
|
||||
and some other default values.
|
||||
|
||||
3.41 Fri May 23 18:42:54 CEST 2008
|
||||
- work around an obscure bug in winsocket select: if you
|
||||
provide only empty fd sets then select returns WSAEINVAL. how sucky.
|
||||
- improve timer scheduling stability and reduce use of time_epsilon.
|
||||
- use 1-based 2-heap for EV_MINIMAL, simplifies code, reduces
|
||||
codesize and makes for better cache-efficiency.
|
||||
- use 3-based 4-heap for !EV_MINIMAL. this makes better use
|
||||
of cpu cache lines and gives better growth behaviour than
|
||||
2-based heaps.
|
||||
- cache timestamp within heap for !EV_MINIMAL, to avoid random
|
||||
memory accesses.
|
||||
- document/add EV_USE_4HEAP and EV_HEAP_CACHE_AT.
|
||||
- fix a potential aliasing issue in ev_timer_again.
|
||||
- add/document ev_periodic_at, retract direct access to ->at.
|
||||
- improve ev_stat docs.
|
||||
- add portability requirements section.
|
||||
- fix manpage headers etc.
|
||||
- normalise WSA error codes to lower range on windows.
|
||||
- add consistency check code that can be called automatically
|
||||
or on demand to check for internal structures (ev_loop_verify).
|
||||
|
||||
3.31 Wed Apr 16 20:45:04 CEST 2008
|
||||
- added last minute fix for ev_poll.c by Brandon Black.
|
||||
|
||||
3.3 Wed Apr 16 19:04:10 CEST 2008
|
||||
- event_base_loopexit should return 0 on success
|
||||
(W.C.A. Wijngaards).
|
||||
- added linux eventfd support.
|
||||
- try to autodetect epoll and inotify support
|
||||
by libc header version if not using autoconf.
|
||||
- new symbols: EV_DEFAULT_UC and EV_DEFAULT_UC_.
|
||||
- declare functions defined in ev.h as inline if
|
||||
C99 or gcc are available.
|
||||
- enable inlining with gcc versions 2 and 3.
|
||||
- work around broken poll implementations potentially
|
||||
not clearing revents field in ev_poll (Brandon Black)
|
||||
(no such systems are known at this time).
|
||||
- work around a bug in realloc on openbsd and darwin,
|
||||
also makes the erroneous valgrind complaints
|
||||
go away (noted by various people).
|
||||
- fix ev_async_pending, add c++ wrapper for ev_async
|
||||
(based on patch sent by Johannes Deisenhofer).
|
||||
- add sensible set method to ev::embed.
|
||||
- made integer constants type int in ev.h.
|
||||
|
||||
3.2 Wed Apr 2 17:11:19 CEST 2008
|
||||
- fix a 64 bit overflow issue in the select backend,
|
||||
by using fd_mask instead of int for the mask.
|
||||
- rename internal sighandler to avoid clash with very old perls.
|
||||
- entering ev_loop will not clear the ONESHOT or NONBLOCKING
|
||||
flags of any outer loops anymore.
|
||||
- add ev_async_pending.
|
||||
|
||||
3.1 Thu Mar 13 13:45:22 CET 2008
|
||||
- implement ev_async watchers.
|
||||
- only initialise signal pipe on demand.
|
||||
- make use of sig_atomic_t configurable.
|
||||
- improved documentation.
|
||||
|
||||
3.0 Mon Jan 28 13:14:47 CET 2008
|
||||
- API/ABI bump to version 3.0.
|
||||
- ev++.h includes "ev.h" by default now, not <ev.h>.
|
||||
- slightly improved documentation.
|
||||
- speed up signal detection after a fork.
|
||||
- only optionally return trace status changed in ev_child
|
||||
watchers.
|
||||
- experimental (and undocumented) loop wrappers for ev++.h.
|
||||
|
||||
2.01 Tue Dec 25 08:04:41 CET 2007
|
||||
- separate Changes file.
|
||||
- fix ev_path_set => ev_stat_set typo.
|
||||
- remove event_compat.h from the libev tarball.
|
||||
- change how include files are found.
|
||||
- doc updates.
|
||||
- update licenses, explicitly allow for GPL relicensing.
|
||||
|
||||
2.0 Sat Dec 22 17:47:03 CET 2007
|
||||
- new ev_sleep, ev_set_(io|timeout)_collect_interval.
|
||||
- removed epoll from embeddable fd set.
|
||||
- fix embed watchers.
|
||||
- renamed ev_embed.loop to other.
|
||||
- added exported Symbol tables.
|
||||
- undefine member wrapper macros at the end of ev.c.
|
||||
- respect EV_H in ev++.h.
|
||||
|
||||
1.86 Tue Dec 18 02:36:57 CET 2007
|
||||
- fix memleak on loop destroy (not relevant for perl).
|
||||
|
||||
1.85 Fri Dec 14 20:32:40 CET 2007
|
||||
- fix some aliasing issues w.r.t. timers and periodics
|
||||
(not relevant for perl).
|
||||
|
||||
(for historic versions refer to EV/Changes, found in the Perl interface)
|
||||
|
||||
0.1 Wed Oct 31 21:31:48 CET 2007
|
||||
- original version; hacked together in <24h.
|
||||
|
||||
36
src/rt/libuv/ev/LICENSE
Normal file
36
src/rt/libuv/ev/LICENSE
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
All files in libev are Copyright (C)2007,2008,2009 Marc Alexander Lehmann.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions are
|
||||
met:
|
||||
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
* 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 COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, 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 OTHERWISE) 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 package 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 package 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 in this and the other files of this package. If you do
|
||||
not delete the provisions above, a recipient may use your version of this
|
||||
file under either the BSD or the GPL.
|
||||
18
src/rt/libuv/ev/Makefile.am
Normal file
18
src/rt/libuv/ev/Makefile.am
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
AUTOMAKE_OPTIONS = foreign
|
||||
|
||||
VERSION_INFO = 4:0:0
|
||||
|
||||
EXTRA_DIST = LICENSE Changes libev.m4 autogen.sh \
|
||||
ev_vars.h ev_wrap.h \
|
||||
ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c \
|
||||
ev.3 ev.pod
|
||||
|
||||
man_MANS = ev.3
|
||||
|
||||
include_HEADERS = ev.h ev++.h event.h
|
||||
|
||||
lib_LTLIBRARIES = libev.la
|
||||
|
||||
libev_la_SOURCES = ev.c event.c
|
||||
libev_la_LDFLAGS = -version-info $(VERSION_INFO)
|
||||
|
||||
771
src/rt/libuv/ev/Makefile.in
Normal file
771
src/rt/libuv/ev/Makefile.in
Normal file
|
|
@ -0,0 +1,771 @@
|
|||
# Makefile.in generated by automake 1.11.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
|
||||
# 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software Foundation,
|
||||
# Inc.
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
# with or without modifications, as long as this notice is preserved.
|
||||
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY, to the extent permitted by law; without
|
||||
# even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||
# PARTICULAR PURPOSE.
|
||||
|
||||
@SET_MAKE@
|
||||
|
||||
|
||||
VPATH = @srcdir@
|
||||
pkgdatadir = $(datadir)/@PACKAGE@
|
||||
pkgincludedir = $(includedir)/@PACKAGE@
|
||||
pkglibdir = $(libdir)/@PACKAGE@
|
||||
pkglibexecdir = $(libexecdir)/@PACKAGE@
|
||||
am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd
|
||||
install_sh_DATA = $(install_sh) -c -m 644
|
||||
install_sh_PROGRAM = $(install_sh) -c
|
||||
install_sh_SCRIPT = $(install_sh) -c
|
||||
INSTALL_HEADER = $(INSTALL_DATA)
|
||||
transform = $(program_transform_name)
|
||||
NORMAL_INSTALL = :
|
||||
PRE_INSTALL = :
|
||||
POST_INSTALL = :
|
||||
NORMAL_UNINSTALL = :
|
||||
PRE_UNINSTALL = :
|
||||
POST_UNINSTALL = :
|
||||
build_triplet = @build@
|
||||
host_triplet = @host@
|
||||
subdir = .
|
||||
DIST_COMMON = README $(am__configure_deps) $(include_HEADERS) \
|
||||
$(srcdir)/Makefile.am $(srcdir)/Makefile.in \
|
||||
$(srcdir)/config.h.in $(top_srcdir)/configure config.guess \
|
||||
config.sub depcomp install-sh ltmain.sh missing mkinstalldirs
|
||||
ACLOCAL_M4 = $(top_srcdir)/aclocal.m4
|
||||
am__aclocal_m4_deps = $(top_srcdir)/libev.m4 \
|
||||
$(top_srcdir)/configure.ac
|
||||
am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \
|
||||
$(ACLOCAL_M4)
|
||||
am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \
|
||||
configure.lineno config.status.lineno
|
||||
mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
|
||||
CONFIG_HEADER = config.h
|
||||
CONFIG_CLEAN_FILES =
|
||||
CONFIG_CLEAN_VPATH_FILES =
|
||||
am__vpath_adj_setup = srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`;
|
||||
am__vpath_adj = case $$p in \
|
||||
$(srcdir)/*) f=`echo "$$p" | sed "s|^$$srcdirstrip/||"`;; \
|
||||
*) f=$$p;; \
|
||||
esac;
|
||||
am__strip_dir = f=`echo $$p | sed -e 's|^.*/||'`;
|
||||
am__install_max = 40
|
||||
am__nobase_strip_setup = \
|
||||
srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*|]/\\\\&/g'`
|
||||
am__nobase_strip = \
|
||||
for p in $$list; do echo "$$p"; done | sed -e "s|$$srcdirstrip/||"
|
||||
am__nobase_list = $(am__nobase_strip_setup); \
|
||||
for p in $$list; do echo "$$p $$p"; done | \
|
||||
sed "s| $$srcdirstrip/| |;"' / .*\//!s/ .*/ ./; s,\( .*\)/[^/]*$$,\1,' | \
|
||||
$(AWK) 'BEGIN { files["."] = "" } { files[$$2] = files[$$2] " " $$1; \
|
||||
if (++n[$$2] == $(am__install_max)) \
|
||||
{ print $$2, files[$$2]; n[$$2] = 0; files[$$2] = "" } } \
|
||||
END { for (dir in files) print dir, files[dir] }'
|
||||
am__base_list = \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;$$!N;s/\n/ /g' | \
|
||||
sed '$$!N;$$!N;$$!N;$$!N;s/\n/ /g'
|
||||
am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" \
|
||||
"$(DESTDIR)$(includedir)"
|
||||
LTLIBRARIES = $(lib_LTLIBRARIES)
|
||||
libev_la_LIBADD =
|
||||
am_libev_la_OBJECTS = ev.lo event.lo
|
||||
libev_la_OBJECTS = $(am_libev_la_OBJECTS)
|
||||
libev_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(libev_la_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
DEFAULT_INCLUDES = -I.@am__isrc@
|
||||
depcomp = $(SHELL) $(top_srcdir)/depcomp
|
||||
am__depfiles_maybe = depfiles
|
||||
am__mv = mv -f
|
||||
COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \
|
||||
$(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||
$(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS)
|
||||
CCLD = $(CC)
|
||||
LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \
|
||||
--mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \
|
||||
$(LDFLAGS) -o $@
|
||||
SOURCES = $(libev_la_SOURCES)
|
||||
DIST_SOURCES = $(libev_la_SOURCES)
|
||||
man3dir = $(mandir)/man3
|
||||
NROFF = nroff
|
||||
MANS = $(man_MANS)
|
||||
HEADERS = $(include_HEADERS)
|
||||
ETAGS = etags
|
||||
CTAGS = ctags
|
||||
DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
|
||||
distdir = $(PACKAGE)-$(VERSION)
|
||||
top_distdir = $(distdir)
|
||||
am__remove_distdir = \
|
||||
{ test ! -d "$(distdir)" \
|
||||
|| { find "$(distdir)" -type d ! -perm -200 -exec chmod u+w {} ';' \
|
||||
&& rm -fr "$(distdir)"; }; }
|
||||
DIST_ARCHIVES = $(distdir).tar.gz
|
||||
GZIP_ENV = --best
|
||||
distuninstallcheck_listfiles = find . -type f -print
|
||||
distcleancheck_listfiles = find . -type f -print
|
||||
ACLOCAL = @ACLOCAL@
|
||||
AMTAR = @AMTAR@
|
||||
AR = @AR@
|
||||
AUTOCONF = @AUTOCONF@
|
||||
AUTOHEADER = @AUTOHEADER@
|
||||
AUTOMAKE = @AUTOMAKE@
|
||||
AWK = @AWK@
|
||||
CC = @CC@
|
||||
CCDEPMODE = @CCDEPMODE@
|
||||
CFLAGS = @CFLAGS@
|
||||
CPP = @CPP@
|
||||
CPPFLAGS = @CPPFLAGS@
|
||||
CYGPATH_W = @CYGPATH_W@
|
||||
DEFS = @DEFS@
|
||||
DEPDIR = @DEPDIR@
|
||||
DSYMUTIL = @DSYMUTIL@
|
||||
DUMPBIN = @DUMPBIN@
|
||||
ECHO_C = @ECHO_C@
|
||||
ECHO_N = @ECHO_N@
|
||||
ECHO_T = @ECHO_T@
|
||||
EGREP = @EGREP@
|
||||
EXEEXT = @EXEEXT@
|
||||
FGREP = @FGREP@
|
||||
GREP = @GREP@
|
||||
INSTALL = @INSTALL@
|
||||
INSTALL_DATA = @INSTALL_DATA@
|
||||
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||
INSTALL_SCRIPT = @INSTALL_SCRIPT@
|
||||
INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
|
||||
LD = @LD@
|
||||
LDFLAGS = @LDFLAGS@
|
||||
LIBOBJS = @LIBOBJS@
|
||||
LIBS = @LIBS@
|
||||
LIBTOOL = @LIBTOOL@
|
||||
LIPO = @LIPO@
|
||||
LN_S = @LN_S@
|
||||
LTLIBOBJS = @LTLIBOBJS@
|
||||
MAINT = @MAINT@
|
||||
MAKEINFO = @MAKEINFO@
|
||||
MKDIR_P = @MKDIR_P@
|
||||
NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
PACKAGE = @PACKAGE@
|
||||
PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@
|
||||
PACKAGE_NAME = @PACKAGE_NAME@
|
||||
PACKAGE_STRING = @PACKAGE_STRING@
|
||||
PACKAGE_TARNAME = @PACKAGE_TARNAME@
|
||||
PACKAGE_URL = @PACKAGE_URL@
|
||||
PACKAGE_VERSION = @PACKAGE_VERSION@
|
||||
PATH_SEPARATOR = @PATH_SEPARATOR@
|
||||
RANLIB = @RANLIB@
|
||||
SED = @SED@
|
||||
SET_MAKE = @SET_MAKE@
|
||||
SHELL = @SHELL@
|
||||
STRIP = @STRIP@
|
||||
VERSION = @VERSION@
|
||||
abs_builddir = @abs_builddir@
|
||||
abs_srcdir = @abs_srcdir@
|
||||
abs_top_builddir = @abs_top_builddir@
|
||||
abs_top_srcdir = @abs_top_srcdir@
|
||||
ac_ct_CC = @ac_ct_CC@
|
||||
ac_ct_DUMPBIN = @ac_ct_DUMPBIN@
|
||||
am__include = @am__include@
|
||||
am__leading_dot = @am__leading_dot@
|
||||
am__quote = @am__quote@
|
||||
am__tar = @am__tar@
|
||||
am__untar = @am__untar@
|
||||
bindir = @bindir@
|
||||
build = @build@
|
||||
build_alias = @build_alias@
|
||||
build_cpu = @build_cpu@
|
||||
build_os = @build_os@
|
||||
build_vendor = @build_vendor@
|
||||
builddir = @builddir@
|
||||
datadir = @datadir@
|
||||
datarootdir = @datarootdir@
|
||||
docdir = @docdir@
|
||||
dvidir = @dvidir@
|
||||
exec_prefix = @exec_prefix@
|
||||
host = @host@
|
||||
host_alias = @host_alias@
|
||||
host_cpu = @host_cpu@
|
||||
host_os = @host_os@
|
||||
host_vendor = @host_vendor@
|
||||
htmldir = @htmldir@
|
||||
includedir = @includedir@
|
||||
infodir = @infodir@
|
||||
install_sh = @install_sh@
|
||||
libdir = @libdir@
|
||||
libexecdir = @libexecdir@
|
||||
localedir = @localedir@
|
||||
localstatedir = @localstatedir@
|
||||
lt_ECHO = @lt_ECHO@
|
||||
mandir = @mandir@
|
||||
mkdir_p = @mkdir_p@
|
||||
oldincludedir = @oldincludedir@
|
||||
pdfdir = @pdfdir@
|
||||
prefix = @prefix@
|
||||
program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
sbindir = @sbindir@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
target_alias = @target_alias@
|
||||
top_build_prefix = @top_build_prefix@
|
||||
top_builddir = @top_builddir@
|
||||
top_srcdir = @top_srcdir@
|
||||
AUTOMAKE_OPTIONS = foreign
|
||||
VERSION_INFO = 4:0:0
|
||||
EXTRA_DIST = LICENSE Changes libev.m4 autogen.sh \
|
||||
ev_vars.h ev_wrap.h \
|
||||
ev_epoll.c ev_select.c ev_poll.c ev_kqueue.c ev_port.c ev_win32.c \
|
||||
ev.3 ev.pod
|
||||
|
||||
man_MANS = ev.3
|
||||
include_HEADERS = ev.h ev++.h event.h
|
||||
lib_LTLIBRARIES = libev.la
|
||||
libev_la_SOURCES = ev.c event.c
|
||||
libev_la_LDFLAGS = -version-info $(VERSION_INFO)
|
||||
all: config.h
|
||||
$(MAKE) $(AM_MAKEFLAGS) all-am
|
||||
|
||||
.SUFFIXES:
|
||||
.SUFFIXES: .c .lo .o .obj
|
||||
am--refresh:
|
||||
@:
|
||||
$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps)
|
||||
@for dep in $?; do \
|
||||
case '$(am__configure_deps)' in \
|
||||
*$$dep*) \
|
||||
echo ' cd $(srcdir) && $(AUTOMAKE) --foreign'; \
|
||||
$(am__cd) $(srcdir) && $(AUTOMAKE) --foreign \
|
||||
&& exit 0; \
|
||||
exit 1;; \
|
||||
esac; \
|
||||
done; \
|
||||
echo ' cd $(top_srcdir) && $(AUTOMAKE) --foreign Makefile'; \
|
||||
$(am__cd) $(top_srcdir) && \
|
||||
$(AUTOMAKE) --foreign Makefile
|
||||
.PRECIOUS: Makefile
|
||||
Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
|
||||
@case '$?' in \
|
||||
*config.status*) \
|
||||
echo ' $(SHELL) ./config.status'; \
|
||||
$(SHELL) ./config.status;; \
|
||||
*) \
|
||||
echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \
|
||||
cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \
|
||||
esac;
|
||||
|
||||
$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
|
||||
$(SHELL) ./config.status --recheck
|
||||
|
||||
$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
$(am__cd) $(srcdir) && $(AUTOCONF)
|
||||
$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
|
||||
$(am__cd) $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
|
||||
$(am__aclocal_m4_deps):
|
||||
|
||||
config.h: stamp-h1
|
||||
@if test ! -f $@; then \
|
||||
rm -f stamp-h1; \
|
||||
$(MAKE) $(AM_MAKEFLAGS) stamp-h1; \
|
||||
else :; fi
|
||||
|
||||
stamp-h1: $(srcdir)/config.h.in $(top_builddir)/config.status
|
||||
@rm -f stamp-h1
|
||||
cd $(top_builddir) && $(SHELL) ./config.status config.h
|
||||
$(srcdir)/config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
|
||||
($(am__cd) $(top_srcdir) && $(AUTOHEADER))
|
||||
rm -f stamp-h1
|
||||
touch $@
|
||||
|
||||
distclean-hdr:
|
||||
-rm -f config.h stamp-h1
|
||||
install-libLTLIBRARIES: $(lib_LTLIBRARIES)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(libdir)" || $(MKDIR_P) "$(DESTDIR)$(libdir)"
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
list2=; for p in $$list; do \
|
||||
if test -f $$p; then \
|
||||
list2="$$list2 $$p"; \
|
||||
else :; fi; \
|
||||
done; \
|
||||
test -z "$$list2" || { \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 '$(DESTDIR)$(libdir)'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL) $(INSTALL_STRIP_FLAG) $$list2 "$(DESTDIR)$(libdir)"; \
|
||||
}
|
||||
|
||||
uninstall-libLTLIBRARIES:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(lib_LTLIBRARIES)'; test -n "$(libdir)" || list=; \
|
||||
for p in $$list; do \
|
||||
$(am__strip_dir) \
|
||||
echo " $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f '$(DESTDIR)$(libdir)/$$f'"; \
|
||||
$(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=uninstall rm -f "$(DESTDIR)$(libdir)/$$f"; \
|
||||
done
|
||||
|
||||
clean-libLTLIBRARIES:
|
||||
-test -z "$(lib_LTLIBRARIES)" || rm -f $(lib_LTLIBRARIES)
|
||||
@list='$(lib_LTLIBRARIES)'; for p in $$list; do \
|
||||
dir="`echo $$p | sed -e 's|/[^/]*$$||'`"; \
|
||||
test "$$dir" != "$$p" || dir=.; \
|
||||
echo "rm -f \"$${dir}/so_locations\""; \
|
||||
rm -f "$${dir}/so_locations"; \
|
||||
done
|
||||
libev.la: $(libev_la_OBJECTS) $(libev_la_DEPENDENCIES)
|
||||
$(libev_la_LINK) -rpath $(libdir) $(libev_la_OBJECTS) $(libev_la_LIBADD) $(LIBS)
|
||||
|
||||
mostlyclean-compile:
|
||||
-rm -f *.$(OBJEXT)
|
||||
|
||||
distclean-compile:
|
||||
-rm -f *.tab.c
|
||||
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ev.Plo@am__quote@
|
||||
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/event.Plo@am__quote@
|
||||
|
||||
.c.o:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c $<
|
||||
|
||||
.c.obj:
|
||||
@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'`
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'`
|
||||
|
||||
.c.lo:
|
||||
@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $<
|
||||
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@
|
||||
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
|
||||
@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $<
|
||||
|
||||
mostlyclean-libtool:
|
||||
-rm -f *.lo
|
||||
|
||||
clean-libtool:
|
||||
-rm -rf .libs _libs
|
||||
|
||||
distclean-libtool:
|
||||
-rm -f libtool config.lt
|
||||
install-man3: $(man_MANS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(man3dir)" || $(MKDIR_P) "$(DESTDIR)$(man3dir)"
|
||||
@list=''; test -n "$(man3dir)" || exit 0; \
|
||||
{ for i in $$list; do echo "$$i"; done; \
|
||||
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
|
||||
sed -n '/\.3[a-z]*$$/p'; \
|
||||
} | while read p; do \
|
||||
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; echo "$$p"; \
|
||||
done | \
|
||||
sed -e 'n;s,.*/,,;p;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,' | \
|
||||
sed 'N;N;s,\n, ,g' | { \
|
||||
list=; while read file base inst; do \
|
||||
if test "$$base" = "$$inst"; then list="$$list $$file"; else \
|
||||
echo " $(INSTALL_DATA) '$$file' '$(DESTDIR)$(man3dir)/$$inst'"; \
|
||||
$(INSTALL_DATA) "$$file" "$(DESTDIR)$(man3dir)/$$inst" || exit $$?; \
|
||||
fi; \
|
||||
done; \
|
||||
for i in $$list; do echo "$$i"; done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
test -z "$$files" || { \
|
||||
echo " $(INSTALL_DATA) $$files '$(DESTDIR)$(man3dir)'"; \
|
||||
$(INSTALL_DATA) $$files "$(DESTDIR)$(man3dir)" || exit $$?; }; \
|
||||
done; }
|
||||
|
||||
uninstall-man3:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list=''; test -n "$(man3dir)" || exit 0; \
|
||||
files=`{ for i in $$list; do echo "$$i"; done; \
|
||||
l2='$(man_MANS)'; for i in $$l2; do echo "$$i"; done | \
|
||||
sed -n '/\.3[a-z]*$$/p'; \
|
||||
} | sed -e 's,.*/,,;h;s,.*\.,,;s,^[^3][0-9a-z]*$$,3,;x' \
|
||||
-e 's,\.[0-9a-z]*$$,,;$(transform);G;s,\n,.,'`; \
|
||||
test -z "$$files" || { \
|
||||
echo " ( cd '$(DESTDIR)$(man3dir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(man3dir)" && rm -f $$files; }
|
||||
install-includeHEADERS: $(include_HEADERS)
|
||||
@$(NORMAL_INSTALL)
|
||||
test -z "$(includedir)" || $(MKDIR_P) "$(DESTDIR)$(includedir)"
|
||||
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
for p in $$list; do \
|
||||
if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
|
||||
echo "$$d$$p"; \
|
||||
done | $(am__base_list) | \
|
||||
while read files; do \
|
||||
echo " $(INSTALL_HEADER) $$files '$(DESTDIR)$(includedir)'"; \
|
||||
$(INSTALL_HEADER) $$files "$(DESTDIR)$(includedir)" || exit $$?; \
|
||||
done
|
||||
|
||||
uninstall-includeHEADERS:
|
||||
@$(NORMAL_UNINSTALL)
|
||||
@list='$(include_HEADERS)'; test -n "$(includedir)" || list=; \
|
||||
files=`for p in $$list; do echo $$p; done | sed -e 's|^.*/||'`; \
|
||||
test -n "$$files" || exit 0; \
|
||||
echo " ( cd '$(DESTDIR)$(includedir)' && rm -f" $$files ")"; \
|
||||
cd "$(DESTDIR)$(includedir)" && rm -f $$files
|
||||
|
||||
ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES)
|
||||
list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
mkid -fID $$unique
|
||||
tags: TAGS
|
||||
|
||||
TAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
set x; \
|
||||
here=`pwd`; \
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
shift; \
|
||||
if test -z "$(ETAGS_ARGS)$$*$$unique"; then :; else \
|
||||
test -n "$$unique" || unique=$$empty_fix; \
|
||||
if test $$# -gt 0; then \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
"$$@" $$unique; \
|
||||
else \
|
||||
$(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \
|
||||
$$unique; \
|
||||
fi; \
|
||||
fi
|
||||
ctags: CTAGS
|
||||
CTAGS: $(HEADERS) $(SOURCES) config.h.in $(TAGS_DEPENDENCIES) \
|
||||
$(TAGS_FILES) $(LISP)
|
||||
list='$(SOURCES) $(HEADERS) config.h.in $(LISP) $(TAGS_FILES)'; \
|
||||
unique=`for i in $$list; do \
|
||||
if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \
|
||||
done | \
|
||||
$(AWK) '{ files[$$0] = 1; nonempty = 1; } \
|
||||
END { if (nonempty) { for (i in files) print i; }; }'`; \
|
||||
test -z "$(CTAGS_ARGS)$$unique" \
|
||||
|| $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \
|
||||
$$unique
|
||||
|
||||
GTAGS:
|
||||
here=`$(am__cd) $(top_builddir) && pwd` \
|
||||
&& $(am__cd) $(top_srcdir) \
|
||||
&& gtags -i $(GTAGS_ARGS) "$$here"
|
||||
|
||||
distclean-tags:
|
||||
-rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags
|
||||
|
||||
distdir: $(DISTFILES)
|
||||
@list='$(MANS)'; if test -n "$$list"; then \
|
||||
list=`for p in $$list; do \
|
||||
if test -f $$p; then d=; else d="$(srcdir)/"; fi; \
|
||||
if test -f "$$d$$p"; then echo "$$d$$p"; else :; fi; done`; \
|
||||
if test -n "$$list" && \
|
||||
grep 'ab help2man is required to generate this page' $$list >/dev/null; then \
|
||||
echo "error: found man pages containing the \`missing help2man' replacement text:" >&2; \
|
||||
grep -l 'ab help2man is required to generate this page' $$list | sed 's/^/ /' >&2; \
|
||||
echo " to fix them, install help2man, remove and regenerate the man pages;" >&2; \
|
||||
echo " typically \`make maintainer-clean' will remove them" >&2; \
|
||||
exit 1; \
|
||||
else :; fi; \
|
||||
else :; fi
|
||||
$(am__remove_distdir)
|
||||
test -d "$(distdir)" || mkdir "$(distdir)"
|
||||
@srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \
|
||||
list='$(DISTFILES)'; \
|
||||
dist_files=`for file in $$list; do echo $$file; done | \
|
||||
sed -e "s|^$$srcdirstrip/||;t" \
|
||||
-e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \
|
||||
case $$dist_files in \
|
||||
*/*) $(MKDIR_P) `echo "$$dist_files" | \
|
||||
sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \
|
||||
sort -u` ;; \
|
||||
esac; \
|
||||
for file in $$dist_files; do \
|
||||
if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \
|
||||
if test -d $$d/$$file; then \
|
||||
dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \
|
||||
if test -d "$(distdir)/$$file"; then \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \
|
||||
cp -fpR $(srcdir)/$$file "$(distdir)$$dir" || exit 1; \
|
||||
find "$(distdir)/$$file" -type d ! -perm -700 -exec chmod u+rwx {} \;; \
|
||||
fi; \
|
||||
cp -fpR $$d/$$file "$(distdir)$$dir" || exit 1; \
|
||||
else \
|
||||
test -f "$(distdir)/$$file" \
|
||||
|| cp -p $$d/$$file "$(distdir)/$$file" \
|
||||
|| exit 1; \
|
||||
fi; \
|
||||
done
|
||||
-test -n "$(am__skip_mode_fix)" \
|
||||
|| find "$(distdir)" -type d ! -perm -755 \
|
||||
-exec chmod u+rwx,go+rx {} \; -o \
|
||||
! -type d ! -perm -444 -links 1 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -400 -exec chmod a+r {} \; -o \
|
||||
! -type d ! -perm -444 -exec $(install_sh) -c -m a+r {} {} \; \
|
||||
|| chmod -R a+r "$(distdir)"
|
||||
dist-gzip: distdir
|
||||
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-bzip2: distdir
|
||||
tardir=$(distdir) && $(am__tar) | bzip2 -9 -c >$(distdir).tar.bz2
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-lzma: distdir
|
||||
tardir=$(distdir) && $(am__tar) | lzma -9 -c >$(distdir).tar.lzma
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-xz: distdir
|
||||
tardir=$(distdir) && $(am__tar) | xz -c >$(distdir).tar.xz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-tarZ: distdir
|
||||
tardir=$(distdir) && $(am__tar) | compress -c >$(distdir).tar.Z
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-shar: distdir
|
||||
shar $(distdir) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).shar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist-zip: distdir
|
||||
-rm -f $(distdir).zip
|
||||
zip -rq $(distdir).zip $(distdir)
|
||||
$(am__remove_distdir)
|
||||
|
||||
dist dist-all: distdir
|
||||
tardir=$(distdir) && $(am__tar) | GZIP=$(GZIP_ENV) gzip -c >$(distdir).tar.gz
|
||||
$(am__remove_distdir)
|
||||
|
||||
# This target untars the dist file and tries a VPATH configuration. Then
|
||||
# it guarantees that the distribution is self-contained by making another
|
||||
# tarfile.
|
||||
distcheck: dist
|
||||
case '$(DIST_ARCHIVES)' in \
|
||||
*.tar.gz*) \
|
||||
GZIP=$(GZIP_ENV) gzip -dc $(distdir).tar.gz | $(am__untar) ;;\
|
||||
*.tar.bz2*) \
|
||||
bzip2 -dc $(distdir).tar.bz2 | $(am__untar) ;;\
|
||||
*.tar.lzma*) \
|
||||
lzma -dc $(distdir).tar.lzma | $(am__untar) ;;\
|
||||
*.tar.xz*) \
|
||||
xz -dc $(distdir).tar.xz | $(am__untar) ;;\
|
||||
*.tar.Z*) \
|
||||
uncompress -c $(distdir).tar.Z | $(am__untar) ;;\
|
||||
*.shar.gz*) \
|
||||
GZIP=$(GZIP_ENV) gzip -dc $(distdir).shar.gz | unshar ;;\
|
||||
*.zip*) \
|
||||
unzip $(distdir).zip ;;\
|
||||
esac
|
||||
chmod -R a-w $(distdir); chmod a+w $(distdir)
|
||||
mkdir $(distdir)/_build
|
||||
mkdir $(distdir)/_inst
|
||||
chmod a-w $(distdir)
|
||||
test -d $(distdir)/_build || exit 0; \
|
||||
dc_install_base=`$(am__cd) $(distdir)/_inst && pwd | sed -e 's,^[^:\\/]:[\\/],/,'` \
|
||||
&& dc_destdir="$${TMPDIR-/tmp}/am-dc-$$$$/" \
|
||||
&& am__cwd=`pwd` \
|
||||
&& $(am__cd) $(distdir)/_build \
|
||||
&& ../configure --srcdir=.. --prefix="$$dc_install_base" \
|
||||
$(DISTCHECK_CONFIGURE_FLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dvi \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) check \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) installcheck \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distuninstallcheck_dir="$$dc_install_base" \
|
||||
distuninstallcheck \
|
||||
&& chmod -R a-w "$$dc_install_base" \
|
||||
&& ({ \
|
||||
(cd ../.. && umask 077 && mkdir "$$dc_destdir") \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" install \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" uninstall \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) DESTDIR="$$dc_destdir" \
|
||||
distuninstallcheck_dir="$$dc_destdir" distuninstallcheck; \
|
||||
} || { rm -rf "$$dc_destdir"; exit 1; }) \
|
||||
&& rm -rf "$$dc_destdir" \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) dist \
|
||||
&& rm -rf $(DIST_ARCHIVES) \
|
||||
&& $(MAKE) $(AM_MAKEFLAGS) distcleancheck \
|
||||
&& cd "$$am__cwd" \
|
||||
|| exit 1
|
||||
$(am__remove_distdir)
|
||||
@(echo "$(distdir) archives ready for distribution: "; \
|
||||
list='$(DIST_ARCHIVES)'; for i in $$list; do echo $$i; done) | \
|
||||
sed -e 1h -e 1s/./=/g -e 1p -e 1x -e '$$p' -e '$$x'
|
||||
distuninstallcheck:
|
||||
@$(am__cd) '$(distuninstallcheck_dir)' \
|
||||
&& test `$(distuninstallcheck_listfiles) | wc -l` -le 1 \
|
||||
|| { echo "ERROR: files left after uninstall:" ; \
|
||||
if test -n "$(DESTDIR)"; then \
|
||||
echo " (check DESTDIR support)"; \
|
||||
fi ; \
|
||||
$(distuninstallcheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
distcleancheck: distclean
|
||||
@if test '$(srcdir)' = . ; then \
|
||||
echo "ERROR: distcleancheck can only run from a VPATH build" ; \
|
||||
exit 1 ; \
|
||||
fi
|
||||
@test `$(distcleancheck_listfiles) | wc -l` -eq 0 \
|
||||
|| { echo "ERROR: files left in build directory after distclean:" ; \
|
||||
$(distcleancheck_listfiles) ; \
|
||||
exit 1; } >&2
|
||||
check-am: all-am
|
||||
check: check-am
|
||||
all-am: Makefile $(LTLIBRARIES) $(MANS) $(HEADERS) config.h
|
||||
installdirs:
|
||||
for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(man3dir)" "$(DESTDIR)$(includedir)"; do \
|
||||
test -z "$$dir" || $(MKDIR_P) "$$dir"; \
|
||||
done
|
||||
install: install-am
|
||||
install-exec: install-exec-am
|
||||
install-data: install-data-am
|
||||
uninstall: uninstall-am
|
||||
|
||||
install-am: all-am
|
||||
@$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am
|
||||
|
||||
installcheck: installcheck-am
|
||||
install-strip:
|
||||
$(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \
|
||||
install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \
|
||||
`test -z '$(STRIP)' || \
|
||||
echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install
|
||||
mostlyclean-generic:
|
||||
|
||||
clean-generic:
|
||||
|
||||
distclean-generic:
|
||||
-test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES)
|
||||
-test . = "$(srcdir)" || test -z "$(CONFIG_CLEAN_VPATH_FILES)" || rm -f $(CONFIG_CLEAN_VPATH_FILES)
|
||||
|
||||
maintainer-clean-generic:
|
||||
@echo "This command is intended for maintainers to use"
|
||||
@echo "it deletes files that may require special tools to rebuild."
|
||||
clean: clean-am
|
||||
|
||||
clean-am: clean-generic clean-libLTLIBRARIES clean-libtool \
|
||||
mostlyclean-am
|
||||
|
||||
distclean: distclean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
distclean-am: clean-am distclean-compile distclean-generic \
|
||||
distclean-hdr distclean-libtool distclean-tags
|
||||
|
||||
dvi: dvi-am
|
||||
|
||||
dvi-am:
|
||||
|
||||
html: html-am
|
||||
|
||||
html-am:
|
||||
|
||||
info: info-am
|
||||
|
||||
info-am:
|
||||
|
||||
install-data-am: install-includeHEADERS install-man
|
||||
|
||||
install-dvi: install-dvi-am
|
||||
|
||||
install-dvi-am:
|
||||
|
||||
install-exec-am: install-libLTLIBRARIES
|
||||
|
||||
install-html: install-html-am
|
||||
|
||||
install-html-am:
|
||||
|
||||
install-info: install-info-am
|
||||
|
||||
install-info-am:
|
||||
|
||||
install-man: install-man3
|
||||
|
||||
install-pdf: install-pdf-am
|
||||
|
||||
install-pdf-am:
|
||||
|
||||
install-ps: install-ps-am
|
||||
|
||||
install-ps-am:
|
||||
|
||||
installcheck-am:
|
||||
|
||||
maintainer-clean: maintainer-clean-am
|
||||
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
|
||||
-rm -rf $(top_srcdir)/autom4te.cache
|
||||
-rm -rf ./$(DEPDIR)
|
||||
-rm -f Makefile
|
||||
maintainer-clean-am: distclean-am maintainer-clean-generic
|
||||
|
||||
mostlyclean: mostlyclean-am
|
||||
|
||||
mostlyclean-am: mostlyclean-compile mostlyclean-generic \
|
||||
mostlyclean-libtool
|
||||
|
||||
pdf: pdf-am
|
||||
|
||||
pdf-am:
|
||||
|
||||
ps: ps-am
|
||||
|
||||
ps-am:
|
||||
|
||||
uninstall-am: uninstall-includeHEADERS uninstall-libLTLIBRARIES \
|
||||
uninstall-man
|
||||
|
||||
uninstall-man: uninstall-man3
|
||||
|
||||
.MAKE: all install-am install-strip
|
||||
|
||||
.PHONY: CTAGS GTAGS all all-am am--refresh check check-am clean \
|
||||
clean-generic clean-libLTLIBRARIES clean-libtool ctags dist \
|
||||
dist-all dist-bzip2 dist-gzip dist-lzma dist-shar dist-tarZ \
|
||||
dist-xz dist-zip distcheck distclean distclean-compile \
|
||||
distclean-generic distclean-hdr distclean-libtool \
|
||||
distclean-tags distcleancheck distdir distuninstallcheck dvi \
|
||||
dvi-am html html-am info info-am install install-am \
|
||||
install-data install-data-am install-dvi install-dvi-am \
|
||||
install-exec install-exec-am install-html install-html-am \
|
||||
install-includeHEADERS install-info install-info-am \
|
||||
install-libLTLIBRARIES install-man install-man3 install-pdf \
|
||||
install-pdf-am install-ps install-ps-am install-strip \
|
||||
installcheck installcheck-am installdirs maintainer-clean \
|
||||
maintainer-clean-generic mostlyclean mostlyclean-compile \
|
||||
mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \
|
||||
tags uninstall uninstall-am uninstall-includeHEADERS \
|
||||
uninstall-libLTLIBRARIES uninstall-man uninstall-man3
|
||||
|
||||
|
||||
# Tell versions [3.59,3.63) of GNU make to not export all variables.
|
||||
# Otherwise a system limit (for SysV at least) may be exceeded.
|
||||
.NOEXPORT:
|
||||
58
src/rt/libuv/ev/README
Normal file
58
src/rt/libuv/ev/README
Normal file
|
|
@ -0,0 +1,58 @@
|
|||
libev is a high-performance event loop/event model with lots of features.
|
||||
(see benchmark at http://libev.schmorp.de/bench.html)
|
||||
|
||||
|
||||
ABOUT
|
||||
|
||||
Homepage: http://software.schmorp.de/pkg/libev
|
||||
Mailinglist: libev@lists.schmorp.de
|
||||
http://lists.schmorp.de/cgi-bin/mailman/listinfo/libev
|
||||
Library Documentation: http://pod.tst.eu/http://cvs.schmorp.de/libev/ev.pod
|
||||
|
||||
Libev is modelled (very losely) after libevent and the Event perl
|
||||
module, but is faster, scales better and is more correct, and also more
|
||||
featureful. And also smaller. Yay.
|
||||
|
||||
Some of the specialties of libev not commonly found elsewhere are:
|
||||
|
||||
- extensive and detailed, readable documentation (not doxygen garbage).
|
||||
- fully supports fork, can detect fork in various ways and automatically
|
||||
re-arms kernel mechanisms that do not support fork.
|
||||
- highly optimised select, poll, epoll, kqueue and event ports backends.
|
||||
- filesystem object (path) watching (with optional linux inotify support).
|
||||
- wallclock-based times (using absolute time, cron-like).
|
||||
- relative timers/timeouts (handle time jumps).
|
||||
- fast intra-thread communication between multiple
|
||||
event loops (with optional fast linux eventfd backend).
|
||||
- extremely easy to embed.
|
||||
- very small codebase, no bloated library.
|
||||
- fully extensible by being able to plug into the event loop,
|
||||
integrate other event loops, integrate other event loop users.
|
||||
- very little memory use (small watchers, small event loop data).
|
||||
- optional C++ interface allowing method and function callbacks
|
||||
at no extra memory or runtime overhead.
|
||||
- optional Perl interface with similar characteristics (capable
|
||||
of running Glib/Gtk2 on libev, interfaces with Net::SNMP and
|
||||
libadns).
|
||||
- support for other languages (multiple C++ interfaces, D, Ruby,
|
||||
Python) available from third-parties.
|
||||
|
||||
Examples of programs that embed libev: the EV perl module,
|
||||
rxvt-unicode, gvpe (GNU Virtual Private Ethernet), the Deliantra MMORPG
|
||||
server (http://www.deliantra.net/), Rubinius (a next-generation Ruby
|
||||
VM), the Ebb web server, the Rev event toolkit.
|
||||
|
||||
|
||||
CONTRIBUTORS
|
||||
|
||||
libev was written and designed by Marc Lehmann and Emanuele Giaquinta.
|
||||
|
||||
The following people sent in patches or made other noteworthy
|
||||
contributions to the design (for minor patches, see the Changes
|
||||
file. If I forgot to include you, please shout at me, it was an
|
||||
accident):
|
||||
|
||||
W.C.A. Wijngaards
|
||||
Christopher Layne
|
||||
Chris Brody
|
||||
|
||||
8957
src/rt/libuv/ev/aclocal.m4
vendored
Normal file
8957
src/rt/libuv/ev/aclocal.m4
vendored
Normal file
File diff suppressed because it is too large
Load diff
6
src/rt/libuv/ev/autogen.sh
Normal file
6
src/rt/libuv/ev/autogen.sh
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
#!/bin/sh
|
||||
|
||||
libtoolize --force
|
||||
automake --add-missing --force-missing
|
||||
autoreconf
|
||||
|
||||
1526
src/rt/libuv/ev/config.guess
vendored
Executable file
1526
src/rt/libuv/ev/config.guess
vendored
Executable file
File diff suppressed because it is too large
Load diff
125
src/rt/libuv/ev/config.h.in
Normal file
125
src/rt/libuv/ev/config.h.in
Normal file
|
|
@ -0,0 +1,125 @@
|
|||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the `clock_gettime' function. */
|
||||
#undef HAVE_CLOCK_GETTIME
|
||||
|
||||
/* "use syscall interface for clock_gettime" */
|
||||
#undef HAVE_CLOCK_SYSCALL
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* Define to 1 if you have the `epoll_ctl' function. */
|
||||
#undef HAVE_EPOLL_CTL
|
||||
|
||||
/* Define to 1 if you have the `eventfd' function. */
|
||||
#undef HAVE_EVENTFD
|
||||
|
||||
/* Define to 1 if you have the `inotify_init' function. */
|
||||
#undef HAVE_INOTIFY_INIT
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the `kqueue' function. */
|
||||
#undef HAVE_KQUEUE
|
||||
|
||||
/* Define to 1 if you have the `m' library (-lm). */
|
||||
#undef HAVE_LIBM
|
||||
|
||||
/* Define to 1 if you have the `rt' library (-lrt). */
|
||||
#undef HAVE_LIBRT
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* Define to 1 if you have the `nanosleep' function. */
|
||||
#undef HAVE_NANOSLEEP
|
||||
|
||||
/* Define to 1 if you have the `poll' function. */
|
||||
#undef HAVE_POLL
|
||||
|
||||
/* Define to 1 if you have the <poll.h> header file. */
|
||||
#undef HAVE_POLL_H
|
||||
|
||||
/* Define to 1 if you have the `port_create' function. */
|
||||
#undef HAVE_PORT_CREATE
|
||||
|
||||
/* Define to 1 if you have the <port.h> header file. */
|
||||
#undef HAVE_PORT_H
|
||||
|
||||
/* Define to 1 if you have the `select' function. */
|
||||
#undef HAVE_SELECT
|
||||
|
||||
/* Define to 1 if you have the `signalfd' function. */
|
||||
#undef HAVE_SIGNALFD
|
||||
|
||||
/* Define to 1 if you have the <stdint.h> header file. */
|
||||
#undef HAVE_STDINT_H
|
||||
|
||||
/* Define to 1 if you have the <stdlib.h> header file. */
|
||||
#undef HAVE_STDLIB_H
|
||||
|
||||
/* Define to 1 if you have the <strings.h> header file. */
|
||||
#undef HAVE_STRINGS_H
|
||||
|
||||
/* Define to 1 if you have the <string.h> header file. */
|
||||
#undef HAVE_STRING_H
|
||||
|
||||
/* Define to 1 if you have the <sys/epoll.h> header file. */
|
||||
#undef HAVE_SYS_EPOLL_H
|
||||
|
||||
/* Define to 1 if you have the <sys/eventfd.h> header file. */
|
||||
#undef HAVE_SYS_EVENTFD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/event.h> header file. */
|
||||
#undef HAVE_SYS_EVENT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/inotify.h> header file. */
|
||||
#undef HAVE_SYS_INOTIFY_H
|
||||
|
||||
/* Define to 1 if you have the <sys/select.h> header file. */
|
||||
#undef HAVE_SYS_SELECT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/signalfd.h> header file. */
|
||||
#undef HAVE_SYS_SIGNALFD_H
|
||||
|
||||
/* Define to 1 if you have the <sys/stat.h> header file. */
|
||||
#undef HAVE_SYS_STAT_H
|
||||
|
||||
/* Define to 1 if you have the <sys/types.h> header file. */
|
||||
#undef HAVE_SYS_TYPES_H
|
||||
|
||||
/* Define to 1 if you have the <unistd.h> header file. */
|
||||
#undef HAVE_UNISTD_H
|
||||
|
||||
/* Define to the sub-directory in which libtool stores uninstalled libraries.
|
||||
*/
|
||||
#undef LT_OBJDIR
|
||||
|
||||
/* Name of package */
|
||||
#undef PACKAGE
|
||||
|
||||
/* Define to the address where bug reports for this package should be sent. */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
||||
/* Define to the full name of this package. */
|
||||
#undef PACKAGE_NAME
|
||||
|
||||
/* Define to the full name and version of this package. */
|
||||
#undef PACKAGE_STRING
|
||||
|
||||
/* Define to the one symbol short name of this package. */
|
||||
#undef PACKAGE_TARNAME
|
||||
|
||||
/* Define to the home page for this package. */
|
||||
#undef PACKAGE_URL
|
||||
|
||||
/* Define to the version of this package. */
|
||||
#undef PACKAGE_VERSION
|
||||
|
||||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#undef STDC_HEADERS
|
||||
|
||||
/* Version number of package */
|
||||
#undef VERSION
|
||||
1658
src/rt/libuv/ev/config.sub
vendored
Executable file
1658
src/rt/libuv/ev/config.sub
vendored
Executable file
File diff suppressed because it is too large
Load diff
13037
src/rt/libuv/ev/configure
vendored
Executable file
13037
src/rt/libuv/ev/configure
vendored
Executable file
File diff suppressed because it is too large
Load diff
18
src/rt/libuv/ev/configure.ac
Normal file
18
src/rt/libuv/ev/configure.ac
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([ev_epoll.c])
|
||||
|
||||
AM_INIT_AUTOMAKE(libev,4.04) dnl also update ev.h!
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
AM_MAINTAINER_MODE
|
||||
|
||||
AC_PROG_INSTALL
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
if test "x$GCC" = xyes ; then
|
||||
CFLAGS="-O3 $CFLAGS"
|
||||
fi
|
||||
|
||||
m4_include([libev.m4])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
630
src/rt/libuv/ev/depcomp
Executable file
630
src/rt/libuv/ev/depcomp
Executable file
|
|
@ -0,0 +1,630 @@
|
|||
#! /bin/sh
|
||||
# depcomp - compile a program generating dependencies as side-effects
|
||||
|
||||
scriptversion=2009-04-28.21; # UTC
|
||||
|
||||
# Copyright (C) 1999, 2000, 2003, 2004, 2005, 2006, 2007, 2009 Free
|
||||
# Software Foundation, Inc.
|
||||
|
||||
# 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, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
# 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.
|
||||
|
||||
# Originally written by Alexandre Oliva <oliva@dcc.unicamp.br>.
|
||||
|
||||
case $1 in
|
||||
'')
|
||||
echo "$0: No command. Try \`$0 --help' for more information." 1>&2
|
||||
exit 1;
|
||||
;;
|
||||
-h | --h*)
|
||||
cat <<\EOF
|
||||
Usage: depcomp [--help] [--version] PROGRAM [ARGS]
|
||||
|
||||
Run PROGRAMS ARGS to compile a file, generating dependencies
|
||||
as side-effects.
|
||||
|
||||
Environment variables:
|
||||
depmode Dependency tracking mode.
|
||||
source Source file read by `PROGRAMS ARGS'.
|
||||
object Object file output by `PROGRAMS ARGS'.
|
||||
DEPDIR directory where to store dependencies.
|
||||
depfile Dependency file to output.
|
||||
tmpdepfile Temporary file to use when outputing dependencies.
|
||||
libtool Whether libtool is used (yes/no).
|
||||
|
||||
Report bugs to <bug-automake@gnu.org>.
|
||||
EOF
|
||||
exit $?
|
||||
;;
|
||||
-v | --v*)
|
||||
echo "depcomp $scriptversion"
|
||||
exit $?
|
||||
;;
|
||||
esac
|
||||
|
||||
if test -z "$depmode" || test -z "$source" || test -z "$object"; then
|
||||
echo "depcomp: Variables source, object and depmode must be set" 1>&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Dependencies for sub/bar.o or sub/bar.obj go into sub/.deps/bar.Po.
|
||||
depfile=${depfile-`echo "$object" |
|
||||
sed 's|[^\\/]*$|'${DEPDIR-.deps}'/&|;s|\.\([^.]*\)$|.P\1|;s|Pobj$|Po|'`}
|
||||
tmpdepfile=${tmpdepfile-`echo "$depfile" | sed 's/\.\([^.]*\)$/.T\1/'`}
|
||||
|
||||
rm -f "$tmpdepfile"
|
||||
|
||||
# Some modes work just like other modes, but use different flags. We
|
||||
# parameterize here, but still list the modes in the big case below,
|
||||
# to make depend.m4 easier to write. Note that we *cannot* use a case
|
||||
# here, because this file can only contain one case statement.
|
||||
if test "$depmode" = hp; then
|
||||
# HP compiler uses -M and no extra arg.
|
||||
gccflag=-M
|
||||
depmode=gcc
|
||||
fi
|
||||
|
||||
if test "$depmode" = dashXmstdout; then
|
||||
# This is just like dashmstdout with a different argument.
|
||||
dashmflag=-xM
|
||||
depmode=dashmstdout
|
||||
fi
|
||||
|
||||
cygpath_u="cygpath -u -f -"
|
||||
if test "$depmode" = msvcmsys; then
|
||||
# This is just like msvisualcpp but w/o cygpath translation.
|
||||
# Just convert the backslash-escaped backslashes to single forward
|
||||
# slashes to satisfy depend.m4
|
||||
cygpath_u="sed s,\\\\\\\\,/,g"
|
||||
depmode=msvisualcpp
|
||||
fi
|
||||
|
||||
case "$depmode" in
|
||||
gcc3)
|
||||
## gcc 3 implements dependency tracking that does exactly what
|
||||
## we want. Yay! Note: for some reason libtool 1.4 doesn't like
|
||||
## it if -MD -MP comes after the -MF stuff. Hmm.
|
||||
## Unfortunately, FreeBSD c89 acceptance of flags depends upon
|
||||
## the command line argument order; so add the flags where they
|
||||
## appear in depend2.am. Note that the slowdown incurred here
|
||||
## affects only configure: in makefiles, %FASTDEP% shortcuts this.
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-c) set fnord "$@" -MT "$object" -MD -MP -MF "$tmpdepfile" "$arg" ;;
|
||||
*) set fnord "$@" "$arg" ;;
|
||||
esac
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
done
|
||||
"$@"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
mv "$tmpdepfile" "$depfile"
|
||||
;;
|
||||
|
||||
gcc)
|
||||
## There are various ways to get dependency output from gcc. Here's
|
||||
## why we pick this rather obscure method:
|
||||
## - Don't want to use -MD because we'd like the dependencies to end
|
||||
## up in a subdir. Having to rename by hand is ugly.
|
||||
## (We might end up doing this anyway to support other compilers.)
|
||||
## - The DEPENDENCIES_OUTPUT environment variable makes gcc act like
|
||||
## -MM, not -M (despite what the docs say).
|
||||
## - Using -M directly means running the compiler twice (even worse
|
||||
## than renaming).
|
||||
if test -z "$gccflag"; then
|
||||
gccflag=-MD,
|
||||
fi
|
||||
"$@" -Wp,"$gccflag$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
alpha=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
|
||||
## The second -e expression handles DOS-style file names with drive letters.
|
||||
sed -e 's/^[^:]*: / /' \
|
||||
-e 's/^['$alpha']:\/[^:]*: / /' < "$tmpdepfile" >> "$depfile"
|
||||
## This next piece of magic avoids the `deleted header file' problem.
|
||||
## The problem is that when a header file which appears in a .P file
|
||||
## is deleted, the dependency causes make to die (because there is
|
||||
## typically no way to rebuild the header). We avoid this by adding
|
||||
## dummy dependencies for each header file. Too bad gcc doesn't do
|
||||
## this for us directly.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" |
|
||||
## Some versions of gcc put a space before the `:'. On the theory
|
||||
## that the space means something, we add a space to the output as
|
||||
## well.
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
sgi)
|
||||
if test "$libtool" = yes; then
|
||||
"$@" "-Wp,-MDupdate,$tmpdepfile"
|
||||
else
|
||||
"$@" -MDupdate "$tmpdepfile"
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
|
||||
if test -f "$tmpdepfile"; then # yes, the sourcefile depend on other files
|
||||
echo "$object : \\" > "$depfile"
|
||||
|
||||
# Clip off the initial element (the dependent). Don't try to be
|
||||
# clever and replace this with sed code, as IRIX sed won't handle
|
||||
# lines with more than a fixed number of characters (4096 in
|
||||
# IRIX 6.2 sed, 8192 in IRIX 6.5). We also remove comment lines;
|
||||
# the IRIX cc adds comments like `#:fec' to the end of the
|
||||
# dependency line.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' | \
|
||||
tr '
|
||||
' ' ' >> "$depfile"
|
||||
echo >> "$depfile"
|
||||
|
||||
# The second pass generates a dummy entry for each header file.
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" \
|
||||
| sed -e 's/^.*\.o://' -e 's/#.*$//' -e '/^$/ d' -e 's/$/:/' \
|
||||
>> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
aix)
|
||||
# The C for AIX Compiler uses -M and outputs the dependencies
|
||||
# in a .u file. In older versions, this file always lives in the
|
||||
# current directory. Also, the AIX compiler puts `$object:' at the
|
||||
# start of each line; $object doesn't have directory information.
|
||||
# Version 6 uses the directory in both cases.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$base.u
|
||||
tmpdepfile3=$dir.libs/$base.u
|
||||
"$@" -Wc,-M
|
||||
else
|
||||
tmpdepfile1=$dir$base.u
|
||||
tmpdepfile2=$dir$base.u
|
||||
tmpdepfile3=$dir$base.u
|
||||
"$@" -M
|
||||
fi
|
||||
stat=$?
|
||||
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
# Each line is of the form `foo.o: dependent.h'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
# The sourcefile does not contain any dependencies, so just
|
||||
# store a dummy comment line, to avoid errors with the Makefile
|
||||
# "include basename.Plo" scheme.
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
icc)
|
||||
# Intel's C compiler understands `-MD -MF file'. However on
|
||||
# icc -MD -MF foo.d -c -o sub/foo.o sub/foo.c
|
||||
# ICC 7.0 will fill foo.d with something like
|
||||
# foo.o: sub/foo.c
|
||||
# foo.o: sub/foo.h
|
||||
# which is wrong. We want:
|
||||
# sub/foo.o: sub/foo.c
|
||||
# sub/foo.o: sub/foo.h
|
||||
# sub/foo.c:
|
||||
# sub/foo.h:
|
||||
# ICC 7.1 will output
|
||||
# foo.o: sub/foo.c sub/foo.h
|
||||
# and will wrap long lines using \ :
|
||||
# foo.o: sub/foo.c ... \
|
||||
# sub/foo.h ... \
|
||||
# ...
|
||||
|
||||
"$@" -MD -MF "$tmpdepfile"
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile"
|
||||
exit $stat
|
||||
fi
|
||||
rm -f "$depfile"
|
||||
# Each line is of the form `foo.o: dependent.h',
|
||||
# or `foo.o: dep1.h dep2.h \', or ` dep3.h dep4.h \'.
|
||||
# Do two passes, one to just change these to
|
||||
# `$object: dependent.h' and one to simply `dependent.h:'.
|
||||
sed "s,^[^:]*:,$object :," < "$tmpdepfile" > "$depfile"
|
||||
# Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
# correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed 's,^[^:]*: \(.*\)$,\1,;s/^\\$//;/^$/d;/:$/d' < "$tmpdepfile" |
|
||||
sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
hp2)
|
||||
# The "hp" stanza above does not work with aCC (C++) and HP's ia64
|
||||
# compilers, which have integrated preprocessors. The correct option
|
||||
# to use with these is +Maked; it writes dependencies to a file named
|
||||
# 'foo.d', which lands next to the object file, wherever that
|
||||
# happens to be.
|
||||
# Much of this is similar to the tru64 case; see comments there.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
if test "$libtool" = yes; then
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir.libs/$base.d
|
||||
"$@" -Wc,+Maked
|
||||
else
|
||||
tmpdepfile1=$dir$base.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
"$@" +Maked
|
||||
fi
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," "$tmpdepfile" > "$depfile"
|
||||
# Add `dependent.h:' lines.
|
||||
sed -ne '2,${
|
||||
s/^ *//
|
||||
s/ \\*$//
|
||||
s/$/:/
|
||||
p
|
||||
}' "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile" "$tmpdepfile2"
|
||||
;;
|
||||
|
||||
tru64)
|
||||
# The Tru64 compiler uses -MD to generate dependencies as a side
|
||||
# effect. `cc -MD -o foo.o ...' puts the dependencies into `foo.o.d'.
|
||||
# At least on Alpha/Redhat 6.1, Compaq CCC V6.2-504 seems to put
|
||||
# dependencies in `foo.d' instead, so we check for that too.
|
||||
# Subdirectories are respected.
|
||||
dir=`echo "$object" | sed -e 's|/[^/]*$|/|'`
|
||||
test "x$dir" = "x$object" && dir=
|
||||
base=`echo "$object" | sed -e 's|^.*/||' -e 's/\.o$//' -e 's/\.lo$//'`
|
||||
|
||||
if test "$libtool" = yes; then
|
||||
# With Tru64 cc, shared objects can also be used to make a
|
||||
# static library. This mechanism is used in libtool 1.4 series to
|
||||
# handle both shared and static libraries in a single compilation.
|
||||
# With libtool 1.4, dependencies were output in $dir.libs/$base.lo.d.
|
||||
#
|
||||
# With libtool 1.5 this exception was removed, and libtool now
|
||||
# generates 2 separate objects for the 2 libraries. These two
|
||||
# compilations output dependencies in $dir.libs/$base.o.d and
|
||||
# in $dir$base.o.d. We have to check for both files, because
|
||||
# one of the two compilations can be disabled. We should prefer
|
||||
# $dir$base.o.d over $dir.libs/$base.o.d because the latter is
|
||||
# automatically cleaned when .libs/ is deleted, while ignoring
|
||||
# the former would cause a distcleancheck panic.
|
||||
tmpdepfile1=$dir.libs/$base.lo.d # libtool 1.4
|
||||
tmpdepfile2=$dir$base.o.d # libtool 1.5
|
||||
tmpdepfile3=$dir.libs/$base.o.d # libtool 1.5
|
||||
tmpdepfile4=$dir.libs/$base.d # Compaq CCC V6.2-504
|
||||
"$@" -Wc,-MD
|
||||
else
|
||||
tmpdepfile1=$dir$base.o.d
|
||||
tmpdepfile2=$dir$base.d
|
||||
tmpdepfile3=$dir$base.d
|
||||
tmpdepfile4=$dir$base.d
|
||||
"$@" -MD
|
||||
fi
|
||||
|
||||
stat=$?
|
||||
if test $stat -eq 0; then :
|
||||
else
|
||||
rm -f "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
exit $stat
|
||||
fi
|
||||
|
||||
for tmpdepfile in "$tmpdepfile1" "$tmpdepfile2" "$tmpdepfile3" "$tmpdepfile4"
|
||||
do
|
||||
test -f "$tmpdepfile" && break
|
||||
done
|
||||
if test -f "$tmpdepfile"; then
|
||||
sed -e "s,^.*\.[a-z]*:,$object:," < "$tmpdepfile" > "$depfile"
|
||||
# That's a tab and a space in the [].
|
||||
sed -e 's,^.*\.[a-z]*:[ ]*,,' -e 's,$,:,' < "$tmpdepfile" >> "$depfile"
|
||||
else
|
||||
echo "#dummy" > "$depfile"
|
||||
fi
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
#nosideeffect)
|
||||
# This comment above is used by automake to tell side-effect
|
||||
# dependency tracking mechanisms from slower ones.
|
||||
|
||||
dashmstdout)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout, regardless of -o.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
test -z "$dashmflag" && dashmflag=-M
|
||||
# Require at least two characters before searching for `:'
|
||||
# in the target name. This is to cope with DOS-style filenames:
|
||||
# a dependency such as `c:/foo/bar' could be seen as target `c' otherwise.
|
||||
"$@" $dashmflag |
|
||||
sed 's:^[ ]*[^: ][^:][^:]*\:[ ]*:'"$object"'\: :' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
tr ' ' '
|
||||
' < "$tmpdepfile" | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
dashXmstdout)
|
||||
# This case only exists to satisfy depend.m4. It is never actually
|
||||
# run, as this mode is specially recognized in the preamble.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
makedepend)
|
||||
"$@" || exit $?
|
||||
# Remove any Libtool call
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
# X makedepend
|
||||
shift
|
||||
cleared=no eat=no
|
||||
for arg
|
||||
do
|
||||
case $cleared in
|
||||
no)
|
||||
set ""; shift
|
||||
cleared=yes ;;
|
||||
esac
|
||||
if test $eat = yes; then
|
||||
eat=no
|
||||
continue
|
||||
fi
|
||||
case "$arg" in
|
||||
-D*|-I*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
# Strip any option that makedepend may not understand. Remove
|
||||
# the object too, otherwise makedepend will parse it as a source file.
|
||||
-arch)
|
||||
eat=yes ;;
|
||||
-*|$object)
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"; shift ;;
|
||||
esac
|
||||
done
|
||||
obj_suffix=`echo "$object" | sed 's/^.*\././'`
|
||||
touch "$tmpdepfile"
|
||||
${MAKEDEPEND-makedepend} -o"$obj_suffix" -f"$tmpdepfile" "$@"
|
||||
rm -f "$depfile"
|
||||
cat < "$tmpdepfile" > "$depfile"
|
||||
sed '1,2d' "$tmpdepfile" | tr ' ' '
|
||||
' | \
|
||||
## Some versions of the HPUX 10.20 sed can't process this invocation
|
||||
## correctly. Breaking it into two sed invocations is a workaround.
|
||||
sed -e 's/^\\$//' -e '/^$/d' -e '/:$/d' | sed -e 's/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile" "$tmpdepfile".bak
|
||||
;;
|
||||
|
||||
cpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
# Remove `-o $object'.
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case $arg in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift # fnord
|
||||
shift # $arg
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
"$@" -E |
|
||||
sed -n -e '/^# [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' \
|
||||
-e '/^#line [0-9][0-9]* "\([^"]*\)".*/ s:: \1 \\:p' |
|
||||
sed '$ s: \\$::' > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
cat < "$tmpdepfile" >> "$depfile"
|
||||
sed < "$tmpdepfile" '/^$/d;s/^ //;s/ \\$//;s/$/ :/' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvisualcpp)
|
||||
# Important note: in order to support this mode, a compiler *must*
|
||||
# always write the preprocessed file to stdout.
|
||||
"$@" || exit $?
|
||||
|
||||
# Remove the call to Libtool.
|
||||
if test "$libtool" = yes; then
|
||||
while test "X$1" != 'X--mode=compile'; do
|
||||
shift
|
||||
done
|
||||
shift
|
||||
fi
|
||||
|
||||
IFS=" "
|
||||
for arg
|
||||
do
|
||||
case "$arg" in
|
||||
-o)
|
||||
shift
|
||||
;;
|
||||
$object)
|
||||
shift
|
||||
;;
|
||||
"-Gm"|"/Gm"|"-Gi"|"/Gi"|"-ZI"|"/ZI")
|
||||
set fnord "$@"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
*)
|
||||
set fnord "$@" "$arg"
|
||||
shift
|
||||
shift
|
||||
;;
|
||||
esac
|
||||
done
|
||||
"$@" -E 2>/dev/null |
|
||||
sed -n '/^#line [0-9][0-9]* "\([^"]*\)"/ s::\1:p' | $cygpath_u | sort -u > "$tmpdepfile"
|
||||
rm -f "$depfile"
|
||||
echo "$object : \\" > "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s:: \1 \\:p' >> "$depfile"
|
||||
echo " " >> "$depfile"
|
||||
sed < "$tmpdepfile" -n -e 's% %\\ %g' -e '/^\(.*\)$/ s::\1\::p' >> "$depfile"
|
||||
rm -f "$tmpdepfile"
|
||||
;;
|
||||
|
||||
msvcmsys)
|
||||
# This case exists only to let depend.m4 do its work. It works by
|
||||
# looking at the text of this script. This case will never be run,
|
||||
# since it is checked for above.
|
||||
exit 1
|
||||
;;
|
||||
|
||||
none)
|
||||
exec "$@"
|
||||
;;
|
||||
|
||||
*)
|
||||
echo "Unknown depmode $depmode" 1>&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
exit 0
|
||||
|
||||
# Local Variables:
|
||||
# mode: shell-script
|
||||
# sh-indentation: 2
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
||||
816
src/rt/libuv/ev/ev++.h
Normal file
816
src/rt/libuv/ev/ev++.h
Normal file
|
|
@ -0,0 +1,816 @@
|
|||
/*
|
||||
* libev simple C++ wrapper classes
|
||||
*
|
||||
* 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 EVPP_H__
|
||||
#define EVPP_H__
|
||||
|
||||
#ifdef EV_H
|
||||
# include EV_H
|
||||
#else
|
||||
# include "ev.h"
|
||||
#endif
|
||||
|
||||
#ifndef EV_USE_STDEXCEPT
|
||||
# define EV_USE_STDEXCEPT 1
|
||||
#endif
|
||||
|
||||
#if EV_USE_STDEXCEPT
|
||||
# include <stdexcept>
|
||||
#endif
|
||||
|
||||
namespace ev {
|
||||
|
||||
typedef ev_tstamp tstamp;
|
||||
|
||||
enum {
|
||||
UNDEF = EV_UNDEF,
|
||||
NONE = EV_NONE,
|
||||
READ = EV_READ,
|
||||
WRITE = EV_WRITE,
|
||||
#if EV_COMPAT3
|
||||
TIMEOUT = EV_TIMEOUT,
|
||||
#endif
|
||||
TIMER = EV_TIMER,
|
||||
PERIODIC = EV_PERIODIC,
|
||||
SIGNAL = EV_SIGNAL,
|
||||
CHILD = EV_CHILD,
|
||||
STAT = EV_STAT,
|
||||
IDLE = EV_IDLE,
|
||||
CHECK = EV_CHECK,
|
||||
PREPARE = EV_PREPARE,
|
||||
FORK = EV_FORK,
|
||||
ASYNC = EV_ASYNC,
|
||||
EMBED = EV_EMBED,
|
||||
# undef ERROR // some systems stupidly #define ERROR
|
||||
ERROR = EV_ERROR
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
AUTO = EVFLAG_AUTO,
|
||||
NOENV = EVFLAG_NOENV,
|
||||
FORKCHECK = EVFLAG_FORKCHECK,
|
||||
|
||||
SELECT = EVBACKEND_SELECT,
|
||||
POLL = EVBACKEND_POLL,
|
||||
EPOLL = EVBACKEND_EPOLL,
|
||||
KQUEUE = EVBACKEND_KQUEUE,
|
||||
DEVPOLL = EVBACKEND_DEVPOLL,
|
||||
PORT = EVBACKEND_PORT
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
#if EV_COMPAT3
|
||||
NONBLOCK = EVLOOP_NONBLOCK,
|
||||
ONESHOT = EVLOOP_ONESHOT,
|
||||
#endif
|
||||
NOWAIT = EVRUN_NOWAIT,
|
||||
ONCE = EVRUN_ONCE
|
||||
};
|
||||
|
||||
enum how_t
|
||||
{
|
||||
ONE = EVBREAK_ONE,
|
||||
ALL = EVBREAK_ALL
|
||||
};
|
||||
|
||||
struct bad_loop
|
||||
#if EV_USE_STDEXCEPT
|
||||
: std::runtime_error
|
||||
#endif
|
||||
{
|
||||
#if EV_USE_STDEXCEPT
|
||||
bad_loop ()
|
||||
: std::runtime_error ("libev event loop cannot be initialized, bad value of LIBEV_FLAGS?")
|
||||
{
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef EV_AX
|
||||
# undef EV_AX
|
||||
#endif
|
||||
|
||||
#ifdef EV_AX_
|
||||
# undef EV_AX_
|
||||
#endif
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
# define EV_AX raw_loop
|
||||
# define EV_AX_ raw_loop,
|
||||
#else
|
||||
# define EV_AX
|
||||
# define EV_AX_
|
||||
#endif
|
||||
|
||||
struct loop_ref
|
||||
{
|
||||
loop_ref (EV_P) throw ()
|
||||
#if EV_MULTIPLICITY
|
||||
: EV_AX (EV_A)
|
||||
#endif
|
||||
{
|
||||
}
|
||||
|
||||
bool operator == (const loop_ref &other) const throw ()
|
||||
{
|
||||
#if EV_MULTIPLICITY
|
||||
return EV_AX == other.EV_AX;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool operator != (const loop_ref &other) const throw ()
|
||||
{
|
||||
#if EV_MULTIPLICITY
|
||||
return ! (*this == other);
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
bool operator == (const EV_P) const throw ()
|
||||
{
|
||||
return this->EV_AX == EV_A;
|
||||
}
|
||||
|
||||
bool operator != (const EV_P) const throw ()
|
||||
{
|
||||
return (*this == EV_A);
|
||||
}
|
||||
|
||||
operator struct ev_loop * () const throw ()
|
||||
{
|
||||
return EV_AX;
|
||||
}
|
||||
|
||||
operator const struct ev_loop * () const throw ()
|
||||
{
|
||||
return EV_AX;
|
||||
}
|
||||
|
||||
bool is_default () const throw ()
|
||||
{
|
||||
return EV_AX == ev_default_loop (0);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if EV_COMPAT3
|
||||
void loop (int flags = 0)
|
||||
{
|
||||
ev_run (EV_AX_ flags);
|
||||
}
|
||||
|
||||
void unloop (how_t how = ONE) throw ()
|
||||
{
|
||||
ev_break (EV_AX_ how);
|
||||
}
|
||||
#endif
|
||||
|
||||
void run (int flags = 0)
|
||||
{
|
||||
ev_run (EV_AX_ flags);
|
||||
}
|
||||
|
||||
void break_loop (how_t how = ONE) throw ()
|
||||
{
|
||||
ev_break (EV_AX_ how);
|
||||
}
|
||||
|
||||
void post_fork () throw ()
|
||||
{
|
||||
ev_loop_fork (EV_AX);
|
||||
}
|
||||
|
||||
unsigned int backend () const throw ()
|
||||
{
|
||||
return ev_backend (EV_AX);
|
||||
}
|
||||
|
||||
tstamp now () const throw ()
|
||||
{
|
||||
return ev_now (EV_AX);
|
||||
}
|
||||
|
||||
void ref () throw ()
|
||||
{
|
||||
ev_ref (EV_AX);
|
||||
}
|
||||
|
||||
void unref () throw ()
|
||||
{
|
||||
ev_unref (EV_AX);
|
||||
}
|
||||
|
||||
#if EV_FEATURE_API
|
||||
unsigned int iteration () const throw ()
|
||||
{
|
||||
return ev_iteration (EV_AX);
|
||||
}
|
||||
|
||||
unsigned int depth () const throw ()
|
||||
{
|
||||
return ev_depth (EV_AX);
|
||||
}
|
||||
|
||||
void set_io_collect_interval (tstamp interval) throw ()
|
||||
{
|
||||
ev_set_io_collect_interval (EV_AX_ interval);
|
||||
}
|
||||
|
||||
void set_timeout_collect_interval (tstamp interval) throw ()
|
||||
{
|
||||
ev_set_timeout_collect_interval (EV_AX_ interval);
|
||||
}
|
||||
#endif
|
||||
|
||||
// function callback
|
||||
void once (int fd, int events, tstamp timeout, void (*cb)(int, void *), void *arg = 0) throw ()
|
||||
{
|
||||
ev_once (EV_AX_ fd, events, timeout, cb, arg);
|
||||
}
|
||||
|
||||
// method callback
|
||||
template<class K, void (K::*method)(int)>
|
||||
void once (int fd, int events, tstamp timeout, K *object) throw ()
|
||||
{
|
||||
once (fd, events, timeout, method_thunk<K, method>, object);
|
||||
}
|
||||
|
||||
// default method == operator ()
|
||||
template<class K>
|
||||
void once (int fd, int events, tstamp timeout, K *object) throw ()
|
||||
{
|
||||
once (fd, events, timeout, method_thunk<K, &K::operator ()>, object);
|
||||
}
|
||||
|
||||
template<class K, void (K::*method)(int)>
|
||||
static void method_thunk (int revents, void *arg)
|
||||
{
|
||||
static_cast<K *>(arg)->*method
|
||||
(revents);
|
||||
}
|
||||
|
||||
// no-argument method callback
|
||||
template<class K, void (K::*method)()>
|
||||
void once (int fd, int events, tstamp timeout, K *object) throw ()
|
||||
{
|
||||
once (fd, events, timeout, method_noargs_thunk<K, method>, object);
|
||||
}
|
||||
|
||||
template<class K, void (K::*method)()>
|
||||
static void method_noargs_thunk (int revents, void *arg)
|
||||
{
|
||||
static_cast<K *>(arg)->*method
|
||||
();
|
||||
}
|
||||
|
||||
// simpler function callback
|
||||
template<void (*cb)(int)>
|
||||
void once (int fd, int events, tstamp timeout) throw ()
|
||||
{
|
||||
once (fd, events, timeout, simpler_func_thunk<cb>);
|
||||
}
|
||||
|
||||
template<void (*cb)(int)>
|
||||
static void simpler_func_thunk (int revents, void *arg)
|
||||
{
|
||||
(*cb)
|
||||
(revents);
|
||||
}
|
||||
|
||||
// simplest function callback
|
||||
template<void (*cb)()>
|
||||
void once (int fd, int events, tstamp timeout) throw ()
|
||||
{
|
||||
once (fd, events, timeout, simplest_func_thunk<cb>);
|
||||
}
|
||||
|
||||
template<void (*cb)()>
|
||||
static void simplest_func_thunk (int revents, void *arg)
|
||||
{
|
||||
(*cb)
|
||||
();
|
||||
}
|
||||
|
||||
void feed_fd_event (int fd, int revents) throw ()
|
||||
{
|
||||
ev_feed_fd_event (EV_AX_ fd, revents);
|
||||
}
|
||||
|
||||
void feed_signal_event (int signum) throw ()
|
||||
{
|
||||
ev_feed_signal_event (EV_AX_ signum);
|
||||
}
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
struct ev_loop* EV_AX;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
struct dynamic_loop : loop_ref
|
||||
{
|
||||
|
||||
dynamic_loop (unsigned int flags = AUTO) throw (bad_loop)
|
||||
: loop_ref (ev_loop_new (flags))
|
||||
{
|
||||
if (!EV_AX)
|
||||
throw bad_loop ();
|
||||
}
|
||||
|
||||
~dynamic_loop () throw ()
|
||||
{
|
||||
ev_loop_destroy (EV_AX);
|
||||
EV_AX = 0;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
dynamic_loop (const dynamic_loop &);
|
||||
|
||||
dynamic_loop & operator= (const dynamic_loop &);
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
struct default_loop : loop_ref
|
||||
{
|
||||
default_loop (unsigned int flags = AUTO) throw (bad_loop)
|
||||
#if EV_MULTIPLICITY
|
||||
: loop_ref (ev_default_loop (flags))
|
||||
#endif
|
||||
{
|
||||
if (
|
||||
#if EV_MULTIPLICITY
|
||||
!EV_AX
|
||||
#else
|
||||
!ev_default_loop (flags)
|
||||
#endif
|
||||
)
|
||||
throw bad_loop ();
|
||||
}
|
||||
|
||||
private:
|
||||
default_loop (const default_loop &);
|
||||
default_loop &operator = (const default_loop &);
|
||||
};
|
||||
|
||||
inline loop_ref get_default_loop () throw ()
|
||||
{
|
||||
#if EV_MULTIPLICITY
|
||||
return ev_default_loop (0);
|
||||
#else
|
||||
return loop_ref ();
|
||||
#endif
|
||||
}
|
||||
|
||||
#undef EV_AX
|
||||
#undef EV_AX_
|
||||
|
||||
#undef EV_PX
|
||||
#undef EV_PX_
|
||||
#if EV_MULTIPLICITY
|
||||
# define EV_PX loop_ref EV_A
|
||||
# define EV_PX_ loop_ref EV_A_
|
||||
#else
|
||||
# define EV_PX
|
||||
# define EV_PX_
|
||||
#endif
|
||||
|
||||
template<class ev_watcher, class watcher>
|
||||
struct base : ev_watcher
|
||||
{
|
||||
#if EV_MULTIPLICITY
|
||||
EV_PX;
|
||||
|
||||
// loop set
|
||||
void set (EV_P) throw ()
|
||||
{
|
||||
this->EV_A = EV_A;
|
||||
}
|
||||
#endif
|
||||
|
||||
base (EV_PX) throw ()
|
||||
#if EV_MULTIPLICITY
|
||||
: EV_A (EV_A)
|
||||
#endif
|
||||
{
|
||||
ev_init (this, 0);
|
||||
}
|
||||
|
||||
void set_ (const void *data, void (*cb)(EV_P_ ev_watcher *w, int revents)) throw ()
|
||||
{
|
||||
this->data = (void *)data;
|
||||
ev_set_cb (static_cast<ev_watcher *>(this), cb);
|
||||
}
|
||||
|
||||
// function callback
|
||||
template<void (*function)(watcher &w, int)>
|
||||
void set (void *data = 0) throw ()
|
||||
{
|
||||
set_ (data, function_thunk<function>);
|
||||
}
|
||||
|
||||
template<void (*function)(watcher &w, int)>
|
||||
static void function_thunk (EV_P_ ev_watcher *w, int revents)
|
||||
{
|
||||
function
|
||||
(*static_cast<watcher *>(w), revents);
|
||||
}
|
||||
|
||||
// method callback
|
||||
template<class K, void (K::*method)(watcher &w, int)>
|
||||
void set (K *object) throw ()
|
||||
{
|
||||
set_ (object, method_thunk<K, method>);
|
||||
}
|
||||
|
||||
// default method == operator ()
|
||||
template<class K>
|
||||
void set (K *object) throw ()
|
||||
{
|
||||
set_ (object, method_thunk<K, &K::operator ()>);
|
||||
}
|
||||
|
||||
template<class K, void (K::*method)(watcher &w, int)>
|
||||
static void method_thunk (EV_P_ ev_watcher *w, int revents)
|
||||
{
|
||||
(static_cast<K *>(w->data)->*method)
|
||||
(*static_cast<watcher *>(w), revents);
|
||||
}
|
||||
|
||||
// no-argument callback
|
||||
template<class K, void (K::*method)()>
|
||||
void set (K *object) throw ()
|
||||
{
|
||||
set_ (object, method_noargs_thunk<K, method>);
|
||||
}
|
||||
|
||||
template<class K, void (K::*method)()>
|
||||
static void method_noargs_thunk (EV_P_ ev_watcher *w, int revents)
|
||||
{
|
||||
(static_cast<K *>(w->data)->*method)
|
||||
();
|
||||
}
|
||||
|
||||
void operator ()(int events = EV_UNDEF)
|
||||
{
|
||||
return
|
||||
ev_cb (static_cast<ev_watcher *>(this))
|
||||
(static_cast<ev_watcher *>(this), events);
|
||||
}
|
||||
|
||||
bool is_active () const throw ()
|
||||
{
|
||||
return ev_is_active (static_cast<const ev_watcher *>(this));
|
||||
}
|
||||
|
||||
bool is_pending () const throw ()
|
||||
{
|
||||
return ev_is_pending (static_cast<const ev_watcher *>(this));
|
||||
}
|
||||
|
||||
void feed_event (int revents) throw ()
|
||||
{
|
||||
ev_feed_event (EV_A_ static_cast<const ev_watcher *>(this), revents);
|
||||
}
|
||||
};
|
||||
|
||||
inline tstamp now () throw ()
|
||||
{
|
||||
return ev_time ();
|
||||
}
|
||||
|
||||
inline void delay (tstamp interval) throw ()
|
||||
{
|
||||
ev_sleep (interval);
|
||||
}
|
||||
|
||||
inline int version_major () throw ()
|
||||
{
|
||||
return ev_version_major ();
|
||||
}
|
||||
|
||||
inline int version_minor () throw ()
|
||||
{
|
||||
return ev_version_minor ();
|
||||
}
|
||||
|
||||
inline unsigned int supported_backends () throw ()
|
||||
{
|
||||
return ev_supported_backends ();
|
||||
}
|
||||
|
||||
inline unsigned int recommended_backends () throw ()
|
||||
{
|
||||
return ev_recommended_backends ();
|
||||
}
|
||||
|
||||
inline unsigned int embeddable_backends () throw ()
|
||||
{
|
||||
return ev_embeddable_backends ();
|
||||
}
|
||||
|
||||
inline void set_allocator (void *(*cb)(void *ptr, long size)) throw ()
|
||||
{
|
||||
ev_set_allocator (cb);
|
||||
}
|
||||
|
||||
inline void set_syserr_cb (void (*cb)(const char *msg)) throw ()
|
||||
{
|
||||
ev_set_syserr_cb (cb);
|
||||
}
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
#define EV_CONSTRUCT(cppstem,cstem) \
|
||||
(EV_PX = get_default_loop ()) throw () \
|
||||
: base<ev_ ## cstem, cppstem> (EV_A) \
|
||||
{ \
|
||||
}
|
||||
#else
|
||||
#define EV_CONSTRUCT(cppstem,cstem) \
|
||||
() throw () \
|
||||
{ \
|
||||
}
|
||||
#endif
|
||||
|
||||
/* using a template here would require quite a bit more lines,
|
||||
* so a macro solution was chosen */
|
||||
#define EV_BEGIN_WATCHER(cppstem,cstem) \
|
||||
\
|
||||
struct cppstem : base<ev_ ## cstem, cppstem> \
|
||||
{ \
|
||||
void start () throw () \
|
||||
{ \
|
||||
ev_ ## cstem ## _start (EV_A_ static_cast<ev_ ## cstem *>(this)); \
|
||||
} \
|
||||
\
|
||||
void stop () throw () \
|
||||
{ \
|
||||
ev_ ## cstem ## _stop (EV_A_ static_cast<ev_ ## cstem *>(this)); \
|
||||
} \
|
||||
\
|
||||
cppstem EV_CONSTRUCT(cppstem,cstem) \
|
||||
\
|
||||
~cppstem () throw () \
|
||||
{ \
|
||||
stop (); \
|
||||
} \
|
||||
\
|
||||
using base<ev_ ## cstem, cppstem>::set; \
|
||||
\
|
||||
private: \
|
||||
\
|
||||
cppstem (const cppstem &o); \
|
||||
\
|
||||
cppstem &operator =(const cppstem &o); \
|
||||
\
|
||||
public:
|
||||
|
||||
#define EV_END_WATCHER(cppstem,cstem) \
|
||||
};
|
||||
|
||||
EV_BEGIN_WATCHER (io, io)
|
||||
void set (int fd, int events) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_io_set (static_cast<ev_io *>(this), fd, events);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void set (int events) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_io_set (static_cast<ev_io *>(this), fd, events);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void start (int fd, int events) throw ()
|
||||
{
|
||||
set (fd, events);
|
||||
start ();
|
||||
}
|
||||
EV_END_WATCHER (io, io)
|
||||
|
||||
EV_BEGIN_WATCHER (timer, timer)
|
||||
void set (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_timer_set (static_cast<ev_timer *>(this), after, repeat);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void start (ev_tstamp after, ev_tstamp repeat = 0.) throw ()
|
||||
{
|
||||
set (after, repeat);
|
||||
start ();
|
||||
}
|
||||
|
||||
void again () throw ()
|
||||
{
|
||||
ev_timer_again (EV_A_ static_cast<ev_timer *>(this));
|
||||
}
|
||||
|
||||
ev_tstamp remaining ()
|
||||
{
|
||||
return ev_timer_remaining (EV_A_ static_cast<ev_timer *>(this));
|
||||
}
|
||||
EV_END_WATCHER (timer, timer)
|
||||
|
||||
#if EV_PERIODIC_ENABLE
|
||||
EV_BEGIN_WATCHER (periodic, periodic)
|
||||
void set (ev_tstamp at, ev_tstamp interval = 0.) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_periodic_set (static_cast<ev_periodic *>(this), at, interval, 0);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void start (ev_tstamp at, ev_tstamp interval = 0.) throw ()
|
||||
{
|
||||
set (at, interval);
|
||||
start ();
|
||||
}
|
||||
|
||||
void again () throw ()
|
||||
{
|
||||
ev_periodic_again (EV_A_ static_cast<ev_periodic *>(this));
|
||||
}
|
||||
EV_END_WATCHER (periodic, periodic)
|
||||
#endif
|
||||
|
||||
#if EV_SIGNAL_ENABLE
|
||||
EV_BEGIN_WATCHER (sig, signal)
|
||||
void set (int signum) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_signal_set (static_cast<ev_signal *>(this), signum);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void start (int signum) throw ()
|
||||
{
|
||||
set (signum);
|
||||
start ();
|
||||
}
|
||||
EV_END_WATCHER (sig, signal)
|
||||
#endif
|
||||
|
||||
#if EV_CHILD_ENABLE
|
||||
EV_BEGIN_WATCHER (child, child)
|
||||
void set (int pid, int trace = 0) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_child_set (static_cast<ev_child *>(this), pid, trace);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void start (int pid, int trace = 0) throw ()
|
||||
{
|
||||
set (pid, trace);
|
||||
start ();
|
||||
}
|
||||
EV_END_WATCHER (child, child)
|
||||
#endif
|
||||
|
||||
#if EV_STAT_ENABLE
|
||||
EV_BEGIN_WATCHER (stat, stat)
|
||||
void set (const char *path, ev_tstamp interval = 0.) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_stat_set (static_cast<ev_stat *>(this), path, interval);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void start (const char *path, ev_tstamp interval = 0.) throw ()
|
||||
{
|
||||
stop ();
|
||||
set (path, interval);
|
||||
start ();
|
||||
}
|
||||
|
||||
void update () throw ()
|
||||
{
|
||||
ev_stat_stat (EV_A_ static_cast<ev_stat *>(this));
|
||||
}
|
||||
EV_END_WATCHER (stat, stat)
|
||||
#endif
|
||||
|
||||
#if EV_IDLE_ENABLE
|
||||
EV_BEGIN_WATCHER (idle, idle)
|
||||
void set () throw () { }
|
||||
EV_END_WATCHER (idle, idle)
|
||||
#endif
|
||||
|
||||
#if EV_PREPARE_ENABLE
|
||||
EV_BEGIN_WATCHER (prepare, prepare)
|
||||
void set () throw () { }
|
||||
EV_END_WATCHER (prepare, prepare)
|
||||
#endif
|
||||
|
||||
#if EV_CHECK_ENABLE
|
||||
EV_BEGIN_WATCHER (check, check)
|
||||
void set () throw () { }
|
||||
EV_END_WATCHER (check, check)
|
||||
#endif
|
||||
|
||||
#if EV_EMBED_ENABLE
|
||||
EV_BEGIN_WATCHER (embed, embed)
|
||||
void set (struct ev_loop *embedded_loop) throw ()
|
||||
{
|
||||
int active = is_active ();
|
||||
if (active) stop ();
|
||||
ev_embed_set (static_cast<ev_embed *>(this), embedded_loop);
|
||||
if (active) start ();
|
||||
}
|
||||
|
||||
void start (struct ev_loop *embedded_loop) throw ()
|
||||
{
|
||||
set (embedded_loop);
|
||||
start ();
|
||||
}
|
||||
|
||||
void sweep ()
|
||||
{
|
||||
ev_embed_sweep (EV_A_ static_cast<ev_embed *>(this));
|
||||
}
|
||||
EV_END_WATCHER (embed, embed)
|
||||
#endif
|
||||
|
||||
#if EV_FORK_ENABLE
|
||||
EV_BEGIN_WATCHER (fork, fork)
|
||||
void set () throw () { }
|
||||
EV_END_WATCHER (fork, fork)
|
||||
#endif
|
||||
|
||||
#if EV_ASYNC_ENABLE
|
||||
EV_BEGIN_WATCHER (async, async)
|
||||
void send () throw ()
|
||||
{
|
||||
ev_async_send (EV_A_ static_cast<ev_async *>(this));
|
||||
}
|
||||
|
||||
bool async_pending () throw ()
|
||||
{
|
||||
return ev_async_pending (static_cast<ev_async *>(this));
|
||||
}
|
||||
EV_END_WATCHER (async, async)
|
||||
#endif
|
||||
|
||||
#undef EV_PX
|
||||
#undef EV_PX_
|
||||
#undef EV_CONSTRUCT
|
||||
#undef EV_BEGIN_WATCHER
|
||||
#undef EV_END_WATCHER
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
5311
src/rt/libuv/ev/ev.3
Normal file
5311
src/rt/libuv/ev/ev.3
Normal file
File diff suppressed because it is too large
Load diff
3913
src/rt/libuv/ev/ev.c
Normal file
3913
src/rt/libuv/ev/ev.c
Normal file
File diff suppressed because it is too large
Load diff
829
src/rt/libuv/ev/ev.h
Normal file
829
src/rt/libuv/ev/ev.h
Normal file
|
|
@ -0,0 +1,829 @@
|
|||
/*
|
||||
* libev native API header
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef EV_H_
|
||||
#define EV_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
# define EV_CPP(x) x
|
||||
#else
|
||||
# define EV_CPP(x)
|
||||
#endif
|
||||
|
||||
EV_CPP(extern "C" {)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* pre-4.0 compatibility */
|
||||
#ifndef EV_COMPAT3
|
||||
# define EV_COMPAT3 1
|
||||
#endif
|
||||
|
||||
#ifndef EV_FEATURES
|
||||
# define EV_FEATURES 0x7f
|
||||
#endif
|
||||
|
||||
#define EV_FEATURE_CODE ((EV_FEATURES) & 1)
|
||||
#define EV_FEATURE_DATA ((EV_FEATURES) & 2)
|
||||
#define EV_FEATURE_CONFIG ((EV_FEATURES) & 4)
|
||||
#define EV_FEATURE_API ((EV_FEATURES) & 8)
|
||||
#define EV_FEATURE_WATCHERS ((EV_FEATURES) & 16)
|
||||
#define EV_FEATURE_BACKENDS ((EV_FEATURES) & 32)
|
||||
#define EV_FEATURE_OS ((EV_FEATURES) & 64)
|
||||
|
||||
/* these priorities are inclusive, higher priorities will be invoked earlier */
|
||||
#ifndef EV_MINPRI
|
||||
# define EV_MINPRI (EV_FEATURE_CONFIG ? -2 : 0)
|
||||
#endif
|
||||
#ifndef EV_MAXPRI
|
||||
# define EV_MAXPRI (EV_FEATURE_CONFIG ? +2 : 0)
|
||||
#endif
|
||||
|
||||
#ifndef EV_MULTIPLICITY
|
||||
# define EV_MULTIPLICITY EV_FEATURE_CONFIG
|
||||
#endif
|
||||
|
||||
#ifndef EV_PERIODIC_ENABLE
|
||||
# define EV_PERIODIC_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_STAT_ENABLE
|
||||
# define EV_STAT_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_PREPARE_ENABLE
|
||||
# define EV_PREPARE_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_CHECK_ENABLE
|
||||
# define EV_CHECK_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_IDLE_ENABLE
|
||||
# define EV_IDLE_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_FORK_ENABLE
|
||||
# define EV_FORK_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_CLEANUP_ENABLE
|
||||
# define EV_CLEANUP_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_SIGNAL_ENABLE
|
||||
# define EV_SIGNAL_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_CHILD_ENABLE
|
||||
# ifdef _WIN32
|
||||
# define EV_CHILD_ENABLE 0
|
||||
# else
|
||||
# define EV_CHILD_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef EV_ASYNC_ENABLE
|
||||
# define EV_ASYNC_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_EMBED_ENABLE
|
||||
# define EV_EMBED_ENABLE EV_FEATURE_WATCHERS
|
||||
#endif
|
||||
|
||||
#ifndef EV_WALK_ENABLE
|
||||
# define EV_WALK_ENABLE 0 /* not yet */
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#if EV_CHILD_ENABLE && !EV_SIGNAL_ENABLE
|
||||
# undef EV_SIGNAL_ENABLE
|
||||
# define EV_SIGNAL_ENABLE 1
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef double ev_tstamp;
|
||||
|
||||
#ifndef EV_ATOMIC_T
|
||||
# include <signal.h>
|
||||
# define EV_ATOMIC_T sig_atomic_t volatile
|
||||
#endif
|
||||
|
||||
#if EV_STAT_ENABLE
|
||||
# ifdef _WIN32
|
||||
# include <time.h>
|
||||
# include <sys/types.h>
|
||||
# endif
|
||||
# include <sys/stat.h>
|
||||
#endif
|
||||
|
||||
/* support multiple event loops? */
|
||||
#if EV_MULTIPLICITY
|
||||
struct ev_loop;
|
||||
# define EV_P struct ev_loop *loop /* a loop as sole parameter in a declaration */
|
||||
# define EV_P_ EV_P, /* a loop as first of multiple parameters */
|
||||
# define EV_A loop /* a loop as sole argument to a function call */
|
||||
# define EV_A_ EV_A, /* a loop as first of multiple arguments */
|
||||
# define EV_DEFAULT_UC ev_default_loop_uc_ () /* the default loop, if initialised, as sole arg */
|
||||
# define EV_DEFAULT_UC_ EV_DEFAULT_UC, /* the default loop as first of multiple arguments */
|
||||
# define EV_DEFAULT ev_default_loop (0) /* the default loop as sole arg */
|
||||
# define EV_DEFAULT_ EV_DEFAULT, /* the default loop as first of multiple arguments */
|
||||
#else
|
||||
# define EV_P void
|
||||
# define EV_P_
|
||||
# define EV_A
|
||||
# define EV_A_
|
||||
# define EV_DEFAULT
|
||||
# define EV_DEFAULT_
|
||||
# define EV_DEFAULT_UC
|
||||
# define EV_DEFAULT_UC_
|
||||
# undef EV_EMBED_ENABLE
|
||||
#endif
|
||||
|
||||
/* EV_INLINE is used for functions in header files */
|
||||
#if __STDC_VERSION__ >= 199901L && __GNUC__ >= 3
|
||||
# define EV_INLINE static inline
|
||||
#else
|
||||
# define EV_INLINE static
|
||||
#endif
|
||||
|
||||
/* EV_PROTOTYPES can be used to switch of prototype declarations */
|
||||
#ifndef EV_PROTOTYPES
|
||||
# define EV_PROTOTYPES 1
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define EV_VERSION_MAJOR 4
|
||||
#define EV_VERSION_MINOR 4
|
||||
|
||||
/* eventmask, revents, events... */
|
||||
enum {
|
||||
EV_UNDEF = 0xFFFFFFFF, /* guaranteed to be invalid */
|
||||
EV_NONE = 0x00, /* no events */
|
||||
EV_READ = 0x01, /* ev_io detected read will not block */
|
||||
EV_WRITE = 0x02, /* ev_io detected write will not block */
|
||||
EV__IOFDSET = 0x80, /* internal use only */
|
||||
EV_IO = EV_READ, /* alias for type-detection */
|
||||
EV_TIMER = 0x00000100, /* timer timed out */
|
||||
#if EV_COMPAT3
|
||||
EV_TIMEOUT = EV_TIMER, /* pre 4.0 API compatibility */
|
||||
#endif
|
||||
EV_PERIODIC = 0x00000200, /* periodic timer timed out */
|
||||
EV_SIGNAL = 0x00000400, /* signal was received */
|
||||
EV_CHILD = 0x00000800, /* child/pid had status change */
|
||||
EV_STAT = 0x00001000, /* stat data changed */
|
||||
EV_IDLE = 0x00002000, /* event loop is idling */
|
||||
EV_PREPARE = 0x00004000, /* event loop about to poll */
|
||||
EV_CHECK = 0x00008000, /* event loop finished poll */
|
||||
EV_EMBED = 0x00010000, /* embedded event loop needs sweep */
|
||||
EV_FORK = 0x00020000, /* event loop resumed in child */
|
||||
EV_CLEANUP = 0x00040000, /* event loop resumed in child */
|
||||
EV_ASYNC = 0x00080000, /* async intra-loop signal */
|
||||
EV_CUSTOM = 0x01000000, /* for use by user code */
|
||||
EV_ERROR = 0x80000000 /* sent when an error occurs */
|
||||
};
|
||||
|
||||
/* can be used to add custom fields to all watchers, while losing binary compatibility */
|
||||
#ifndef EV_COMMON
|
||||
# define EV_COMMON void *data;
|
||||
#endif
|
||||
|
||||
#ifndef EV_CB_DECLARE
|
||||
# define EV_CB_DECLARE(type) void (*cb)(EV_P_ struct type *w, int revents);
|
||||
#endif
|
||||
#ifndef EV_CB_INVOKE
|
||||
# define EV_CB_INVOKE(watcher,revents) (watcher)->cb (EV_A_ (watcher), (revents))
|
||||
#endif
|
||||
|
||||
/* not official, do not use */
|
||||
#define EV_CB(type,name) void name (EV_P_ struct ev_ ## type *w, int revents)
|
||||
|
||||
/*
|
||||
* struct member types:
|
||||
* private: you may look at them, but not change them,
|
||||
* and they might not mean anything to you.
|
||||
* ro: can be read anytime, but only changed when the watcher isn't active.
|
||||
* rw: can be read and modified anytime, even when the watcher is active.
|
||||
*
|
||||
* some internal details that might be helpful for debugging:
|
||||
*
|
||||
* active is either 0, which means the watcher is not active,
|
||||
* or the array index of the watcher (periodics, timers)
|
||||
* or the array index + 1 (most other watchers)
|
||||
* or simply 1 for watchers that aren't in some array.
|
||||
* pending is either 0, in which case the watcher isn't,
|
||||
* or the array index + 1 in the pendings array.
|
||||
*/
|
||||
|
||||
#if EV_MINPRI == EV_MAXPRI
|
||||
# define EV_DECL_PRIORITY
|
||||
#elif !defined (EV_DECL_PRIORITY)
|
||||
# define EV_DECL_PRIORITY int priority;
|
||||
#endif
|
||||
|
||||
/* shared by all watchers */
|
||||
#define EV_WATCHER(type) \
|
||||
int active; /* private */ \
|
||||
int pending; /* private */ \
|
||||
EV_DECL_PRIORITY /* private */ \
|
||||
EV_COMMON /* rw */ \
|
||||
EV_CB_DECLARE (type) /* private */
|
||||
|
||||
#define EV_WATCHER_LIST(type) \
|
||||
EV_WATCHER (type) \
|
||||
struct ev_watcher_list *next; /* private */
|
||||
|
||||
#define EV_WATCHER_TIME(type) \
|
||||
EV_WATCHER (type) \
|
||||
ev_tstamp at; /* private */
|
||||
|
||||
/* base class, nothing to see here unless you subclass */
|
||||
typedef struct ev_watcher
|
||||
{
|
||||
EV_WATCHER (ev_watcher)
|
||||
} ev_watcher;
|
||||
|
||||
/* base class, nothing to see here unless you subclass */
|
||||
typedef struct ev_watcher_list
|
||||
{
|
||||
EV_WATCHER_LIST (ev_watcher_list)
|
||||
} ev_watcher_list;
|
||||
|
||||
/* base class, nothing to see here unless you subclass */
|
||||
typedef struct ev_watcher_time
|
||||
{
|
||||
EV_WATCHER_TIME (ev_watcher_time)
|
||||
} ev_watcher_time;
|
||||
|
||||
/* invoked when fd is either EV_READable or EV_WRITEable */
|
||||
/* revent EV_READ, EV_WRITE */
|
||||
typedef struct ev_io
|
||||
{
|
||||
EV_WATCHER_LIST (ev_io)
|
||||
|
||||
int fd; /* ro */
|
||||
int events; /* ro */
|
||||
} ev_io;
|
||||
|
||||
/* invoked after a specific time, repeatable (based on monotonic clock) */
|
||||
/* revent EV_TIMEOUT */
|
||||
typedef struct ev_timer
|
||||
{
|
||||
EV_WATCHER_TIME (ev_timer)
|
||||
|
||||
ev_tstamp repeat; /* rw */
|
||||
} ev_timer;
|
||||
|
||||
/* invoked at some specific time, possibly repeating at regular intervals (based on UTC) */
|
||||
/* revent EV_PERIODIC */
|
||||
typedef struct ev_periodic
|
||||
{
|
||||
EV_WATCHER_TIME (ev_periodic)
|
||||
|
||||
ev_tstamp offset; /* rw */
|
||||
ev_tstamp interval; /* rw */
|
||||
ev_tstamp (*reschedule_cb)(struct ev_periodic *w, ev_tstamp now); /* rw */
|
||||
} ev_periodic;
|
||||
|
||||
/* invoked when the given signal has been received */
|
||||
/* revent EV_SIGNAL */
|
||||
typedef struct ev_signal
|
||||
{
|
||||
EV_WATCHER_LIST (ev_signal)
|
||||
|
||||
int signum; /* ro */
|
||||
} ev_signal;
|
||||
|
||||
/* invoked when sigchld is received and waitpid indicates the given pid */
|
||||
/* revent EV_CHILD */
|
||||
/* does not support priorities */
|
||||
typedef struct ev_child
|
||||
{
|
||||
EV_WATCHER_LIST (ev_child)
|
||||
|
||||
int flags; /* private */
|
||||
int pid; /* ro */
|
||||
int rpid; /* rw, holds the received pid */
|
||||
int rstatus; /* rw, holds the exit status, use the macros from sys/wait.h */
|
||||
} ev_child;
|
||||
|
||||
#if EV_STAT_ENABLE
|
||||
/* st_nlink = 0 means missing file or other error */
|
||||
# ifdef _WIN32
|
||||
typedef struct _stati64 ev_statdata;
|
||||
# else
|
||||
typedef struct stat ev_statdata;
|
||||
# endif
|
||||
|
||||
/* invoked each time the stat data changes for a given path */
|
||||
/* revent EV_STAT */
|
||||
typedef struct ev_stat
|
||||
{
|
||||
EV_WATCHER_LIST (ev_stat)
|
||||
|
||||
ev_timer timer; /* private */
|
||||
ev_tstamp interval; /* ro */
|
||||
const char *path; /* ro */
|
||||
ev_statdata prev; /* ro */
|
||||
ev_statdata attr; /* ro */
|
||||
|
||||
int wd; /* wd for inotify, fd for kqueue */
|
||||
} ev_stat;
|
||||
#endif
|
||||
|
||||
#if EV_IDLE_ENABLE
|
||||
/* invoked when the nothing else needs to be done, keeps the process from blocking */
|
||||
/* revent EV_IDLE */
|
||||
typedef struct ev_idle
|
||||
{
|
||||
EV_WATCHER (ev_idle)
|
||||
} ev_idle;
|
||||
#endif
|
||||
|
||||
/* invoked for each run of the mainloop, just before the blocking call */
|
||||
/* you can still change events in any way you like */
|
||||
/* revent EV_PREPARE */
|
||||
typedef struct ev_prepare
|
||||
{
|
||||
EV_WATCHER (ev_prepare)
|
||||
} ev_prepare;
|
||||
|
||||
/* invoked for each run of the mainloop, just after the blocking call */
|
||||
/* revent EV_CHECK */
|
||||
typedef struct ev_check
|
||||
{
|
||||
EV_WATCHER (ev_check)
|
||||
} ev_check;
|
||||
|
||||
#if EV_FORK_ENABLE
|
||||
/* the callback gets invoked before check in the child process when a fork was detected */
|
||||
/* revent EV_FORK */
|
||||
typedef struct ev_fork
|
||||
{
|
||||
EV_WATCHER (ev_fork)
|
||||
} ev_fork;
|
||||
#endif
|
||||
|
||||
#if EV_CLEANUP_ENABLE
|
||||
/* is invoked just before the loop gets destroyed */
|
||||
/* revent EV_CLEANUP */
|
||||
typedef struct ev_cleanup
|
||||
{
|
||||
EV_WATCHER (ev_cleanup)
|
||||
} ev_cleanup;
|
||||
#endif
|
||||
|
||||
#if EV_EMBED_ENABLE
|
||||
/* used to embed an event loop inside another */
|
||||
/* the callback gets invoked when the event loop has handled events, and can be 0 */
|
||||
typedef struct ev_embed
|
||||
{
|
||||
EV_WATCHER (ev_embed)
|
||||
|
||||
struct ev_loop *other; /* ro */
|
||||
ev_io io; /* private */
|
||||
ev_prepare prepare; /* private */
|
||||
ev_check check; /* unused */
|
||||
ev_timer timer; /* unused */
|
||||
ev_periodic periodic; /* unused */
|
||||
ev_idle idle; /* unused */
|
||||
ev_fork fork; /* private */
|
||||
#if EV_CLEANUP_ENABLE
|
||||
ev_cleanup cleanup; /* unused */
|
||||
#endif
|
||||
} ev_embed;
|
||||
#endif
|
||||
|
||||
#if EV_ASYNC_ENABLE
|
||||
/* invoked when somebody calls ev_async_send on the watcher */
|
||||
/* revent EV_ASYNC */
|
||||
typedef struct ev_async
|
||||
{
|
||||
EV_WATCHER (ev_async)
|
||||
|
||||
EV_ATOMIC_T sent; /* private */
|
||||
} ev_async;
|
||||
|
||||
# define ev_async_pending(w) (+(w)->sent)
|
||||
#endif
|
||||
|
||||
/* the presence of this union forces similar struct layout */
|
||||
union ev_any_watcher
|
||||
{
|
||||
struct ev_watcher w;
|
||||
struct ev_watcher_list wl;
|
||||
|
||||
struct ev_io io;
|
||||
struct ev_timer timer;
|
||||
struct ev_periodic periodic;
|
||||
struct ev_signal signal;
|
||||
struct ev_child child;
|
||||
#if EV_STAT_ENABLE
|
||||
struct ev_stat stat;
|
||||
#endif
|
||||
#if EV_IDLE_ENABLE
|
||||
struct ev_idle idle;
|
||||
#endif
|
||||
struct ev_prepare prepare;
|
||||
struct ev_check check;
|
||||
#if EV_FORK_ENABLE
|
||||
struct ev_fork fork;
|
||||
#endif
|
||||
#if EV_CLEANUP_ENABLE
|
||||
struct ev_cleanup cleanup;
|
||||
#endif
|
||||
#if EV_EMBED_ENABLE
|
||||
struct ev_embed embed;
|
||||
#endif
|
||||
#if EV_ASYNC_ENABLE
|
||||
struct ev_async async;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* flag bits for ev_default_loop and ev_loop_new */
|
||||
enum {
|
||||
/* the default */
|
||||
EVFLAG_AUTO = 0x00000000U, /* not quite a mask */
|
||||
/* flag bits */
|
||||
EVFLAG_NOENV = 0x01000000U, /* do NOT consult environment */
|
||||
EVFLAG_FORKCHECK = 0x02000000U, /* check for a fork in each iteration */
|
||||
/* debugging/feature disable */
|
||||
EVFLAG_NOINOTIFY = 0x00100000U, /* do not attempt to use inotify */
|
||||
#if EV_COMPAT3
|
||||
EVFLAG_NOSIGFD = 0, /* compatibility to pre-3.9 */
|
||||
#endif
|
||||
EVFLAG_SIGNALFD = 0x00200000U, /* attempt to use signalfd */
|
||||
EVFLAG_NOSIGMASK = 0x00400000U /* avoid modifying the signal mask */
|
||||
};
|
||||
|
||||
/* method bits to be ored together */
|
||||
enum {
|
||||
EVBACKEND_SELECT = 0x00000001U, /* about anywhere */
|
||||
EVBACKEND_POLL = 0x00000002U, /* !win */
|
||||
EVBACKEND_EPOLL = 0x00000004U, /* linux */
|
||||
EVBACKEND_KQUEUE = 0x00000008U, /* bsd */
|
||||
EVBACKEND_DEVPOLL = 0x00000010U, /* solaris 8 */ /* NYI */
|
||||
EVBACKEND_PORT = 0x00000020U, /* solaris 10 */
|
||||
EVBACKEND_ALL = 0x0000003FU, /* all known backends */
|
||||
EVBACKEND_MASK = 0x0000FFFFU /* all future backends */
|
||||
};
|
||||
|
||||
#if EV_PROTOTYPES
|
||||
int ev_version_major (void);
|
||||
int ev_version_minor (void);
|
||||
|
||||
unsigned int ev_supported_backends (void);
|
||||
unsigned int ev_recommended_backends (void);
|
||||
unsigned int ev_embeddable_backends (void);
|
||||
|
||||
ev_tstamp ev_time (void);
|
||||
void ev_sleep (ev_tstamp delay); /* sleep for a while */
|
||||
|
||||
/* Sets the allocation function to use, works like realloc.
|
||||
* It is used to allocate and free memory.
|
||||
* If it returns zero when memory needs to be allocated, the library might abort
|
||||
* or take some potentially destructive action.
|
||||
* The default is your system realloc function.
|
||||
*/
|
||||
void ev_set_allocator (void *(*cb)(void *ptr, long size));
|
||||
|
||||
/* set the callback function to call on a
|
||||
* retryable syscall error
|
||||
* (such as failed select, poll, epoll_wait)
|
||||
*/
|
||||
void ev_set_syserr_cb (void (*cb)(const char *msg));
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
|
||||
/* the default loop is the only one that handles signals and child watchers */
|
||||
/* you can call this as often as you like */
|
||||
struct ev_loop *ev_default_loop (unsigned int flags EV_CPP (= 0));
|
||||
|
||||
EV_INLINE struct ev_loop *
|
||||
ev_default_loop_uc_ (void)
|
||||
{
|
||||
extern struct ev_loop *ev_default_loop_ptr;
|
||||
|
||||
return ev_default_loop_ptr;
|
||||
}
|
||||
|
||||
EV_INLINE int
|
||||
ev_is_default_loop (EV_P)
|
||||
{
|
||||
return EV_A == EV_DEFAULT_UC;
|
||||
}
|
||||
|
||||
/* create and destroy alternative loops that don't handle signals */
|
||||
struct ev_loop *ev_loop_new (unsigned int flags EV_CPP (= 0));
|
||||
|
||||
ev_tstamp ev_now (EV_P); /* time w.r.t. timers and the eventloop, updated after each poll */
|
||||
|
||||
#else
|
||||
|
||||
int ev_default_loop (unsigned int flags EV_CPP (= 0)); /* returns true when successful */
|
||||
|
||||
EV_INLINE ev_tstamp
|
||||
ev_now (void)
|
||||
{
|
||||
extern ev_tstamp ev_rt_now;
|
||||
|
||||
return ev_rt_now;
|
||||
}
|
||||
|
||||
/* looks weird, but ev_is_default_loop (EV_A) still works if this exists */
|
||||
EV_INLINE int
|
||||
ev_is_default_loop (void)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
#endif /* multiplicity */
|
||||
|
||||
/* destroy event loops, also works for the default loop */
|
||||
void ev_loop_destroy (EV_P);
|
||||
|
||||
/* this needs to be called after fork, to duplicate the loop */
|
||||
/* when you want to re-use it in the child */
|
||||
/* you can call it in either the parent or the child */
|
||||
/* you can actually call it at any time, anywhere :) */
|
||||
void ev_loop_fork (EV_P);
|
||||
|
||||
unsigned int ev_backend (EV_P); /* backend in use by loop */
|
||||
|
||||
void ev_now_update (EV_P); /* update event loop time */
|
||||
|
||||
#if EV_WALK_ENABLE
|
||||
/* walk (almost) all watchers in the loop of a given type, invoking the */
|
||||
/* callback on every such watcher. The callback might stop the watcher, */
|
||||
/* but do nothing else with the loop */
|
||||
void ev_walk (EV_P_ int types, void (*cb)(EV_P_ int type, void *w));
|
||||
#endif
|
||||
|
||||
#endif /* prototypes */
|
||||
|
||||
/* ev_run flags values */
|
||||
enum {
|
||||
EVRUN_NOWAIT = 1, /* do not block/wait */
|
||||
EVRUN_ONCE = 2 /* block *once* only */
|
||||
};
|
||||
|
||||
/* ev_break how values */
|
||||
enum {
|
||||
EVBREAK_CANCEL = 0, /* undo unloop */
|
||||
EVBREAK_ONE = 1, /* unloop once */
|
||||
EVBREAK_ALL = 2 /* unloop all loops */
|
||||
};
|
||||
|
||||
#if EV_PROTOTYPES
|
||||
void ev_run (EV_P_ int flags EV_CPP (= 0));
|
||||
void ev_break (EV_P_ int how EV_CPP (= EVBREAK_ONE)); /* break out of the loop */
|
||||
|
||||
/*
|
||||
* ref/unref can be used to add or remove a refcount on the mainloop. every watcher
|
||||
* keeps one reference. if you have a long-running watcher you never unregister that
|
||||
* should not keep ev_loop from running, unref() after starting, and ref() before stopping.
|
||||
*/
|
||||
void ev_ref (EV_P);
|
||||
void ev_unref (EV_P);
|
||||
|
||||
/*
|
||||
* convenience function, wait for a single event, without registering an event watcher
|
||||
* if timeout is < 0, do wait indefinitely
|
||||
*/
|
||||
void ev_once (EV_P_ int fd, int events, ev_tstamp timeout, void (*cb)(int revents, void *arg), void *arg);
|
||||
|
||||
# if EV_FEATURE_API
|
||||
unsigned int ev_iteration (EV_P); /* number of loop iterations */
|
||||
unsigned int ev_depth (EV_P); /* #ev_loop enters - #ev_loop leaves */
|
||||
void ev_verify (EV_P); /* abort if loop data corrupted */
|
||||
|
||||
void ev_set_io_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
|
||||
void ev_set_timeout_collect_interval (EV_P_ ev_tstamp interval); /* sleep at least this time, default 0 */
|
||||
|
||||
/* advanced stuff for threading etc. support, see docs */
|
||||
void ev_set_userdata (EV_P_ void *data);
|
||||
void *ev_userdata (EV_P);
|
||||
void ev_set_invoke_pending_cb (EV_P_ void (*invoke_pending_cb)(EV_P));
|
||||
void ev_set_loop_release_cb (EV_P_ void (*release)(EV_P), void (*acquire)(EV_P));
|
||||
|
||||
unsigned int ev_pending_count (EV_P); /* number of pending events, if any */
|
||||
void ev_invoke_pending (EV_P); /* invoke all pending watchers */
|
||||
|
||||
/*
|
||||
* stop/start the timer handling.
|
||||
*/
|
||||
void ev_suspend (EV_P);
|
||||
void ev_resume (EV_P);
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/* these may evaluate ev multiple times, and the other arguments at most once */
|
||||
/* either use ev_init + ev_TYPE_set, or the ev_TYPE_init macro, below, to first initialise a watcher */
|
||||
#define ev_init(ev,cb_) do { \
|
||||
((ev_watcher *)(void *)(ev))->active = \
|
||||
((ev_watcher *)(void *)(ev))->pending = 0; \
|
||||
ev_set_priority ((ev), 0); \
|
||||
ev_set_cb ((ev), cb_); \
|
||||
} while (0)
|
||||
|
||||
#define ev_io_set(ev,fd_,events_) do { (ev)->fd = (fd_); (ev)->events = (events_) | EV__IOFDSET; } while (0)
|
||||
#define ev_timer_set(ev,after_,repeat_) do { ((ev_watcher_time *)(ev))->at = (after_); (ev)->repeat = (repeat_); } while (0)
|
||||
#define ev_periodic_set(ev,ofs_,ival_,rcb_) do { (ev)->offset = (ofs_); (ev)->interval = (ival_); (ev)->reschedule_cb = (rcb_); } while (0)
|
||||
#define ev_signal_set(ev,signum_) do { (ev)->signum = (signum_); } while (0)
|
||||
#define ev_child_set(ev,pid_,trace_) do { (ev)->pid = (pid_); (ev)->flags = !!(trace_); } while (0)
|
||||
#define ev_stat_set(ev,path_,interval_) do { (ev)->path = (path_); (ev)->interval = (interval_); (ev)->wd = -2; } while (0)
|
||||
#define ev_idle_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_prepare_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_check_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_embed_set(ev,other_) do { (ev)->other = (other_); } while (0)
|
||||
#define ev_fork_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_cleanup_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
#define ev_async_set(ev) /* nop, yes, this is a serious in-joke */
|
||||
|
||||
#define ev_io_init(ev,cb,fd,events) do { ev_init ((ev), (cb)); ev_io_set ((ev),(fd),(events)); } while (0)
|
||||
#define ev_timer_init(ev,cb,after,repeat) do { ev_init ((ev), (cb)); ev_timer_set ((ev),(after),(repeat)); } while (0)
|
||||
#define ev_periodic_init(ev,cb,ofs,ival,rcb) do { ev_init ((ev), (cb)); ev_periodic_set ((ev),(ofs),(ival),(rcb)); } while (0)
|
||||
#define ev_signal_init(ev,cb,signum) do { ev_init ((ev), (cb)); ev_signal_set ((ev), (signum)); } while (0)
|
||||
#define ev_child_init(ev,cb,pid,trace) do { ev_init ((ev), (cb)); ev_child_set ((ev),(pid),(trace)); } while (0)
|
||||
#define ev_stat_init(ev,cb,path,interval) do { ev_init ((ev), (cb)); ev_stat_set ((ev),(path),(interval)); } while (0)
|
||||
#define ev_idle_init(ev,cb) do { ev_init ((ev), (cb)); ev_idle_set ((ev)); } while (0)
|
||||
#define ev_prepare_init(ev,cb) do { ev_init ((ev), (cb)); ev_prepare_set ((ev)); } while (0)
|
||||
#define ev_check_init(ev,cb) do { ev_init ((ev), (cb)); ev_check_set ((ev)); } while (0)
|
||||
#define ev_embed_init(ev,cb,other) do { ev_init ((ev), (cb)); ev_embed_set ((ev),(other)); } while (0)
|
||||
#define ev_fork_init(ev,cb) do { ev_init ((ev), (cb)); ev_fork_set ((ev)); } while (0)
|
||||
#define ev_cleanup_init(ev,cb) do { ev_init ((ev), (cb)); ev_cleanup_set ((ev)); } while (0)
|
||||
#define ev_async_init(ev,cb) do { ev_init ((ev), (cb)); ev_async_set ((ev)); } while (0)
|
||||
|
||||
#define ev_is_pending(ev) (0 + ((ev_watcher *)(void *)(ev))->pending) /* ro, true when watcher is waiting for callback invocation */
|
||||
#define ev_is_active(ev) (0 + ((ev_watcher *)(void *)(ev))->active) /* ro, true when the watcher has been started */
|
||||
|
||||
#define ev_cb(ev) (ev)->cb /* rw */
|
||||
|
||||
#if EV_MINPRI == EV_MAXPRI
|
||||
# define ev_priority(ev) ((ev), EV_MINPRI)
|
||||
# define ev_set_priority(ev,pri) ((ev), (pri))
|
||||
#else
|
||||
# define ev_priority(ev) (+(((ev_watcher *)(void *)(ev))->priority))
|
||||
# define ev_set_priority(ev,pri) ( (ev_watcher *)(void *)(ev))->priority = (pri)
|
||||
#endif
|
||||
|
||||
#define ev_periodic_at(ev) (+((ev_watcher_time *)(ev))->at)
|
||||
|
||||
#ifndef ev_set_cb
|
||||
# define ev_set_cb(ev,cb_) ev_cb (ev) = (cb_)
|
||||
#endif
|
||||
|
||||
/* stopping (enabling, adding) a watcher does nothing if it is already running */
|
||||
/* stopping (disabling, deleting) a watcher does nothing unless its already running */
|
||||
#if EV_PROTOTYPES
|
||||
|
||||
/* feeds an event into a watcher as if the event actually occured */
|
||||
/* accepts any ev_watcher type */
|
||||
void ev_feed_event (EV_P_ void *w, int revents);
|
||||
void ev_feed_fd_event (EV_P_ int fd, int revents);
|
||||
#if EV_SIGNAL_ENABLE
|
||||
void ev_feed_signal (int signum);
|
||||
void ev_feed_signal_event (EV_P_ int signum);
|
||||
#endif
|
||||
void ev_invoke (EV_P_ void *w, int revents);
|
||||
int ev_clear_pending (EV_P_ void *w);
|
||||
|
||||
void ev_io_start (EV_P_ ev_io *w);
|
||||
void ev_io_stop (EV_P_ ev_io *w);
|
||||
|
||||
void ev_timer_start (EV_P_ ev_timer *w);
|
||||
void ev_timer_stop (EV_P_ ev_timer *w);
|
||||
/* stops if active and no repeat, restarts if active and repeating, starts if inactive and repeating */
|
||||
void ev_timer_again (EV_P_ ev_timer *w);
|
||||
/* return remaining time */
|
||||
ev_tstamp ev_timer_remaining (EV_P_ ev_timer *w);
|
||||
|
||||
#if EV_PERIODIC_ENABLE
|
||||
void ev_periodic_start (EV_P_ ev_periodic *w);
|
||||
void ev_periodic_stop (EV_P_ ev_periodic *w);
|
||||
void ev_periodic_again (EV_P_ ev_periodic *w);
|
||||
#endif
|
||||
|
||||
/* only supported in the default loop */
|
||||
#if EV_SIGNAL_ENABLE
|
||||
void ev_signal_start (EV_P_ ev_signal *w);
|
||||
void ev_signal_stop (EV_P_ ev_signal *w);
|
||||
#endif
|
||||
|
||||
/* only supported in the default loop */
|
||||
# if EV_CHILD_ENABLE
|
||||
void ev_child_start (EV_P_ ev_child *w);
|
||||
void ev_child_stop (EV_P_ ev_child *w);
|
||||
# endif
|
||||
|
||||
# if EV_STAT_ENABLE
|
||||
void ev_stat_start (EV_P_ ev_stat *w);
|
||||
void ev_stat_stop (EV_P_ ev_stat *w);
|
||||
void ev_stat_stat (EV_P_ ev_stat *w);
|
||||
# endif
|
||||
|
||||
# if EV_IDLE_ENABLE
|
||||
void ev_idle_start (EV_P_ ev_idle *w);
|
||||
void ev_idle_stop (EV_P_ ev_idle *w);
|
||||
# endif
|
||||
|
||||
#if EV_PREPARE_ENABLE
|
||||
void ev_prepare_start (EV_P_ ev_prepare *w);
|
||||
void ev_prepare_stop (EV_P_ ev_prepare *w);
|
||||
#endif
|
||||
|
||||
#if EV_CHECK_ENABLE
|
||||
void ev_check_start (EV_P_ ev_check *w);
|
||||
void ev_check_stop (EV_P_ ev_check *w);
|
||||
#endif
|
||||
|
||||
# if EV_FORK_ENABLE
|
||||
void ev_fork_start (EV_P_ ev_fork *w);
|
||||
void ev_fork_stop (EV_P_ ev_fork *w);
|
||||
# endif
|
||||
|
||||
# if EV_CLEANUP_ENABLE
|
||||
void ev_cleanup_start (EV_P_ ev_cleanup *w);
|
||||
void ev_cleanup_stop (EV_P_ ev_cleanup *w);
|
||||
# endif
|
||||
|
||||
# if EV_EMBED_ENABLE
|
||||
/* only supported when loop to be embedded is in fact embeddable */
|
||||
void ev_embed_start (EV_P_ ev_embed *w);
|
||||
void ev_embed_stop (EV_P_ ev_embed *w);
|
||||
void ev_embed_sweep (EV_P_ ev_embed *w);
|
||||
# endif
|
||||
|
||||
# if EV_ASYNC_ENABLE
|
||||
void ev_async_start (EV_P_ ev_async *w);
|
||||
void ev_async_stop (EV_P_ ev_async *w);
|
||||
void ev_async_send (EV_P_ ev_async *w);
|
||||
# endif
|
||||
|
||||
#if EV_COMPAT3
|
||||
#define EVLOOP_NONBLOCK EVRUN_NOWAIT
|
||||
#define EVLOOP_ONESHOT EVRUN_ONCE
|
||||
#define EVUNLOOP_CANCEL EVBREAK_CANCEL
|
||||
#define EVUNLOOP_ONE EVBREAK_ONE
|
||||
#define EVUNLOOP_ALL EVBREAK_ALL
|
||||
#if EV_PROTOTYPES
|
||||
EV_INLINE void ev_loop (EV_P_ int flags) { ev_run (EV_A_ flags); }
|
||||
EV_INLINE void ev_unloop (EV_P_ int how ) { ev_break (EV_A_ how ); }
|
||||
EV_INLINE void ev_default_destroy (void) { ev_loop_destroy (EV_DEFAULT); }
|
||||
EV_INLINE void ev_default_fork (void) { ev_loop_fork (EV_DEFAULT); }
|
||||
#if EV_FEATURE_API
|
||||
EV_INLINE unsigned int ev_loop_count (EV_P) { return ev_iteration (EV_A); }
|
||||
EV_INLINE unsigned int ev_loop_depth (EV_P) { return ev_depth (EV_A); }
|
||||
EV_INLINE void ev_loop_verify (EV_P) { ev_verify (EV_A); }
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
typedef struct ev_loop ev_loop;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
EV_CPP(})
|
||||
|
||||
#endif
|
||||
|
||||
5243
src/rt/libuv/ev/ev.pod
Normal file
5243
src/rt/libuv/ev/ev.pod
Normal file
File diff suppressed because it is too large
Load diff
266
src/rt/libuv/ev/ev_epoll.c
Normal file
266
src/rt/libuv/ev/ev_epoll.c
Normal file
|
|
@ -0,0 +1,266 @@
|
|||
/*
|
||||
* libev epoll fd activity backend
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* general notes about epoll:
|
||||
*
|
||||
* a) epoll silently removes fds from the fd set. as nothing tells us
|
||||
* that an fd has been removed otherwise, we have to continually
|
||||
* "rearm" fds that we suspect *might* have changed (same
|
||||
* problem with kqueue, but much less costly there).
|
||||
* b) the fact that ADD != MOD creates a lot of extra syscalls due to a)
|
||||
* and seems not to have any advantage.
|
||||
* c) the inability to handle fork or file descriptors (think dup)
|
||||
* limits the applicability over poll, so this is not a generic
|
||||
* poll replacement.
|
||||
* d) epoll doesn't work the same as select with many file descriptors
|
||||
* (such as files). while not critical, no other advanced interface
|
||||
* seems to share this (rather non-unixy) limitation.
|
||||
* e) epoll claims to be embeddable, but in practise you never get
|
||||
* a ready event for the epoll fd (broken: <=2.6.26, working: >=2.6.32).
|
||||
* f) epoll_ctl returning EPERM means the fd is always ready.
|
||||
*
|
||||
* lots of "weird code" and complication handling in this file is due
|
||||
* to these design problems with epoll, as we try very hard to avoid
|
||||
* epoll_ctl syscalls for common usage patterns and handle the breakage
|
||||
* ensuing from receiving events for closed and otherwise long gone
|
||||
* file descriptors.
|
||||
*/
|
||||
|
||||
#include <sys/epoll.h>
|
||||
|
||||
#define EV_EMASK_EPERM 0x80
|
||||
|
||||
static void
|
||||
epoll_modify (EV_P_ int fd, int oev, int nev)
|
||||
{
|
||||
struct epoll_event ev;
|
||||
unsigned char oldmask;
|
||||
|
||||
/*
|
||||
* we handle EPOLL_CTL_DEL by ignoring it here
|
||||
* on the assumption that the fd is gone anyways
|
||||
* if that is wrong, we have to handle the spurious
|
||||
* event in epoll_poll.
|
||||
* if the fd is added again, we try to ADD it, and, if that
|
||||
* fails, we assume it still has the same eventmask.
|
||||
*/
|
||||
if (!nev)
|
||||
return;
|
||||
|
||||
oldmask = anfds [fd].emask;
|
||||
anfds [fd].emask = nev;
|
||||
|
||||
/* store the generation counter in the upper 32 bits, the fd in the lower 32 bits */
|
||||
ev.data.u64 = (uint64_t)(uint32_t)fd
|
||||
| ((uint64_t)(uint32_t)++anfds [fd].egen << 32);
|
||||
ev.events = (nev & EV_READ ? EPOLLIN : 0)
|
||||
| (nev & EV_WRITE ? EPOLLOUT : 0);
|
||||
|
||||
if (expect_true (!epoll_ctl (backend_fd, oev && oldmask != nev ? EPOLL_CTL_MOD : EPOLL_CTL_ADD, fd, &ev)))
|
||||
return;
|
||||
|
||||
if (expect_true (errno == ENOENT))
|
||||
{
|
||||
/* if ENOENT then the fd went away, so try to do the right thing */
|
||||
if (!nev)
|
||||
goto dec_egen;
|
||||
|
||||
if (!epoll_ctl (backend_fd, EPOLL_CTL_ADD, fd, &ev))
|
||||
return;
|
||||
}
|
||||
else if (expect_true (errno == EEXIST))
|
||||
{
|
||||
/* EEXIST means we ignored a previous DEL, but the fd is still active */
|
||||
/* if the kernel mask is the same as the new mask, we assume it hasn't changed */
|
||||
if (oldmask == nev)
|
||||
goto dec_egen;
|
||||
|
||||
if (!epoll_ctl (backend_fd, EPOLL_CTL_MOD, fd, &ev))
|
||||
return;
|
||||
}
|
||||
else if (expect_true (errno == EPERM))
|
||||
{
|
||||
/* EPERM means the fd is always ready, but epoll is too snobbish */
|
||||
/* to handle it, unlike select or poll. */
|
||||
anfds [fd].emask = EV_EMASK_EPERM;
|
||||
|
||||
/* add fd to epoll_eperms, if not already inside */
|
||||
if (!(oldmask & EV_EMASK_EPERM))
|
||||
{
|
||||
array_needsize (int, epoll_eperms, epoll_epermmax, epoll_epermcnt + 1, EMPTY2);
|
||||
epoll_eperms [epoll_epermcnt++] = fd;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
fd_kill (EV_A_ fd);
|
||||
|
||||
dec_egen:
|
||||
/* we didn't successfully call epoll_ctl, so decrement the generation counter again */
|
||||
--anfds [fd].egen;
|
||||
}
|
||||
|
||||
static void
|
||||
epoll_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
int i;
|
||||
int eventcnt;
|
||||
|
||||
/* epoll wait times cannot be larger than (LONG_MAX - 999UL) / HZ msecs, which is below */
|
||||
/* the default libev max wait time, however. */
|
||||
EV_RELEASE_CB;
|
||||
eventcnt = epoll_wait (backend_fd, epoll_events, epoll_eventmax,
|
||||
epoll_epermcnt ? 0 : ev_timeout_to_ms (timeout));
|
||||
EV_ACQUIRE_CB;
|
||||
|
||||
if (expect_false (eventcnt < 0))
|
||||
{
|
||||
if (errno != EINTR)
|
||||
ev_syserr ("(libev) epoll_wait");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < eventcnt; ++i)
|
||||
{
|
||||
struct epoll_event *ev = epoll_events + i;
|
||||
|
||||
int fd = (uint32_t)ev->data.u64; /* mask out the lower 32 bits */
|
||||
int want = anfds [fd].events;
|
||||
int got = (ev->events & (EPOLLOUT | EPOLLERR | EPOLLHUP) ? EV_WRITE : 0)
|
||||
| (ev->events & (EPOLLIN | EPOLLERR | EPOLLHUP) ? EV_READ : 0);
|
||||
|
||||
/* check for spurious notification */
|
||||
/* we assume that fd is always in range, as we never shrink the anfds array */
|
||||
if (expect_false ((uint32_t)anfds [fd].egen != (uint32_t)(ev->data.u64 >> 32)))
|
||||
{
|
||||
/* recreate kernel state */
|
||||
postfork = 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (expect_false (got & ~want))
|
||||
{
|
||||
anfds [fd].emask = want;
|
||||
|
||||
/* we received an event but are not interested in it, try mod or del */
|
||||
/* I don't think we ever need MOD, but let's handle it anyways */
|
||||
ev->events = (want & EV_READ ? EPOLLIN : 0)
|
||||
| (want & EV_WRITE ? EPOLLOUT : 0);
|
||||
|
||||
/* pre-2.6.9 kernels require a non-null pointer with EPOLL_CTL_DEL, */
|
||||
/* which is fortunately easy to do for us. */
|
||||
if (epoll_ctl (backend_fd, want ? EPOLL_CTL_MOD : EPOLL_CTL_DEL, fd, ev))
|
||||
{
|
||||
postfork = 1; /* an error occurred, recreate kernel state */
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
fd_event (EV_A_ fd, got);
|
||||
}
|
||||
|
||||
/* if the receive array was full, increase its size */
|
||||
if (expect_false (eventcnt == epoll_eventmax))
|
||||
{
|
||||
ev_free (epoll_events);
|
||||
epoll_eventmax = array_nextsize (sizeof (struct epoll_event), epoll_eventmax, epoll_eventmax + 1);
|
||||
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
||||
}
|
||||
|
||||
/* now synthesize events for all fds where epoll fails, while select works... */
|
||||
for (i = epoll_epermcnt; i--; )
|
||||
{
|
||||
int fd = epoll_eperms [i];
|
||||
unsigned char events = anfds [fd].events & (EV_READ | EV_WRITE);
|
||||
|
||||
if (anfds [fd].emask & EV_EMASK_EPERM && events)
|
||||
fd_event (EV_A_ fd, events);
|
||||
else
|
||||
epoll_eperms [i] = epoll_eperms [--epoll_epermcnt];
|
||||
}
|
||||
}
|
||||
|
||||
int inline_size
|
||||
epoll_init (EV_P_ int flags)
|
||||
{
|
||||
#ifdef EPOLL_CLOEXEC
|
||||
backend_fd = epoll_create1 (EPOLL_CLOEXEC);
|
||||
|
||||
if (backend_fd <= 0)
|
||||
#endif
|
||||
backend_fd = epoll_create (256);
|
||||
|
||||
if (backend_fd < 0)
|
||||
return 0;
|
||||
|
||||
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
backend_fudge = 0.; /* kernel sources seem to indicate this to be zero */
|
||||
backend_modify = epoll_modify;
|
||||
backend_poll = epoll_poll;
|
||||
|
||||
epoll_eventmax = 64; /* initial number of events receivable per poll */
|
||||
epoll_events = (struct epoll_event *)ev_malloc (sizeof (struct epoll_event) * epoll_eventmax);
|
||||
|
||||
return EVBACKEND_EPOLL;
|
||||
}
|
||||
|
||||
void inline_size
|
||||
epoll_destroy (EV_P)
|
||||
{
|
||||
ev_free (epoll_events);
|
||||
array_free (epoll_eperm, EMPTY);
|
||||
}
|
||||
|
||||
void inline_size
|
||||
epoll_fork (EV_P)
|
||||
{
|
||||
close (backend_fd);
|
||||
|
||||
while ((backend_fd = epoll_create (256)) < 0)
|
||||
ev_syserr ("(libev) epoll_create");
|
||||
|
||||
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
fd_rearm_all (EV_A);
|
||||
}
|
||||
|
||||
198
src/rt/libuv/ev/ev_kqueue.c
Normal file
198
src/rt/libuv/ev/ev_kqueue.c
Normal file
|
|
@ -0,0 +1,198 @@
|
|||
/*
|
||||
* libev kqueue backend
|
||||
*
|
||||
* Copyright (c) 2007,2008,2009,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.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/event.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
void inline_speed
|
||||
kqueue_change (EV_P_ int fd, int filter, int flags, int fflags)
|
||||
{
|
||||
++kqueue_changecnt;
|
||||
array_needsize (struct kevent, kqueue_changes, kqueue_changemax, kqueue_changecnt, EMPTY2);
|
||||
|
||||
EV_SET (&kqueue_changes [kqueue_changecnt - 1], fd, filter, flags, fflags, 0, 0);
|
||||
}
|
||||
|
||||
/* OS X at least needs this */
|
||||
#ifndef EV_ENABLE
|
||||
# define EV_ENABLE 0
|
||||
#endif
|
||||
#ifndef NOTE_EOF
|
||||
# define NOTE_EOF 0
|
||||
#endif
|
||||
|
||||
static void
|
||||
kqueue_modify (EV_P_ int fd, int oev, int nev)
|
||||
{
|
||||
if (oev != nev)
|
||||
{
|
||||
if (oev & EV_READ)
|
||||
kqueue_change (EV_A_ fd, EVFILT_READ , EV_DELETE, 0);
|
||||
|
||||
if (oev & EV_WRITE)
|
||||
kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_DELETE, 0);
|
||||
}
|
||||
|
||||
/* to detect close/reopen reliably, we have to re-add */
|
||||
/* event requests even when oev == nev */
|
||||
|
||||
if (nev & EV_READ)
|
||||
kqueue_change (EV_A_ fd, EVFILT_READ , EV_ADD | EV_ENABLE, NOTE_EOF);
|
||||
|
||||
if (nev & EV_WRITE)
|
||||
kqueue_change (EV_A_ fd, EVFILT_WRITE, EV_ADD | EV_ENABLE, NOTE_EOF);
|
||||
}
|
||||
|
||||
static void
|
||||
kqueue_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
int res, i;
|
||||
struct timespec ts;
|
||||
|
||||
/* need to resize so there is enough space for errors */
|
||||
if (kqueue_changecnt > kqueue_eventmax)
|
||||
{
|
||||
ev_free (kqueue_events);
|
||||
kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_changecnt);
|
||||
kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
|
||||
}
|
||||
|
||||
EV_RELEASE_CB;
|
||||
EV_TS_SET (ts, timeout);
|
||||
res = kevent (backend_fd, kqueue_changes, kqueue_changecnt, kqueue_events, kqueue_eventmax, &ts);
|
||||
EV_ACQUIRE_CB;
|
||||
kqueue_changecnt = 0;
|
||||
|
||||
if (expect_false (res < 0))
|
||||
{
|
||||
if (errno != EINTR)
|
||||
ev_syserr ("(libev) kevent");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
for (i = 0; i < res; ++i)
|
||||
{
|
||||
int fd = kqueue_events [i].ident;
|
||||
|
||||
if (expect_false (kqueue_events [i].flags & EV_ERROR))
|
||||
{
|
||||
int err = kqueue_events [i].data;
|
||||
|
||||
/* we are only interested in errors for fds that we are interested in :) */
|
||||
if (anfds [fd].events)
|
||||
{
|
||||
if (err == ENOENT) /* resubmit changes on ENOENT */
|
||||
kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
|
||||
else if (err == EBADF) /* on EBADF, we re-check the fd */
|
||||
{
|
||||
if (fd_valid (fd))
|
||||
kqueue_modify (EV_A_ fd, 0, anfds [fd].events);
|
||||
else
|
||||
fd_kill (EV_A_ fd);
|
||||
}
|
||||
else /* on all other errors, we error out on the fd */
|
||||
fd_kill (EV_A_ fd);
|
||||
}
|
||||
}
|
||||
else
|
||||
fd_event (
|
||||
EV_A_
|
||||
fd,
|
||||
kqueue_events [i].filter == EVFILT_READ ? EV_READ
|
||||
: kqueue_events [i].filter == EVFILT_WRITE ? EV_WRITE
|
||||
: 0
|
||||
);
|
||||
}
|
||||
|
||||
if (expect_false (res == kqueue_eventmax))
|
||||
{
|
||||
ev_free (kqueue_events);
|
||||
kqueue_eventmax = array_nextsize (sizeof (struct kevent), kqueue_eventmax, kqueue_eventmax + 1);
|
||||
kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
|
||||
}
|
||||
}
|
||||
|
||||
int inline_size
|
||||
kqueue_init (EV_P_ int flags)
|
||||
{
|
||||
/* Initialize the kernel queue */
|
||||
if ((backend_fd = kqueue ()) < 0)
|
||||
return 0;
|
||||
|
||||
fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
|
||||
|
||||
backend_fudge = 0.;
|
||||
backend_modify = kqueue_modify;
|
||||
backend_poll = kqueue_poll;
|
||||
|
||||
kqueue_eventmax = 64; /* initial number of events receivable per poll */
|
||||
kqueue_events = (struct kevent *)ev_malloc (sizeof (struct kevent) * kqueue_eventmax);
|
||||
|
||||
kqueue_changes = 0;
|
||||
kqueue_changemax = 0;
|
||||
kqueue_changecnt = 0;
|
||||
|
||||
return EVBACKEND_KQUEUE;
|
||||
}
|
||||
|
||||
void inline_size
|
||||
kqueue_destroy (EV_P)
|
||||
{
|
||||
ev_free (kqueue_events);
|
||||
ev_free (kqueue_changes);
|
||||
}
|
||||
|
||||
void inline_size
|
||||
kqueue_fork (EV_P)
|
||||
{
|
||||
close (backend_fd);
|
||||
|
||||
while ((backend_fd = kqueue ()) < 0)
|
||||
ev_syserr ("(libev) kqueue");
|
||||
|
||||
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
/* re-register interest in fds */
|
||||
fd_rearm_all (EV_A);
|
||||
}
|
||||
|
||||
148
src/rt/libuv/ev/ev_poll.c
Normal file
148
src/rt/libuv/ev/ev_poll.c
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
* libev poll fd activity backend
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <poll.h>
|
||||
|
||||
void inline_size
|
||||
pollidx_init (int *base, int count)
|
||||
{
|
||||
/* consider using memset (.., -1, ...), which is practically guaranteed
|
||||
* to work on all systems implementing poll */
|
||||
while (count--)
|
||||
*base++ = -1;
|
||||
}
|
||||
|
||||
static void
|
||||
poll_modify (EV_P_ int fd, int oev, int nev)
|
||||
{
|
||||
int idx;
|
||||
|
||||
if (oev == nev)
|
||||
return;
|
||||
|
||||
array_needsize (int, pollidxs, pollidxmax, fd + 1, pollidx_init);
|
||||
|
||||
idx = pollidxs [fd];
|
||||
|
||||
if (idx < 0) /* need to allocate a new pollfd */
|
||||
{
|
||||
pollidxs [fd] = idx = pollcnt++;
|
||||
array_needsize (struct pollfd, polls, pollmax, pollcnt, EMPTY2);
|
||||
polls [idx].fd = fd;
|
||||
}
|
||||
|
||||
assert (polls [idx].fd == fd);
|
||||
|
||||
if (nev)
|
||||
polls [idx].events =
|
||||
(nev & EV_READ ? POLLIN : 0)
|
||||
| (nev & EV_WRITE ? POLLOUT : 0);
|
||||
else /* remove pollfd */
|
||||
{
|
||||
pollidxs [fd] = -1;
|
||||
|
||||
if (expect_true (idx < --pollcnt))
|
||||
{
|
||||
polls [idx] = polls [pollcnt];
|
||||
pollidxs [polls [idx].fd] = idx;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
poll_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
struct pollfd *p;
|
||||
int res;
|
||||
|
||||
EV_RELEASE_CB;
|
||||
res = poll (polls, pollcnt, ev_timeout_to_ms (timeout));
|
||||
EV_ACQUIRE_CB;
|
||||
|
||||
if (expect_false (res < 0))
|
||||
{
|
||||
if (errno == EBADF)
|
||||
fd_ebadf (EV_A);
|
||||
else if (errno == ENOMEM && !syserr_cb)
|
||||
fd_enomem (EV_A);
|
||||
else if (errno != EINTR)
|
||||
ev_syserr ("(libev) poll");
|
||||
}
|
||||
else
|
||||
for (p = polls; res; ++p)
|
||||
{
|
||||
assert (("libev: poll() returned illegal result, broken BSD kernel?", p < polls + pollcnt));
|
||||
|
||||
if (expect_false (p->revents)) /* this expect is debatable */
|
||||
{
|
||||
--res;
|
||||
|
||||
if (expect_false (p->revents & POLLNVAL))
|
||||
fd_kill (EV_A_ p->fd);
|
||||
else
|
||||
fd_event (
|
||||
EV_A_
|
||||
p->fd,
|
||||
(p->revents & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
|
||||
| (p->revents & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int inline_size
|
||||
poll_init (EV_P_ int flags)
|
||||
{
|
||||
backend_fudge = 0.; /* posix says this is zero */
|
||||
backend_modify = poll_modify;
|
||||
backend_poll = poll_poll;
|
||||
|
||||
pollidxs = 0; pollidxmax = 0;
|
||||
polls = 0; pollmax = 0; pollcnt = 0;
|
||||
|
||||
return EVBACKEND_POLL;
|
||||
}
|
||||
|
||||
void inline_size
|
||||
poll_destroy (EV_P)
|
||||
{
|
||||
ev_free (pollidxs);
|
||||
ev_free (polls);
|
||||
}
|
||||
|
||||
179
src/rt/libuv/ev/ev_port.c
Normal file
179
src/rt/libuv/ev/ev_port.c
Normal file
|
|
@ -0,0 +1,179 @@
|
|||
/*
|
||||
* libev solaris event port backend
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/* useful reading:
|
||||
*
|
||||
* http://bugs.opensolaris.org/view_bug.do?bug_id=6268715 (random results)
|
||||
* http://bugs.opensolaris.org/view_bug.do?bug_id=6455223 (just totally broken)
|
||||
* http://bugs.opensolaris.org/view_bug.do?bug_id=6873782 (manpage ETIME)
|
||||
* http://bugs.opensolaris.org/view_bug.do?bug_id=6874410 (implementation ETIME)
|
||||
* http://www.mail-archive.com/networking-discuss@opensolaris.org/msg11898.html ETIME vs. nget
|
||||
* http://src.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/lib/libc/port/gen/event_port.c (libc)
|
||||
* http://cvs.opensolaris.org/source/xref/onnv/onnv-gate/usr/src/uts/common/fs/portfs/port.c#1325 (kernel)
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <poll.h>
|
||||
#include <port.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
void inline_speed
|
||||
port_associate_and_check (EV_P_ int fd, int ev)
|
||||
{
|
||||
if (0 >
|
||||
port_associate (
|
||||
backend_fd, PORT_SOURCE_FD, fd,
|
||||
(ev & EV_READ ? POLLIN : 0)
|
||||
| (ev & EV_WRITE ? POLLOUT : 0),
|
||||
0
|
||||
)
|
||||
)
|
||||
{
|
||||
if (errno == EBADFD)
|
||||
fd_kill (EV_A_ fd);
|
||||
else
|
||||
ev_syserr ("(libev) port_associate");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
port_modify (EV_P_ int fd, int oev, int nev)
|
||||
{
|
||||
/* we need to reassociate no matter what, as closes are
|
||||
* once more silently being discarded.
|
||||
*/
|
||||
if (!nev)
|
||||
{
|
||||
if (oev)
|
||||
port_dissociate (backend_fd, PORT_SOURCE_FD, fd);
|
||||
}
|
||||
else
|
||||
port_associate_and_check (EV_A_ fd, nev);
|
||||
}
|
||||
|
||||
static void
|
||||
port_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
int res, i;
|
||||
struct timespec ts;
|
||||
uint_t nget = 1;
|
||||
|
||||
/* we initialise this to something we will skip in the loop, as */
|
||||
/* port_getn can return with nget unchanged, but no indication */
|
||||
/* whether it was the original value or has been updated :/ */
|
||||
port_events [0].portev_source = 0;
|
||||
|
||||
EV_RELEASE_CB;
|
||||
EV_TS_SET (ts, timeout);
|
||||
res = port_getn (backend_fd, port_events, port_eventmax, &nget, &ts);
|
||||
EV_ACQUIRE_CB;
|
||||
|
||||
/* port_getn may or may not set nget on error */
|
||||
/* so we rely on port_events [0].portev_source not being updated */
|
||||
if (res == -1 && errno != ETIME && errno != EINTR)
|
||||
ev_syserr ("(libev) port_getn (see http://bugs.opensolaris.org/view_bug.do?bug_id=6268715, try LIBEV_FLAGS=3 env variable)");
|
||||
|
||||
for (i = 0; i < nget; ++i)
|
||||
{
|
||||
if (port_events [i].portev_source == PORT_SOURCE_FD)
|
||||
{
|
||||
int fd = port_events [i].portev_object;
|
||||
|
||||
fd_event (
|
||||
EV_A_
|
||||
fd,
|
||||
(port_events [i].portev_events & (POLLOUT | POLLERR | POLLHUP) ? EV_WRITE : 0)
|
||||
| (port_events [i].portev_events & (POLLIN | POLLERR | POLLHUP) ? EV_READ : 0)
|
||||
);
|
||||
|
||||
fd_change (EV_A_ fd, EV__IOFDSET);
|
||||
}
|
||||
}
|
||||
|
||||
if (expect_false (nget == port_eventmax))
|
||||
{
|
||||
ev_free (port_events);
|
||||
port_eventmax = array_nextsize (sizeof (port_event_t), port_eventmax, port_eventmax + 1);
|
||||
port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
|
||||
}
|
||||
}
|
||||
|
||||
int inline_size
|
||||
port_init (EV_P_ int flags)
|
||||
{
|
||||
/* Initialize the kernel queue */
|
||||
if ((backend_fd = port_create ()) < 0)
|
||||
return 0;
|
||||
|
||||
assert (("libev: PORT_SOURCE_FD must not be zero", PORT_SOURCE_FD));
|
||||
|
||||
fcntl (backend_fd, F_SETFD, FD_CLOEXEC); /* not sure if necessary, hopefully doesn't hurt */
|
||||
|
||||
backend_fudge = 1e-3; /* needed to compensate for port_getn returning early */
|
||||
backend_modify = port_modify;
|
||||
backend_poll = port_poll;
|
||||
|
||||
port_eventmax = 64; /* initial number of events receivable per poll */
|
||||
port_events = (port_event_t *)ev_malloc (sizeof (port_event_t) * port_eventmax);
|
||||
|
||||
return EVBACKEND_PORT;
|
||||
}
|
||||
|
||||
void inline_size
|
||||
port_destroy (EV_P)
|
||||
{
|
||||
ev_free (port_events);
|
||||
}
|
||||
|
||||
void inline_size
|
||||
port_fork (EV_P)
|
||||
{
|
||||
close (backend_fd);
|
||||
|
||||
while ((backend_fd = port_create ()) < 0)
|
||||
ev_syserr ("(libev) port");
|
||||
|
||||
fcntl (backend_fd, F_SETFD, FD_CLOEXEC);
|
||||
|
||||
/* re-register interest in fds */
|
||||
fd_rearm_all (EV_A);
|
||||
}
|
||||
|
||||
310
src/rt/libuv/ev/ev_select.c
Normal file
310
src/rt/libuv/ev/ev_select.c
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
/*
|
||||
* libev select fd activity backend
|
||||
*
|
||||
* Copyright (c) 2007,2008,2009,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 _WIN32
|
||||
/* for unix systems */
|
||||
# include <inttypes.h>
|
||||
# ifndef __hpux
|
||||
/* for REAL unix systems */
|
||||
# include <sys/select.h>
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef EV_SELECT_USE_FD_SET
|
||||
# ifdef NFDBITS
|
||||
# define EV_SELECT_USE_FD_SET 0
|
||||
# else
|
||||
# define EV_SELECT_USE_FD_SET 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#if EV_SELECT_IS_WINSOCKET
|
||||
# undef EV_SELECT_USE_FD_SET
|
||||
# define EV_SELECT_USE_FD_SET 1
|
||||
# undef NFDBITS
|
||||
# define NFDBITS 0
|
||||
#endif
|
||||
|
||||
#if !EV_SELECT_USE_FD_SET
|
||||
# define NFDBYTES (NFDBITS / 8)
|
||||
#endif
|
||||
|
||||
#include <string.h>
|
||||
|
||||
static void
|
||||
select_modify (EV_P_ int fd, int oev, int nev)
|
||||
{
|
||||
if (oev == nev)
|
||||
return;
|
||||
|
||||
{
|
||||
#if EV_SELECT_USE_FD_SET
|
||||
|
||||
#if EV_SELECT_IS_WINSOCKET
|
||||
SOCKET handle = anfds [fd].handle;
|
||||
#else
|
||||
int handle = fd;
|
||||
#endif
|
||||
|
||||
assert (("libev: fd >= FD_SETSIZE passed to fd_set-based select backend", fd < FD_SETSIZE));
|
||||
|
||||
/* FD_SET is broken on windows (it adds the fd to a set twice or more,
|
||||
* which eventually leads to overflows). Need to call it only on changes.
|
||||
*/
|
||||
#if EV_SELECT_IS_WINSOCKET
|
||||
if ((oev ^ nev) & EV_READ)
|
||||
#endif
|
||||
if (nev & EV_READ)
|
||||
FD_SET (handle, (fd_set *)vec_ri);
|
||||
else
|
||||
FD_CLR (handle, (fd_set *)vec_ri);
|
||||
|
||||
#if EV_SELECT_IS_WINSOCKET
|
||||
if ((oev ^ nev) & EV_WRITE)
|
||||
#endif
|
||||
if (nev & EV_WRITE)
|
||||
FD_SET (handle, (fd_set *)vec_wi);
|
||||
else
|
||||
FD_CLR (handle, (fd_set *)vec_wi);
|
||||
|
||||
#else
|
||||
|
||||
int word = fd / NFDBITS;
|
||||
fd_mask mask = 1UL << (fd % NFDBITS);
|
||||
|
||||
if (expect_false (vec_max <= word))
|
||||
{
|
||||
int new_max = word + 1;
|
||||
|
||||
vec_ri = ev_realloc (vec_ri, new_max * NFDBYTES);
|
||||
vec_ro = ev_realloc (vec_ro, new_max * NFDBYTES); /* could free/malloc */
|
||||
vec_wi = ev_realloc (vec_wi, new_max * NFDBYTES);
|
||||
vec_wo = ev_realloc (vec_wo, new_max * NFDBYTES); /* could free/malloc */
|
||||
#ifdef _WIN32
|
||||
vec_eo = ev_realloc (vec_eo, new_max * NFDBYTES); /* could free/malloc */
|
||||
#endif
|
||||
|
||||
for (; vec_max < new_max; ++vec_max)
|
||||
((fd_mask *)vec_ri) [vec_max] =
|
||||
((fd_mask *)vec_wi) [vec_max] = 0;
|
||||
}
|
||||
|
||||
((fd_mask *)vec_ri) [word] |= mask;
|
||||
if (!(nev & EV_READ))
|
||||
((fd_mask *)vec_ri) [word] &= ~mask;
|
||||
|
||||
((fd_mask *)vec_wi) [word] |= mask;
|
||||
if (!(nev & EV_WRITE))
|
||||
((fd_mask *)vec_wi) [word] &= ~mask;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
select_poll (EV_P_ ev_tstamp timeout)
|
||||
{
|
||||
struct timeval tv;
|
||||
int res;
|
||||
int fd_setsize;
|
||||
|
||||
EV_RELEASE_CB;
|
||||
EV_TV_SET (tv, timeout);
|
||||
|
||||
#if EV_SELECT_USE_FD_SET
|
||||
fd_setsize = sizeof (fd_set);
|
||||
#else
|
||||
fd_setsize = vec_max * NFDBYTES;
|
||||
#endif
|
||||
|
||||
memcpy (vec_ro, vec_ri, fd_setsize);
|
||||
memcpy (vec_wo, vec_wi, fd_setsize);
|
||||
|
||||
#ifdef _WIN32
|
||||
/* pass in the write set as except set.
|
||||
* the idea behind this is to work around a windows bug that causes
|
||||
* errors to be reported as an exception and not by setting
|
||||
* the writable bit. this is so uncontrollably lame.
|
||||
*/
|
||||
memcpy (vec_eo, vec_wi, fd_setsize);
|
||||
res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, (fd_set *)vec_eo, &tv);
|
||||
#elif EV_SELECT_USE_FD_SET
|
||||
fd_setsize = anfdmax < FD_SETSIZE ? anfdmax : FD_SETSIZE;
|
||||
res = select (fd_setsize, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
|
||||
#else
|
||||
res = select (vec_max * NFDBITS, (fd_set *)vec_ro, (fd_set *)vec_wo, 0, &tv);
|
||||
#endif
|
||||
EV_ACQUIRE_CB;
|
||||
|
||||
if (expect_false (res < 0))
|
||||
{
|
||||
#if EV_SELECT_IS_WINSOCKET
|
||||
errno = WSAGetLastError ();
|
||||
#endif
|
||||
#ifdef WSABASEERR
|
||||
/* on windows, select returns incompatible error codes, fix this */
|
||||
if (errno >= WSABASEERR && errno < WSABASEERR + 1000)
|
||||
if (errno == WSAENOTSOCK)
|
||||
errno = EBADF;
|
||||
else
|
||||
errno -= WSABASEERR;
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
/* select on windows erroneously returns EINVAL when no fd sets have been
|
||||
* provided (this is documented). what microsoft doesn't tell you that this bug
|
||||
* exists even when the fd sets _are_ provided, so we have to check for this bug
|
||||
* here and emulate by sleeping manually.
|
||||
* we also get EINVAL when the timeout is invalid, but we ignore this case here
|
||||
* and assume that EINVAL always means: you have to wait manually.
|
||||
*/
|
||||
if (errno == EINVAL)
|
||||
{
|
||||
ev_sleep (timeout);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (errno == EBADF)
|
||||
fd_ebadf (EV_A);
|
||||
else if (errno == ENOMEM && !syserr_cb)
|
||||
fd_enomem (EV_A);
|
||||
else if (errno != EINTR)
|
||||
ev_syserr ("(libev) select");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#if EV_SELECT_USE_FD_SET
|
||||
|
||||
{
|
||||
int fd;
|
||||
|
||||
for (fd = 0; fd < anfdmax; ++fd)
|
||||
if (anfds [fd].events)
|
||||
{
|
||||
int events = 0;
|
||||
#if EV_SELECT_IS_WINSOCKET
|
||||
SOCKET handle = anfds [fd].handle;
|
||||
#else
|
||||
int handle = fd;
|
||||
#endif
|
||||
|
||||
if (FD_ISSET (handle, (fd_set *)vec_ro)) events |= EV_READ;
|
||||
if (FD_ISSET (handle, (fd_set *)vec_wo)) events |= EV_WRITE;
|
||||
#ifdef _WIN32
|
||||
if (FD_ISSET (handle, (fd_set *)vec_eo)) events |= EV_WRITE;
|
||||
#endif
|
||||
|
||||
if (expect_true (events))
|
||||
fd_event (EV_A_ fd, events);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
{
|
||||
int word, bit;
|
||||
for (word = vec_max; word--; )
|
||||
{
|
||||
fd_mask word_r = ((fd_mask *)vec_ro) [word];
|
||||
fd_mask word_w = ((fd_mask *)vec_wo) [word];
|
||||
#ifdef _WIN32
|
||||
word_w |= ((fd_mask *)vec_eo) [word];
|
||||
#endif
|
||||
|
||||
if (word_r || word_w)
|
||||
for (bit = NFDBITS; bit--; )
|
||||
{
|
||||
fd_mask mask = 1UL << bit;
|
||||
int events = 0;
|
||||
|
||||
events |= word_r & mask ? EV_READ : 0;
|
||||
events |= word_w & mask ? EV_WRITE : 0;
|
||||
|
||||
if (expect_true (events))
|
||||
fd_event (EV_A_ word * NFDBITS + bit, events);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
int inline_size
|
||||
select_init (EV_P_ int flags)
|
||||
{
|
||||
backend_fudge = 0.; /* posix says this is zero */
|
||||
backend_modify = select_modify;
|
||||
backend_poll = select_poll;
|
||||
|
||||
#if EV_SELECT_USE_FD_SET
|
||||
vec_ri = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_ri);
|
||||
vec_ro = ev_malloc (sizeof (fd_set));
|
||||
vec_wi = ev_malloc (sizeof (fd_set)); FD_ZERO ((fd_set *)vec_wi);
|
||||
vec_wo = ev_malloc (sizeof (fd_set));
|
||||
#ifdef _WIN32
|
||||
vec_eo = ev_malloc (sizeof (fd_set));
|
||||
#endif
|
||||
#else
|
||||
vec_max = 0;
|
||||
vec_ri = 0;
|
||||
vec_ro = 0;
|
||||
vec_wi = 0;
|
||||
vec_wo = 0;
|
||||
#ifdef _WIN32
|
||||
vec_eo = 0;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return EVBACKEND_SELECT;
|
||||
}
|
||||
|
||||
void inline_size
|
||||
select_destroy (EV_P)
|
||||
{
|
||||
ev_free (vec_ri);
|
||||
ev_free (vec_ro);
|
||||
ev_free (vec_wi);
|
||||
ev_free (vec_wo);
|
||||
#ifdef _WIN32
|
||||
ev_free (vec_eo);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
203
src/rt/libuv/ev/ev_vars.h
Normal file
203
src/rt/libuv/ev/ev_vars.h
Normal file
|
|
@ -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
|
||||
|
||||
153
src/rt/libuv/ev/ev_win32.c
Normal file
153
src/rt/libuv/ev/ev_win32.c
Normal file
|
|
@ -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
|
||||
|
||||
196
src/rt/libuv/ev/ev_wrap.h
Normal file
196
src/rt/libuv/ev/ev_wrap.h
Normal file
|
|
@ -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
|
||||
402
src/rt/libuv/ev/event.c
Normal file
402
src/rt/libuv/ev/event.c
Normal file
|
|
@ -0,0 +1,402 @@
|
|||
/*
|
||||
* libevent compatibility layer
|
||||
*
|
||||
* Copyright (c) 2007,2008,2009,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.
|
||||
*/
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#ifdef EV_EVENT_H
|
||||
# include EV_EVENT_H
|
||||
#else
|
||||
# include "event.h"
|
||||
#endif
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
# define dLOOPev struct ev_loop *loop = (struct ev_loop *)ev->ev_base
|
||||
# define dLOOPbase struct ev_loop *loop = (struct ev_loop *)base
|
||||
#else
|
||||
# define dLOOPev
|
||||
# define dLOOPbase
|
||||
#endif
|
||||
|
||||
/* never accessed, will always be cast from/to ev_loop */
|
||||
struct event_base
|
||||
{
|
||||
int dummy;
|
||||
};
|
||||
|
||||
static struct event_base *ev_x_cur;
|
||||
|
||||
static ev_tstamp
|
||||
ev_tv_get (struct timeval *tv)
|
||||
{
|
||||
if (tv)
|
||||
{
|
||||
ev_tstamp after = tv->tv_sec + tv->tv_usec * 1e-6;
|
||||
return after ? after : 1e-6;
|
||||
}
|
||||
else
|
||||
return -1.;
|
||||
}
|
||||
|
||||
#define EVENT_STRINGIFY(s) # s
|
||||
#define EVENT_VERSION(a,b) EVENT_STRINGIFY (a) "." EVENT_STRINGIFY (b)
|
||||
|
||||
const char *event_get_version (void)
|
||||
{
|
||||
/* returns ABI, not API or library, version */
|
||||
return EVENT_VERSION (EV_VERSION_MAJOR, EV_VERSION_MINOR);
|
||||
}
|
||||
|
||||
const char *event_get_method (void)
|
||||
{
|
||||
return "libev";
|
||||
}
|
||||
|
||||
void *event_init (void)
|
||||
{
|
||||
#if EV_MULTIPLICITY
|
||||
if (ev_x_cur)
|
||||
ev_x_cur = (struct event_base *)ev_loop_new (EVFLAG_AUTO);
|
||||
else
|
||||
ev_x_cur = (struct event_base *)ev_default_loop (EVFLAG_AUTO);
|
||||
#else
|
||||
assert (("libev: multiple event bases not supported when not compiled with EV_MULTIPLICITY", !ev_x_cur));
|
||||
|
||||
ev_x_cur = (struct event_base *)(long)ev_default_loop (EVFLAG_AUTO);
|
||||
#endif
|
||||
|
||||
return ev_x_cur;
|
||||
}
|
||||
|
||||
void event_base_free (struct event_base *base)
|
||||
{
|
||||
dLOOPbase;
|
||||
|
||||
#if EV_MULTIPLICITY
|
||||
if (!ev_is_default_loop (loop))
|
||||
ev_loop_destroy (loop);
|
||||
#endif
|
||||
}
|
||||
|
||||
int event_dispatch (void)
|
||||
{
|
||||
return event_base_dispatch (ev_x_cur);
|
||||
}
|
||||
|
||||
#ifdef EV_STANDALONE
|
||||
void event_set_log_callback (event_log_cb cb)
|
||||
{
|
||||
/* nop */
|
||||
}
|
||||
#endif
|
||||
|
||||
int event_loop (int flags)
|
||||
{
|
||||
return event_base_loop (ev_x_cur, flags);
|
||||
}
|
||||
|
||||
int event_loopexit (struct timeval *tv)
|
||||
{
|
||||
return event_base_loopexit (ev_x_cur, tv);
|
||||
}
|
||||
|
||||
static void
|
||||
ev_x_cb (struct event *ev, int revents)
|
||||
{
|
||||
revents &= EV_READ | EV_WRITE | EV_TIMER | EV_SIGNAL;
|
||||
|
||||
ev->ev_res = revents;
|
||||
ev->ev_callback (ev->ev_fd, (short)revents, ev->ev_arg);
|
||||
}
|
||||
|
||||
static void
|
||||
ev_x_cb_sig (EV_P_ struct ev_signal *w, int revents)
|
||||
{
|
||||
struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.sig));
|
||||
|
||||
if (revents & EV_ERROR)
|
||||
event_del (ev);
|
||||
|
||||
ev_x_cb (ev, revents);
|
||||
}
|
||||
|
||||
static void
|
||||
ev_x_cb_io (EV_P_ struct ev_io *w, int revents)
|
||||
{
|
||||
struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, iosig.io));
|
||||
|
||||
if ((revents & EV_ERROR) || !(ev->ev_events & EV_PERSIST))
|
||||
event_del (ev);
|
||||
|
||||
ev_x_cb (ev, revents);
|
||||
}
|
||||
|
||||
static void
|
||||
ev_x_cb_to (EV_P_ struct ev_timer *w, int revents)
|
||||
{
|
||||
struct event *ev = (struct event *)(((char *)w) - offsetof (struct event, to));
|
||||
|
||||
event_del (ev);
|
||||
|
||||
ev_x_cb (ev, revents);
|
||||
}
|
||||
|
||||
void event_set (struct event *ev, int fd, short events, void (*cb)(int, short, void *), void *arg)
|
||||
{
|
||||
if (events & EV_SIGNAL)
|
||||
ev_init (&ev->iosig.sig, ev_x_cb_sig);
|
||||
else
|
||||
ev_init (&ev->iosig.io, ev_x_cb_io);
|
||||
|
||||
ev_init (&ev->to, ev_x_cb_to);
|
||||
|
||||
ev->ev_base = ev_x_cur; /* not threadsafe, but it's how libevent works */
|
||||
ev->ev_fd = fd;
|
||||
ev->ev_events = events;
|
||||
ev->ev_pri = 0;
|
||||
ev->ev_callback = cb;
|
||||
ev->ev_arg = arg;
|
||||
ev->ev_res = 0;
|
||||
ev->ev_flags = EVLIST_INIT;
|
||||
}
|
||||
|
||||
int event_once (int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
|
||||
{
|
||||
return event_base_once (ev_x_cur, fd, events, cb, arg, tv);
|
||||
}
|
||||
|
||||
int event_add (struct event *ev, struct timeval *tv)
|
||||
{
|
||||
dLOOPev;
|
||||
|
||||
if (ev->ev_events & EV_SIGNAL)
|
||||
{
|
||||
if (!ev_is_active (&ev->iosig.sig))
|
||||
{
|
||||
ev_signal_set (&ev->iosig.sig, ev->ev_fd);
|
||||
ev_signal_start (EV_A_ &ev->iosig.sig);
|
||||
|
||||
ev->ev_flags |= EVLIST_SIGNAL;
|
||||
}
|
||||
}
|
||||
else if (ev->ev_events & (EV_READ | EV_WRITE))
|
||||
{
|
||||
if (!ev_is_active (&ev->iosig.io))
|
||||
{
|
||||
ev_io_set (&ev->iosig.io, ev->ev_fd, ev->ev_events & (EV_READ | EV_WRITE));
|
||||
ev_io_start (EV_A_ &ev->iosig.io);
|
||||
|
||||
ev->ev_flags |= EVLIST_INSERTED;
|
||||
}
|
||||
}
|
||||
|
||||
if (tv)
|
||||
{
|
||||
ev->to.repeat = ev_tv_get (tv);
|
||||
ev_timer_again (EV_A_ &ev->to);
|
||||
ev->ev_flags |= EVLIST_TIMEOUT;
|
||||
}
|
||||
else
|
||||
{
|
||||
ev_timer_stop (EV_A_ &ev->to);
|
||||
ev->ev_flags &= ~EVLIST_TIMEOUT;
|
||||
}
|
||||
|
||||
ev->ev_flags |= EVLIST_ACTIVE;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_del (struct event *ev)
|
||||
{
|
||||
dLOOPev;
|
||||
|
||||
if (ev->ev_events & EV_SIGNAL)
|
||||
ev_signal_stop (EV_A_ &ev->iosig.sig);
|
||||
else if (ev->ev_events & (EV_READ | EV_WRITE))
|
||||
ev_io_stop (EV_A_ &ev->iosig.io);
|
||||
|
||||
if (ev_is_active (&ev->to))
|
||||
ev_timer_stop (EV_A_ &ev->to);
|
||||
|
||||
ev->ev_flags = EVLIST_INIT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void event_active (struct event *ev, int res, short ncalls)
|
||||
{
|
||||
dLOOPev;
|
||||
|
||||
if (res & EV_TIMEOUT)
|
||||
ev_feed_event (EV_A_ &ev->to, res & EV_TIMEOUT);
|
||||
|
||||
if (res & EV_SIGNAL)
|
||||
ev_feed_event (EV_A_ &ev->iosig.sig, res & EV_SIGNAL);
|
||||
|
||||
if (res & (EV_READ | EV_WRITE))
|
||||
ev_feed_event (EV_A_ &ev->iosig.io, res & (EV_READ | EV_WRITE));
|
||||
}
|
||||
|
||||
int event_pending (struct event *ev, short events, struct timeval *tv)
|
||||
{
|
||||
short revents = 0;
|
||||
dLOOPev;
|
||||
|
||||
if (ev->ev_events & EV_SIGNAL)
|
||||
{
|
||||
/* sig */
|
||||
if (ev_is_active (&ev->iosig.sig) || ev_is_pending (&ev->iosig.sig))
|
||||
revents |= EV_SIGNAL;
|
||||
}
|
||||
else if (ev->ev_events & (EV_READ | EV_WRITE))
|
||||
{
|
||||
/* io */
|
||||
if (ev_is_active (&ev->iosig.io) || ev_is_pending (&ev->iosig.io))
|
||||
revents |= ev->ev_events & (EV_READ | EV_WRITE);
|
||||
}
|
||||
|
||||
if (ev->ev_events & EV_TIMEOUT || ev_is_active (&ev->to) || ev_is_pending (&ev->to))
|
||||
{
|
||||
revents |= EV_TIMEOUT;
|
||||
|
||||
if (tv)
|
||||
{
|
||||
ev_tstamp at = ev_now (EV_A);
|
||||
|
||||
tv->tv_sec = (long)at;
|
||||
tv->tv_usec = (long)((at - (ev_tstamp)tv->tv_sec) * 1e6);
|
||||
}
|
||||
}
|
||||
|
||||
return events & revents;
|
||||
}
|
||||
|
||||
int event_priority_init (int npri)
|
||||
{
|
||||
return event_base_priority_init (ev_x_cur, npri);
|
||||
}
|
||||
|
||||
int event_priority_set (struct event *ev, int pri)
|
||||
{
|
||||
ev->ev_pri = pri;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_base_set (struct event_base *base, struct event *ev)
|
||||
{
|
||||
ev->ev_base = base;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_base_loop (struct event_base *base, int flags)
|
||||
{
|
||||
dLOOPbase;
|
||||
|
||||
ev_run (EV_A_ flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_base_dispatch (struct event_base *base)
|
||||
{
|
||||
return event_base_loop (base, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
ev_x_loopexit_cb (int revents, void *base)
|
||||
{
|
||||
dLOOPbase;
|
||||
|
||||
ev_break (EV_A_ EVBREAK_ONE);
|
||||
}
|
||||
|
||||
int event_base_loopexit (struct event_base *base, struct timeval *tv)
|
||||
{
|
||||
ev_tstamp after = ev_tv_get (tv);
|
||||
dLOOPbase;
|
||||
|
||||
ev_once (EV_A_ -1, 0, after >= 0. ? after : 0., ev_x_loopexit_cb, (void *)base);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ev_x_once
|
||||
{
|
||||
int fd;
|
||||
void (*cb)(int, short, void *);
|
||||
void *arg;
|
||||
};
|
||||
|
||||
static void
|
||||
ev_x_once_cb (int revents, void *arg)
|
||||
{
|
||||
struct ev_x_once *once = (struct ev_x_once *)arg;
|
||||
|
||||
once->cb (once->fd, (short)revents, once->arg);
|
||||
free (once);
|
||||
}
|
||||
|
||||
int event_base_once (struct event_base *base, int fd, short events, void (*cb)(int, short, void *), void *arg, struct timeval *tv)
|
||||
{
|
||||
struct ev_x_once *once = (struct ev_x_once *)malloc (sizeof (struct ev_x_once));
|
||||
dLOOPbase;
|
||||
|
||||
if (!once)
|
||||
return -1;
|
||||
|
||||
once->fd = fd;
|
||||
once->cb = cb;
|
||||
once->arg = arg;
|
||||
|
||||
ev_once (EV_A_ fd, events & (EV_READ | EV_WRITE), ev_tv_get (tv), ev_x_once_cb, (void *)once);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int event_base_priority_init (struct event_base *base, int npri)
|
||||
{
|
||||
/*dLOOPbase;*/
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
170
src/rt/libuv/ev/event.h
Normal file
170
src/rt/libuv/ev/event.h
Normal file
|
|
@ -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
|
||||
|
||||
294
src/rt/libuv/ev/install-sh
Executable file
294
src/rt/libuv/ev/install-sh
Executable file
|
|
@ -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
|
||||
}
|
||||
39
src/rt/libuv/ev/libev.m4
Normal file
39
src/rt/libuv/ev/libev.m4
Normal file
|
|
@ -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)
|
||||
|
||||
8413
src/rt/libuv/ev/ltmain.sh
Executable file
8413
src/rt/libuv/ev/ltmain.sh
Executable file
File diff suppressed because it is too large
Load diff
336
src/rt/libuv/ev/missing
Executable file
336
src/rt/libuv/ev/missing
Executable file
|
|
@ -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
|
||||
111
src/rt/libuv/ev/mkinstalldirs
Executable file
111
src/rt/libuv/ev/mkinstalldirs
Executable file
|
|
@ -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
|
||||
172
src/rt/libuv/msvs/libuv-benchmark.vcxproj
Normal file
172
src/rt/libuv/msvs/libuv-benchmark.vcxproj
Normal file
|
|
@ -0,0 +1,172 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\test\benchmark-ping-pongs.c" />
|
||||
<ClCompile Include="..\test\benchmark-pump.c" />
|
||||
<ClCompile Include="..\test\benchmark-sizes.c" />
|
||||
<ClCompile Include="..\test\echo-server.c" />
|
||||
<ClCompile Include="..\test\run-benchmarks.c" />
|
||||
<ClCompile Include="..\test\runner-unix.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test\runner-win.c" />
|
||||
<ClCompile Include="..\test\runner.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\test\benchmark-list.h" />
|
||||
<ClInclude Include="..\test\runner-unix.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\test\runner-win.h" />
|
||||
<ClInclude Include="..\test\runner.h" />
|
||||
<ClInclude Include="..\test\task.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="libuv.vcxproj">
|
||||
<Project>{301fe650-cd34-14e5-6b63-42e383fa02bc}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
184
src/rt/libuv/msvs/libuv-test.vcxproj
Normal file
184
src/rt/libuv/msvs/libuv-test.vcxproj
Normal file
|
|
@ -0,0 +1,184 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<TargetMachine>MachineX86</TargetMachine>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;ws2_32.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\test\echo-server.c" />
|
||||
<ClCompile Include="..\test\runner-unix.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\test\test-async.c" />
|
||||
<ClCompile Include="..\test\test-delayed-accept.c" />
|
||||
<ClCompile Include="..\test\test-callback-stack.c" />
|
||||
<ClCompile Include="..\test\test-connection-fail.c" />
|
||||
<ClCompile Include="..\test\test-get-currentexe.c" />
|
||||
<ClCompile Include="..\test\test-fail-always.c" />
|
||||
<ClCompile Include="..\test\test-loop-handles.c" />
|
||||
<ClCompile Include="..\test\test-pass-always.c" />
|
||||
<ClCompile Include="..\test\test-ping-pong.c" />
|
||||
<ClCompile Include="..\test\runner-win.c" />
|
||||
<ClCompile Include="..\test\runner.c" />
|
||||
<ClCompile Include="..\test\test-bind-error.c" />
|
||||
<ClCompile Include="..\test\test-shutdown-eof.c" />
|
||||
<ClCompile Include="..\test\test-tcp-writealot.c" />
|
||||
<ClCompile Include="..\test\test-timer-again.c" />
|
||||
<ClCompile Include="..\test\test-timer.c" />
|
||||
<ClCompile Include="..\test\run-tests.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\test\runner-unix.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\test\test-list.h" />
|
||||
<ClInclude Include="..\test\runner-win.h" />
|
||||
<ClInclude Include="..\test\runner.h" />
|
||||
<ClInclude Include="..\test\task.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="libuv.vcxproj">
|
||||
<Project>{301fe650-cd34-14e5-6b63-42e383fa02bc}</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
46
src/rt/libuv/msvs/libuv.sln
Normal file
46
src/rt/libuv/msvs/libuv.sln
Normal file
|
|
@ -0,0 +1,46 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 11.00
|
||||
# Visual Studio 2010
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libuv", "libuv.vcxproj", "{301FE650-CD34-14E5-6B63-42E383FA02BC}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libuv-test", "libuv-test.vcxproj", "{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libuv-benchmark", "libuv-benchmark.vcxproj", "{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Win32 = Debug|Win32
|
||||
Debug|x64 = Debug|x64
|
||||
Release|Win32 = Release|Win32
|
||||
Release|x64 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Debug|x64.Build.0 = Debug|x64
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|Win32.Build.0 = Release|Win32
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|x64.ActiveCfg = Release|x64
|
||||
{301FE650-CD34-14E5-6B63-42E383FA02BC}.Release|x64.Build.0 = Release|x64
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Debug|x64.Build.0 = Debug|x64
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|Win32.Build.0 = Release|Win32
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|x64.ActiveCfg = Release|x64
|
||||
{1D7C3F6C-A4AF-DD73-2D20-B2FC919B3744}.Release|x64.Build.0 = Release|x64
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|Win32.ActiveCfg = Debug|Win32
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|Win32.Build.0 = Debug|Win32
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Debug|x64.Build.0 = Debug|x64
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|Win32.ActiveCfg = Release|Win32
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|Win32.Build.0 = Release|Win32
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|x64.ActiveCfg = Release|x64
|
||||
{6CCBDAFD-7A11-133D-357B-E2D2F4C621E4}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
136
src/rt/libuv/msvs/libuv.vcxproj
Normal file
136
src/rt/libuv/msvs/libuv.vcxproj
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<ProjectGuid>{301FE650-CD34-14E5-6B63-42E383FA02BC}</ProjectGuid>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<OutDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</OutDir>
|
||||
<IntDir>$(SolutionDir)..\build\$(Platform)\$(Configuration)\</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<RuntimeLibrary>MultiThreaded</RuntimeLibrary>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\ngx-queue.h" />
|
||||
<ClInclude Include="..\uv-unix.h">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\uv-win.h" />
|
||||
<ClInclude Include="..\uv.h" />
|
||||
<ClInclude Include="..\tree.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\uv-unix.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">true</ExcludedFromBuild>
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Release|x64'">true</ExcludedFromBuild>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\uv-win.c" />
|
||||
<ClCompile Include="..\uv-common.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\AUTHORS" />
|
||||
<None Include="..\config-mingw.mk" />
|
||||
<None Include="..\config-unix.mk" />
|
||||
<None Include="..\iocp-links.html" />
|
||||
<None Include="..\LICENSE" />
|
||||
<None Include="..\Makefile" />
|
||||
<None Include="..\README" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
102
src/rt/libuv/ngx-queue.h
Normal file
102
src/rt/libuv/ngx-queue.h
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
|
||||
/*
|
||||
* Copyright (C) Igor Sysoev
|
||||
*/
|
||||
|
||||
|
||||
#ifndef _NGX_QUEUE_H_INCLUDED_
|
||||
#define _NGX_QUEUE_H_INCLUDED_
|
||||
|
||||
|
||||
typedef struct ngx_queue_s ngx_queue_t;
|
||||
|
||||
struct ngx_queue_s {
|
||||
ngx_queue_t *prev;
|
||||
ngx_queue_t *next;
|
||||
};
|
||||
|
||||
|
||||
#define ngx_queue_init(q) \
|
||||
(q)->prev = q; \
|
||||
(q)->next = q
|
||||
|
||||
|
||||
#define ngx_queue_empty(h) \
|
||||
(h == (h)->prev)
|
||||
|
||||
|
||||
#define ngx_queue_insert_head(h, x) \
|
||||
(x)->next = (h)->next; \
|
||||
(x)->next->prev = x; \
|
||||
(x)->prev = h; \
|
||||
(h)->next = x
|
||||
|
||||
|
||||
#define ngx_queue_insert_after ngx_queue_insert_head
|
||||
|
||||
|
||||
#define ngx_queue_insert_tail(h, x) \
|
||||
(x)->prev = (h)->prev; \
|
||||
(x)->prev->next = x; \
|
||||
(x)->next = h; \
|
||||
(h)->prev = x
|
||||
|
||||
|
||||
#define ngx_queue_head(h) \
|
||||
(h)->next
|
||||
|
||||
|
||||
#define ngx_queue_last(h) \
|
||||
(h)->prev
|
||||
|
||||
|
||||
#define ngx_queue_sentinel(h) \
|
||||
(h)
|
||||
|
||||
|
||||
#define ngx_queue_next(q) \
|
||||
(q)->next
|
||||
|
||||
|
||||
#define ngx_queue_prev(q) \
|
||||
(q)->prev
|
||||
|
||||
|
||||
#if (NGX_DEBUG)
|
||||
|
||||
#define ngx_queue_remove(x) \
|
||||
(x)->next->prev = (x)->prev; \
|
||||
(x)->prev->next = (x)->next; \
|
||||
(x)->prev = NULL; \
|
||||
(x)->next = NULL
|
||||
|
||||
#else
|
||||
|
||||
#define ngx_queue_remove(x) \
|
||||
(x)->next->prev = (x)->prev; \
|
||||
(x)->prev->next = (x)->next
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#define ngx_queue_split(h, q, n) \
|
||||
(n)->prev = (h)->prev; \
|
||||
(n)->prev->next = n; \
|
||||
(n)->next = q; \
|
||||
(h)->prev = (q)->prev; \
|
||||
(h)->prev->next = h; \
|
||||
(q)->prev = n;
|
||||
|
||||
|
||||
#define ngx_queue_add(h, n) \
|
||||
(h)->prev->next = (n)->next; \
|
||||
(n)->next->prev = (h)->prev; \
|
||||
(h)->prev = (n)->prev; \
|
||||
(h)->prev->next = h;
|
||||
|
||||
|
||||
#define ngx_queue_data(q, type, link) \
|
||||
(type *) ((unsigned char *) q - offsetof(type, link))
|
||||
|
||||
|
||||
#endif /* _NGX_QUEUE_H_INCLUDED_ */
|
||||
40
src/rt/libuv/test/benchmark-list.h
Normal file
40
src/rt/libuv/test/benchmark-list.h
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
BENCHMARK_DECLARE (sizes)
|
||||
BENCHMARK_DECLARE (ping_pongs)
|
||||
BENCHMARK_DECLARE (pump100_client)
|
||||
BENCHMARK_DECLARE (pump1_client)
|
||||
HELPER_DECLARE (pump_server)
|
||||
HELPER_DECLARE (echo_server)
|
||||
|
||||
TASK_LIST_START
|
||||
BENCHMARK_ENTRY (sizes)
|
||||
|
||||
BENCHMARK_ENTRY (ping_pongs)
|
||||
BENCHMARK_HELPER (ping_pongs, echo_server)
|
||||
|
||||
BENCHMARK_ENTRY (pump100_client)
|
||||
BENCHMARK_HELPER (pump100_client, pump_server)
|
||||
|
||||
BENCHMARK_ENTRY (pump1_client)
|
||||
BENCHMARK_HELPER (pump1_client, pump_server)
|
||||
TASK_LIST_END
|
||||
217
src/rt/libuv/test/benchmark-ping-pongs.c
Normal file
217
src/rt/libuv/test/benchmark-ping-pongs.c
Normal file
|
|
@ -0,0 +1,217 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* strlen */
|
||||
|
||||
/* Run the benchmark for this many ms */
|
||||
#define TIME 5000
|
||||
|
||||
|
||||
typedef struct {
|
||||
int pongs;
|
||||
int state;
|
||||
uv_tcp_t tcp;
|
||||
uv_req_t connect_req;
|
||||
uv_req_t shutdown_req;
|
||||
} pinger_t;
|
||||
|
||||
typedef struct buf_s {
|
||||
uv_buf_t uv_buf_t;
|
||||
struct buf_s* next;
|
||||
} buf_t;
|
||||
|
||||
|
||||
static char PING[] = "PING\n";
|
||||
|
||||
static buf_t* buf_freelist = NULL;
|
||||
static int pinger_shutdown_cb_called;
|
||||
static int completed_pingers = 0;
|
||||
static int64_t start_time;
|
||||
|
||||
|
||||
static uv_buf_t buf_alloc(uv_tcp_t* tcp, size_t size) {
|
||||
buf_t* ab;
|
||||
|
||||
ab = buf_freelist;
|
||||
|
||||
if (ab != NULL) {
|
||||
buf_freelist = ab->next;
|
||||
return ab->uv_buf_t;
|
||||
}
|
||||
|
||||
ab = (buf_t*) malloc(size + sizeof *ab);
|
||||
ab->uv_buf_t.len = size;
|
||||
ab->uv_buf_t.base = ((char*) ab) + sizeof *ab;
|
||||
|
||||
return ab->uv_buf_t;
|
||||
}
|
||||
|
||||
|
||||
static void buf_free(uv_buf_t uv_buf_t) {
|
||||
buf_t* ab = (buf_t*) (uv_buf_t.base - sizeof *ab);
|
||||
|
||||
ab->next = buf_freelist;
|
||||
buf_freelist = ab;
|
||||
}
|
||||
|
||||
|
||||
static void pinger_close_cb(uv_handle_t* handle) {
|
||||
pinger_t* pinger;
|
||||
|
||||
pinger = (pinger_t*)handle->data;
|
||||
LOGF("ping_pongs: %d roundtrips/s\n", (1000 * pinger->pongs) / TIME);
|
||||
|
||||
free(pinger);
|
||||
|
||||
completed_pingers++;
|
||||
}
|
||||
|
||||
|
||||
static void pinger_write_cb(uv_req_t *req, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void pinger_write_ping(pinger_t* pinger) {
|
||||
uv_req_t *req;
|
||||
uv_buf_t buf;
|
||||
|
||||
buf.base = (char*)&PING;
|
||||
buf.len = strlen(PING);
|
||||
|
||||
req = (uv_req_t*)malloc(sizeof(*req));
|
||||
uv_req_init(req, (uv_handle_t*)(&pinger->tcp), pinger_write_cb);
|
||||
|
||||
if (uv_write(req, &buf, 1)) {
|
||||
FATAL("uv_write failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pinger_shutdown_cb(uv_handle_t* handle, int status) {
|
||||
ASSERT(status == 0);
|
||||
pinger_shutdown_cb_called++;
|
||||
|
||||
/*
|
||||
* The close callback has not been triggered yet. We must wait for EOF
|
||||
* until we close the connection.
|
||||
*/
|
||||
ASSERT(completed_pingers == 0);
|
||||
}
|
||||
|
||||
|
||||
static void pinger_read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
unsigned int i;
|
||||
pinger_t* pinger;
|
||||
|
||||
pinger = (pinger_t*)tcp->data;
|
||||
|
||||
if (nread < 0) {
|
||||
ASSERT(uv_last_error().code == UV_EOF);
|
||||
|
||||
if (buf.base) {
|
||||
buf_free(buf);
|
||||
}
|
||||
|
||||
ASSERT(pinger_shutdown_cb_called == 1);
|
||||
uv_close((uv_handle_t*)tcp, pinger_close_cb);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now we count the pings */
|
||||
for (i = 0; i < nread; i++) {
|
||||
ASSERT(buf.base[i] == PING[pinger->state]);
|
||||
pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
|
||||
if (pinger->state == 0) {
|
||||
pinger->pongs++;
|
||||
if (uv_now() - start_time > TIME) {
|
||||
uv_req_init(&pinger->shutdown_req, (uv_handle_t*)tcp, pinger_shutdown_cb);
|
||||
uv_shutdown(&pinger->shutdown_req);
|
||||
break;
|
||||
} else {
|
||||
pinger_write_ping(pinger);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
buf_free(buf);
|
||||
}
|
||||
|
||||
|
||||
static void pinger_connect_cb(uv_req_t *req, int status) {
|
||||
pinger_t *pinger = (pinger_t*)req->handle->data;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
pinger_write_ping(pinger);
|
||||
|
||||
if (uv_read_start((uv_tcp_t*)(req->handle), buf_alloc, pinger_read_cb)) {
|
||||
FATAL("uv_read_start failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pinger_new() {
|
||||
int r;
|
||||
struct sockaddr_in client_addr = uv_ip4_addr("0.0.0.0", 0);
|
||||
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
pinger_t *pinger;
|
||||
|
||||
pinger = (pinger_t*)malloc(sizeof(*pinger));
|
||||
pinger->state = 0;
|
||||
pinger->pongs = 0;
|
||||
|
||||
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
|
||||
r = uv_tcp_init(&pinger->tcp);
|
||||
ASSERT(!r);
|
||||
|
||||
pinger->tcp.data = pinger;
|
||||
|
||||
/* We are never doing multiple reads/connects at a time anyway. */
|
||||
/* so these handles can be pre-initialized. */
|
||||
uv_req_init(&pinger->connect_req, (uv_handle_t*)&pinger->tcp,
|
||||
pinger_connect_cb);
|
||||
|
||||
uv_bind(&pinger->tcp, client_addr);
|
||||
r = uv_connect(&pinger->connect_req, server_addr);
|
||||
ASSERT(!r);
|
||||
}
|
||||
|
||||
|
||||
BENCHMARK_IMPL(ping_pongs) {
|
||||
uv_init();
|
||||
start_time = uv_now();
|
||||
|
||||
pinger_new();
|
||||
uv_run();
|
||||
|
||||
ASSERT(completed_pingers == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
389
src/rt/libuv/test/benchmark-pump.c
Normal file
389
src/rt/libuv/test/benchmark-pump.c
Normal file
|
|
@ -0,0 +1,389 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "task.h"
|
||||
#include "../uv.h"
|
||||
|
||||
#include <math.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static int TARGET_CONNECTIONS;
|
||||
#define WRITE_BUFFER_SIZE 8192
|
||||
#define MAX_SIMULTANEOUS_CONNECTS 100
|
||||
|
||||
#define PRINT_STATS 0
|
||||
#define STATS_INTERVAL 1000 /* msec */
|
||||
#define STATS_COUNT 5
|
||||
|
||||
|
||||
static void do_write(uv_tcp_t*);
|
||||
static void maybe_connect_some();
|
||||
|
||||
static uv_req_t* req_alloc();
|
||||
static void req_free(uv_req_t* uv_req);
|
||||
|
||||
static uv_buf_t buf_alloc(uv_tcp_t*, size_t size);
|
||||
static void buf_free(uv_buf_t uv_buf_t);
|
||||
|
||||
|
||||
static uv_tcp_t server;
|
||||
static struct sockaddr_in listen_addr;
|
||||
static struct sockaddr_in connect_addr;
|
||||
|
||||
static int64_t start_time;
|
||||
|
||||
static int max_connect_socket = 0;
|
||||
static int max_read_sockets = 0;
|
||||
static int read_sockets = 0;
|
||||
static int write_sockets = 0;
|
||||
|
||||
static int64_t nrecv = 0;
|
||||
static int64_t nrecv_total = 0;
|
||||
static int64_t nsent = 0;
|
||||
static int64_t nsent_total = 0;
|
||||
|
||||
static int stats_left = 0;
|
||||
|
||||
static char write_buffer[WRITE_BUFFER_SIZE];
|
||||
|
||||
/* Make this as large as you need. */
|
||||
#define MAX_WRITE_HANDLES 1000
|
||||
|
||||
static uv_tcp_t write_handles[MAX_WRITE_HANDLES];
|
||||
|
||||
static uv_timer_t timer_handle;
|
||||
|
||||
|
||||
static double gbit(int64_t bytes, int64_t passed_ms) {
|
||||
double gbits = ((double)bytes / (1024 * 1024 * 1024)) * 8;
|
||||
return gbits / ((double)passed_ms / 1000);
|
||||
}
|
||||
|
||||
|
||||
static void show_stats(uv_handle_t *handle, int status) {
|
||||
int64_t diff;
|
||||
|
||||
#if PRINT_STATS
|
||||
LOGF("connections: %d, write: %.1f gbit/s\n",
|
||||
write_sockets,
|
||||
gbit(nsent, STATS_INTERVAL));
|
||||
#endif
|
||||
|
||||
/* Exit if the show is over */
|
||||
if (!--stats_left) {
|
||||
|
||||
uv_update_time();
|
||||
diff = uv_now() - start_time;
|
||||
|
||||
LOGF("pump%d_client: %.1f gbit/s\n", write_sockets,
|
||||
gbit(nsent_total, diff));
|
||||
|
||||
exit(0);
|
||||
}
|
||||
|
||||
/* Reset read and write counters */
|
||||
nrecv = 0;
|
||||
nsent = 0;
|
||||
}
|
||||
|
||||
|
||||
static void read_show_stats() {
|
||||
int64_t diff;
|
||||
|
||||
uv_update_time();
|
||||
diff = uv_now() - start_time;
|
||||
|
||||
LOGF("pump%d_server: %.1f gbit/s\n", max_read_sockets,
|
||||
gbit(nrecv_total, diff));
|
||||
}
|
||||
|
||||
|
||||
|
||||
void write_sockets_close_cb(uv_handle_t* handle) {
|
||||
/* If any client closes, the process is done. */
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
void read_sockets_close_cb(uv_handle_t* handle) {
|
||||
free(handle);
|
||||
read_sockets--;
|
||||
|
||||
/* If it's past the first second and everyone has closed their connection
|
||||
* Then print stats.
|
||||
*/
|
||||
if (uv_now() - start_time > 1000 && read_sockets == 0) {
|
||||
read_show_stats();
|
||||
uv_close((uv_handle_t*)&server, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void start_stats_collection() {
|
||||
uv_req_t* req = req_alloc();
|
||||
int r;
|
||||
|
||||
/* Show-stats timer */
|
||||
stats_left = STATS_COUNT;
|
||||
r = uv_timer_init(&timer_handle);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(&timer_handle, show_stats, STATS_INTERVAL, STATS_INTERVAL);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_update_time();
|
||||
start_time = uv_now();
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t bytes, uv_buf_t buf) {
|
||||
if (nrecv_total == 0) {
|
||||
ASSERT(start_time == 0);
|
||||
uv_update_time();
|
||||
start_time = uv_now();
|
||||
}
|
||||
|
||||
if (bytes < 0) {
|
||||
uv_close((uv_handle_t*)tcp, read_sockets_close_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
buf_free(buf);
|
||||
|
||||
nrecv += bytes;
|
||||
nrecv_total += bytes;
|
||||
}
|
||||
|
||||
|
||||
static void write_cb(uv_req_t *req, int status) {
|
||||
uv_buf_t* buf = (uv_buf_t*) req->data;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
req_free(req);
|
||||
|
||||
nsent += sizeof write_buffer;
|
||||
nsent_total += sizeof write_buffer;
|
||||
|
||||
do_write((uv_tcp_t*)req->handle);
|
||||
}
|
||||
|
||||
|
||||
static void do_write(uv_tcp_t* tcp) {
|
||||
uv_req_t* req;
|
||||
uv_buf_t buf;
|
||||
int r;
|
||||
|
||||
buf.base = (char*) &write_buffer;
|
||||
buf.len = sizeof write_buffer;
|
||||
|
||||
while (tcp->write_queue_size == 0) {
|
||||
req = req_alloc();
|
||||
uv_req_init(req, (uv_handle_t*)tcp, write_cb);
|
||||
|
||||
r = uv_write(req, &buf, 1);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void connect_cb(uv_req_t* req, int status) {
|
||||
int i;
|
||||
|
||||
if (status) LOG(uv_strerror(uv_last_error()));
|
||||
ASSERT(status == 0);
|
||||
|
||||
write_sockets++;
|
||||
req_free(req);
|
||||
|
||||
maybe_connect_some();
|
||||
|
||||
if (write_sockets == TARGET_CONNECTIONS) {
|
||||
start_stats_collection();
|
||||
|
||||
/* Yay! start writing */
|
||||
for (i = 0; i < write_sockets; i++) {
|
||||
do_write(&write_handles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void maybe_connect_some() {
|
||||
uv_req_t* req;
|
||||
uv_tcp_t* tcp;
|
||||
int r;
|
||||
|
||||
while (max_connect_socket < TARGET_CONNECTIONS &&
|
||||
max_connect_socket < write_sockets + MAX_SIMULTANEOUS_CONNECTS) {
|
||||
tcp = &write_handles[max_connect_socket++];
|
||||
|
||||
r = uv_tcp_init(tcp);
|
||||
ASSERT(r == 0);
|
||||
|
||||
req = req_alloc();
|
||||
uv_req_init(req, (uv_handle_t*)tcp, connect_cb);
|
||||
r = uv_connect(req, connect_addr);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void connection_cb(uv_tcp_t* s, int status) {
|
||||
uv_tcp_t* tcp;
|
||||
int r;
|
||||
|
||||
ASSERT(&server == s);
|
||||
ASSERT(status == 0);
|
||||
|
||||
tcp = malloc(sizeof(uv_tcp_t));
|
||||
|
||||
uv_tcp_init(tcp);
|
||||
|
||||
r = uv_accept(s, tcp);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start(tcp, buf_alloc, read_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
read_sockets++;
|
||||
max_read_sockets++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Request allocator
|
||||
*/
|
||||
|
||||
typedef struct req_list_s {
|
||||
uv_req_t uv_req;
|
||||
struct req_list_s* next;
|
||||
} req_list_t;
|
||||
|
||||
|
||||
static req_list_t* req_freelist = NULL;
|
||||
|
||||
|
||||
static uv_req_t* req_alloc() {
|
||||
req_list_t* req;
|
||||
|
||||
req = req_freelist;
|
||||
if (req != NULL) {
|
||||
req_freelist = req->next;
|
||||
return (uv_req_t*) req;
|
||||
}
|
||||
|
||||
req = (req_list_t*) malloc(sizeof *req);
|
||||
return (uv_req_t*) req;
|
||||
}
|
||||
|
||||
|
||||
static void req_free(uv_req_t* uv_req) {
|
||||
req_list_t* req = (req_list_t*) uv_req;
|
||||
|
||||
req->next = req_freelist;
|
||||
req_freelist = req;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Buffer allocator
|
||||
*/
|
||||
|
||||
typedef struct buf_list_s {
|
||||
uv_buf_t uv_buf_t;
|
||||
struct buf_list_s* next;
|
||||
} buf_list_t;
|
||||
|
||||
|
||||
static buf_list_t* buf_freelist = NULL;
|
||||
|
||||
|
||||
static uv_buf_t buf_alloc(uv_tcp_t* tcp, size_t size) {
|
||||
buf_list_t* buf;
|
||||
|
||||
buf = buf_freelist;
|
||||
if (buf != NULL) {
|
||||
buf_freelist = buf->next;
|
||||
return buf->uv_buf_t;
|
||||
}
|
||||
|
||||
buf = (buf_list_t*) malloc(size + sizeof *buf);
|
||||
buf->uv_buf_t.len = (unsigned int)size;
|
||||
buf->uv_buf_t.base = ((char*) buf) + sizeof *buf;
|
||||
|
||||
return buf->uv_buf_t;
|
||||
}
|
||||
|
||||
|
||||
static void buf_free(uv_buf_t uv_buf_t) {
|
||||
buf_list_t* buf = (buf_list_t*) (uv_buf_t.base - sizeof *buf);
|
||||
|
||||
buf->next = buf_freelist;
|
||||
buf_freelist = buf;
|
||||
}
|
||||
|
||||
|
||||
HELPER_IMPL(pump_server) {
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
listen_addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
|
||||
|
||||
/* Server */
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, listen_addr);
|
||||
ASSERT(r == 0);
|
||||
r = uv_listen(&server, MAX_WRITE_HANDLES, connection_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_run();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void pump(int n) {
|
||||
ASSERT(n <= MAX_WRITE_HANDLES);
|
||||
TARGET_CONNECTIONS = n;
|
||||
|
||||
uv_init();
|
||||
|
||||
connect_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
|
||||
/* Start making connections */
|
||||
maybe_connect_some();
|
||||
|
||||
uv_run();
|
||||
}
|
||||
|
||||
|
||||
BENCHMARK_IMPL(pump100_client) {
|
||||
pump(100);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
BENCHMARK_IMPL(pump1_client) {
|
||||
pump(1);
|
||||
return 0;
|
||||
}
|
||||
35
src/rt/libuv/test/benchmark-sizes.c
Normal file
35
src/rt/libuv/test/benchmark-sizes.c
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "task.h"
|
||||
#include "../uv.h"
|
||||
|
||||
|
||||
BENCHMARK_IMPL(sizes) {
|
||||
LOGF("uv_req_t: %lu bytes\n", sizeof(uv_req_t));
|
||||
LOGF("uv_tcp_t: %lu bytes\n", sizeof(uv_tcp_t));
|
||||
LOGF("uv_prepare_t: %lu bytes\n", sizeof(uv_prepare_t));
|
||||
LOGF("uv_check_t: %lu bytes\n", sizeof(uv_check_t));
|
||||
LOGF("uv_idle_t: %lu bytes\n", sizeof(uv_idle_t));
|
||||
LOGF("uv_async_t: %lu bytes\n", sizeof(uv_async_t));
|
||||
LOGF("uv_timer_t: %lu bytes\n", sizeof(uv_timer_t));
|
||||
return 0;
|
||||
}
|
||||
188
src/rt/libuv/test/echo-server.c
Normal file
188
src/rt/libuv/test/echo-server.c
Normal file
|
|
@ -0,0 +1,188 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
uv_req_t req;
|
||||
uv_buf_t buf;
|
||||
} write_req_t;
|
||||
|
||||
|
||||
static int server_closed;
|
||||
static uv_tcp_t server;
|
||||
|
||||
|
||||
static void after_write(uv_req_t* req, int status);
|
||||
static void after_read(uv_tcp_t*, ssize_t nread, uv_buf_t buf);
|
||||
static void on_close(uv_handle_t* peer);
|
||||
static void on_server_close(uv_handle_t* handle);
|
||||
static void on_connection(uv_tcp_t*, int status);
|
||||
|
||||
|
||||
static void after_write(uv_req_t* req, int status) {
|
||||
write_req_t* wr;
|
||||
|
||||
if (status) {
|
||||
uv_err_t err = uv_last_error();
|
||||
fprintf(stderr, "uv_write error: %s\n", uv_strerror(err));
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
wr = (write_req_t*) req;
|
||||
|
||||
/* Free the read/write buffer and the request */
|
||||
free(wr->buf.base);
|
||||
free(wr);
|
||||
}
|
||||
|
||||
|
||||
static void after_shutdown(uv_req_t* req, int status) {
|
||||
uv_close(req->handle, on_close);
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void after_read(uv_tcp_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
int i;
|
||||
write_req_t *wr;
|
||||
uv_req_t* req;
|
||||
|
||||
if (nread < 0) {
|
||||
/* Error or EOF */
|
||||
ASSERT (uv_last_error().code == UV_EOF);
|
||||
|
||||
if (buf.base) {
|
||||
free(buf.base);
|
||||
}
|
||||
|
||||
req = (uv_req_t*) malloc(sizeof *req);
|
||||
uv_req_init(req, (uv_handle_t*)handle, after_shutdown);
|
||||
uv_shutdown(req);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (nread == 0) {
|
||||
/* Everything OK, but nothing read. */
|
||||
free(buf.base);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Scan for the letter Q which signals that we should quit. */
|
||||
if (!server_closed) {
|
||||
for (i = 0; i < nread; i++) {
|
||||
if (buf.base[i] == 'Q') {
|
||||
uv_close((uv_handle_t*)&server, on_server_close);
|
||||
server_closed = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wr = (write_req_t*) malloc(sizeof *wr);
|
||||
|
||||
uv_req_init(&wr->req, (uv_handle_t*)handle, after_write);
|
||||
wr->buf.base = buf.base;
|
||||
wr->buf.len = nread;
|
||||
if (uv_write(&wr->req, &wr->buf, 1)) {
|
||||
FATAL("uv_write failed");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void on_close(uv_handle_t* peer) {
|
||||
free(peer);
|
||||
}
|
||||
|
||||
|
||||
static uv_buf_t echo_alloc(uv_tcp_t* handle, size_t suggested_size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*) malloc(suggested_size);
|
||||
buf.len = suggested_size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void on_connection(uv_tcp_t* server, int status) {
|
||||
uv_tcp_t* handle;
|
||||
int r;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
handle = (uv_tcp_t*) malloc(sizeof *handle);
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
uv_tcp_init(handle);
|
||||
|
||||
r = uv_accept(server, handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start(handle, echo_alloc, after_read);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static void on_server_close(uv_handle_t* handle) {
|
||||
ASSERT(handle == (uv_handle_t*)&server);
|
||||
}
|
||||
|
||||
|
||||
static int echo_start(int port) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", port);
|
||||
int r;
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Socket creation error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_bind(&server, addr);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Bind error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_listen(&server, 128, on_connection);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Listen error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
HELPER_IMPL(echo_server) {
|
||||
uv_init();
|
||||
if (echo_start(TEST_PORT))
|
||||
return 1;
|
||||
|
||||
uv_run();
|
||||
return 0;
|
||||
}
|
||||
59
src/rt/libuv/test/run-benchmarks.c
Normal file
59
src/rt/libuv/test/run-benchmarks.c
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "runner.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Actual benchmarks and helpers are defined in benchmark-list.h */
|
||||
#include "benchmark-list.h"
|
||||
|
||||
|
||||
/* The time in milliseconds after which a single benchmark times out. */
|
||||
#define BENCHMARK_TIMEOUT 60000
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
task_entry_t *task;
|
||||
|
||||
platform_init(argc, argv);
|
||||
|
||||
if (argc > 1) {
|
||||
/* A specific process was requested. */
|
||||
return run_process(argv[1]);
|
||||
|
||||
} else {
|
||||
/* Run all benchmarks. */
|
||||
task = (task_entry_t*)&TASKS;
|
||||
for (task = (task_entry_t*)&TASKS; task->main; task++) {
|
||||
if (task->is_helper) {
|
||||
continue;
|
||||
}
|
||||
|
||||
run_task(task, BENCHMARK_TIMEOUT, 1);
|
||||
}
|
||||
LOG("Done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
86
src/rt/libuv/test/run-tests.c
Normal file
86
src/rt/libuv/test/run-tests.c
Normal file
|
|
@ -0,0 +1,86 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "runner.h"
|
||||
#include "task.h"
|
||||
|
||||
/* Actual tests and helpers are defined in test-list.h */
|
||||
#include "test-list.h"
|
||||
|
||||
|
||||
/* The time in milliseconds after which a single test times out. */
|
||||
#define TEST_TIMEOUT 5000
|
||||
|
||||
|
||||
static void log_progress(int total, int passed, int failed, char* name) {
|
||||
LOGF("[%% %3d|+ %3d|- %3d]: %s", (passed + failed) / total * 100,
|
||||
passed, failed, name);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int total, passed, failed;
|
||||
task_entry_t* task;
|
||||
|
||||
platform_init(argc, argv);
|
||||
|
||||
if (argc > 1) {
|
||||
/* A specific process was requested. */
|
||||
return run_process(argv[1]);
|
||||
|
||||
} else {
|
||||
/* Count the number of tests. */
|
||||
total = 0;
|
||||
task = (task_entry_t*)&TASKS;
|
||||
for (task = (task_entry_t*)&TASKS; task->main; task++) {
|
||||
if (!task->is_helper) {
|
||||
total++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Run all tests. */
|
||||
passed = 0;
|
||||
failed = 0;
|
||||
task = (task_entry_t*)&TASKS;
|
||||
for (task = (task_entry_t*)&TASKS; task->main; task++) {
|
||||
if (task->is_helper) {
|
||||
continue;
|
||||
}
|
||||
|
||||
rewind_cursor();
|
||||
log_progress(total, passed, failed, task->task_name);
|
||||
|
||||
if (run_task(task, TEST_TIMEOUT, 0)) {
|
||||
passed++;
|
||||
} else {
|
||||
failed++;
|
||||
}
|
||||
}
|
||||
|
||||
rewind_cursor();
|
||||
log_progress(total, passed, failed, "Done.\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
335
src/rt/libuv/test/runner-unix.c
Normal file
335
src/rt/libuv/test/runner-unix.c
Normal file
|
|
@ -0,0 +1,335 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "runner-unix.h"
|
||||
#include "runner.h"
|
||||
|
||||
#include <stdint.h> /* uintptr_t */
|
||||
|
||||
#include <unistd.h> /* usleep */
|
||||
#include <string.h> /* strdup */
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/stat.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <sys/select.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <mach-o/dyld.h> /* _NSGetExecutablePath */
|
||||
|
||||
static void get_executable_path() {
|
||||
uint32_t bufsize = sizeof(executable_path);
|
||||
_NSGetExecutablePath(executable_path, &bufsize);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __linux__
|
||||
static void get_executable_path() {
|
||||
if (!executable_path[0]) {
|
||||
readlink("/proc/self/exe", executable_path, PATHMAX - 1);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* Do platform-specific initialization. */
|
||||
void platform_init(int argc, char **argv) {
|
||||
/* Disable stdio output buffering. */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
#ifdef get_executable_path
|
||||
get_executable_path();
|
||||
#else
|
||||
strcpy(executable_path, argv[0]);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Invoke "arv[0] test-name". Store process info in *p. */
|
||||
/* Make sure that all stdio output of the processes is buffered up. */
|
||||
int process_start(char* name, process_info_t* p) {
|
||||
FILE* stdout_file = tmpfile();
|
||||
if (!stdout_file) {
|
||||
perror("tmpfile");
|
||||
return -1;
|
||||
}
|
||||
|
||||
p->terminated = 0;
|
||||
p->status = 0;
|
||||
|
||||
pid_t pid = fork();
|
||||
|
||||
if (pid < 0) {
|
||||
perror("vfork");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (pid == 0) {
|
||||
/* child */
|
||||
dup2(fileno(stdout_file), STDOUT_FILENO);
|
||||
dup2(fileno(stdout_file), STDERR_FILENO);
|
||||
|
||||
char* args[3] = { executable_path, name, NULL };
|
||||
execvp(executable_path, args);
|
||||
perror("execvp()");
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
/* parent */
|
||||
p->pid = pid;
|
||||
p->name = strdup(name);
|
||||
p->stdout_file = stdout_file;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
int pipe[2];
|
||||
process_info_t* vec;
|
||||
int n;
|
||||
} dowait_args;
|
||||
|
||||
|
||||
/* This function is run inside a pthread. We do this so that we can possibly
|
||||
* timeout.
|
||||
*/
|
||||
static void* dowait(void* data) {
|
||||
dowait_args* args = data;
|
||||
|
||||
int i, status, r;
|
||||
process_info_t* p;
|
||||
|
||||
for (i = 0; i < args->n; i++) {
|
||||
p = (process_info_t*)(args->vec + i * sizeof(process_info_t));
|
||||
if (p->terminated) continue;
|
||||
status = 0;
|
||||
r = waitpid(p->pid, &p->status, 0);
|
||||
if (r < 0) {
|
||||
perror("waitpid");
|
||||
return NULL;
|
||||
}
|
||||
p->terminated = 1;
|
||||
}
|
||||
|
||||
if (args->pipe[1] >= 0) {
|
||||
/* Write a character to the main thread to notify it about this. */
|
||||
char c = 0;
|
||||
write(args->pipe[1], &c, 1);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Wait for all `n` processes in `vec` to terminate. */
|
||||
/* Time out after `timeout` msec, or never if timeout == -1 */
|
||||
/* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */
|
||||
int process_wait(process_info_t* vec, int n, int timeout) {
|
||||
int i;
|
||||
process_info_t* p;
|
||||
dowait_args args;
|
||||
args.vec = vec;
|
||||
args.n = n;
|
||||
args.pipe[0] = -1;
|
||||
args.pipe[1] = -1;
|
||||
|
||||
/* The simple case is where there is no timeout */
|
||||
if (timeout == -1) {
|
||||
dowait(&args);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Hard case. Do the wait with a timeout.
|
||||
*
|
||||
* Assumption: we are the only ones making this call right now. Otherwise
|
||||
* we'd need to lock vec.
|
||||
*/
|
||||
|
||||
pthread_t tid;
|
||||
int retval;
|
||||
|
||||
int r = pipe((int*)&(args.pipe));
|
||||
if (r) {
|
||||
perror("pipe()");
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = pthread_create(&tid, NULL, dowait, &args);
|
||||
if (r) {
|
||||
perror("pthread_create()");
|
||||
retval = -1;
|
||||
goto terminate;
|
||||
}
|
||||
|
||||
struct timeval tv;
|
||||
tv.tv_sec = timeout / 1000;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
fd_set fds;
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(args.pipe[0], &fds);
|
||||
|
||||
r = select(args.pipe[0] + 1, &fds, NULL, NULL, &tv);
|
||||
|
||||
if (r == -1) {
|
||||
perror("select()");
|
||||
retval = -1;
|
||||
|
||||
} else if (r) {
|
||||
/* The thread completed successfully. */
|
||||
retval = 0;
|
||||
|
||||
} else {
|
||||
/* Timeout. Kill all the children. */
|
||||
for (i = 0; i < n; i++) {
|
||||
p = (process_info_t*)(vec + i * sizeof(process_info_t));
|
||||
kill(p->pid, SIGTERM);
|
||||
}
|
||||
retval = -2;
|
||||
|
||||
/* Wait for thread to finish. */
|
||||
r = pthread_join(tid, NULL);
|
||||
if (r) {
|
||||
perror("pthread_join");
|
||||
retval = -1;
|
||||
}
|
||||
}
|
||||
|
||||
terminate:
|
||||
close(args.pipe[0]);
|
||||
close(args.pipe[1]);
|
||||
return retval;
|
||||
}
|
||||
|
||||
|
||||
/* Returns the number of bytes in the stdio output buffer for process `p`. */
|
||||
long int process_output_size(process_info_t *p) {
|
||||
/* Size of the p->stdout_file */
|
||||
struct stat buf;
|
||||
|
||||
int r = fstat(fileno(p->stdout_file), &buf);
|
||||
if (r < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (long)buf.st_size;
|
||||
}
|
||||
|
||||
|
||||
/* Copy the contents of the stdio output buffer to `fd`. */
|
||||
int process_copy_output(process_info_t *p, int fd) {
|
||||
int r = fseek(p->stdout_file, 0, SEEK_SET);
|
||||
if (r < 0) {
|
||||
perror("fseek");
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t nread, nwritten;
|
||||
char buf[1024];
|
||||
|
||||
while ((nread = read(fileno(p->stdout_file), buf, 1024)) > 0) {
|
||||
nwritten = write(fd, buf, nread);
|
||||
/* TODO: what if write doesn't write the whole buffer... */
|
||||
if (nwritten < 0) {
|
||||
perror("write");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (nread < 0) {
|
||||
perror("read");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Return the name that was specified when `p` was started by process_start */
|
||||
char* process_get_name(process_info_t *p) {
|
||||
return p->name;
|
||||
}
|
||||
|
||||
|
||||
/* Terminate process `p`. */
|
||||
int process_terminate(process_info_t *p) {
|
||||
return kill(p->pid, SIGTERM);
|
||||
}
|
||||
|
||||
|
||||
/* Return the exit code of process p. */
|
||||
/* On error, return -1. */
|
||||
int process_reap(process_info_t *p) {
|
||||
if (WIFEXITED(p->status)) {
|
||||
return WEXITSTATUS(p->status);
|
||||
} else {
|
||||
return p->status; /* ? */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */
|
||||
void process_cleanup(process_info_t *p) {
|
||||
fclose(p->stdout_file);
|
||||
free(p->name);
|
||||
}
|
||||
|
||||
|
||||
/* Move the console cursor one line up and back to the first column. */
|
||||
void rewind_cursor() {
|
||||
fprintf(stderr, "\033[2K\r");
|
||||
}
|
||||
|
||||
|
||||
typedef void* (*uv_thread_cb)(void* arg);
|
||||
|
||||
|
||||
uintptr_t uv_create_thread(void (*entry)(void* arg), void* arg) {
|
||||
pthread_t t;
|
||||
uv_thread_cb cb = (uv_thread_cb)entry;
|
||||
int r = pthread_create(&t, NULL, cb, arg);
|
||||
|
||||
if (r) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return (uintptr_t)t;
|
||||
}
|
||||
|
||||
|
||||
/* Wait for a thread to terminate. Should return 0 if the thread ended, -1 on
|
||||
* error.
|
||||
*/
|
||||
int uv_wait_thread(uintptr_t thread_id) {
|
||||
return pthread_join((pthread_t)thread_id, NULL);
|
||||
}
|
||||
|
||||
|
||||
/* Pause the calling thread for a number of milliseconds. */
|
||||
void uv_sleep(int msec) {
|
||||
usleep(msec);
|
||||
}
|
||||
36
src/rt/libuv/test/runner-unix.h
Normal file
36
src/rt/libuv/test/runner-unix.h
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TEST_RUNNER_UNIX_H
|
||||
#define TEST_RUNNER_UNIX_H
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <stdio.h> /* FILE */
|
||||
|
||||
typedef struct {
|
||||
FILE* stdout_file;
|
||||
pid_t pid;
|
||||
char* name;
|
||||
int status;
|
||||
int terminated;
|
||||
} process_info_t;
|
||||
|
||||
#endif /* TEST_RUNNER_UNIX_H */
|
||||
331
src/rt/libuv/test/runner-win.c
Normal file
331
src/rt/libuv/test/runner-win.c
Normal file
|
|
@ -0,0 +1,331 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <io.h>
|
||||
#include <malloc.h>
|
||||
#include <stdio.h>
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "task.h"
|
||||
#include "runner.h"
|
||||
|
||||
|
||||
/*
|
||||
* Define the stuff that MinGW doesn't have
|
||||
*/
|
||||
#ifndef GetFileSizeEx
|
||||
WINBASEAPI BOOL WINAPI GetFileSizeEx(HANDLE hFile,
|
||||
PLARGE_INTEGER lpFileSize);
|
||||
#endif
|
||||
|
||||
|
||||
/* Do platform-specific initialization. */
|
||||
void platform_init(int argc, char **argv) {
|
||||
/* Disable the "application crashed" popup. */
|
||||
SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX |
|
||||
SEM_NOOPENFILEERRORBOX);
|
||||
|
||||
/* Disable stdio output buffering. */
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
setvbuf(stderr, NULL, _IONBF, 0);
|
||||
|
||||
strcpy(executable_path, argv[0]);
|
||||
}
|
||||
|
||||
|
||||
int process_start(char *name, process_info_t *p) {
|
||||
HANDLE file = INVALID_HANDLE_VALUE;
|
||||
HANDLE nul = INVALID_HANDLE_VALUE;
|
||||
WCHAR path[MAX_PATH], filename[MAX_PATH];
|
||||
WCHAR image[MAX_PATH + 1];
|
||||
WCHAR args[MAX_PATH * 2];
|
||||
STARTUPINFOW si;
|
||||
PROCESS_INFORMATION pi;
|
||||
DWORD result;
|
||||
|
||||
if (GetTempPathW(sizeof(path) / sizeof(WCHAR), (WCHAR*)&path) == 0)
|
||||
goto error;
|
||||
if (GetTempFileNameW((WCHAR*)&path, L"uv", 0, (WCHAR*)&filename) == 0)
|
||||
goto error;
|
||||
|
||||
file = CreateFileW((WCHAR*)filename,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
CREATE_ALWAYS,
|
||||
FILE_ATTRIBUTE_TEMPORARY | FILE_FLAG_DELETE_ON_CLOSE,
|
||||
NULL);
|
||||
if (file == INVALID_HANDLE_VALUE)
|
||||
goto error;
|
||||
|
||||
if (!SetHandleInformation(file, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
|
||||
goto error;
|
||||
|
||||
nul = CreateFileA("nul",
|
||||
GENERIC_READ,
|
||||
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_NORMAL,
|
||||
NULL);
|
||||
if (nul == INVALID_HANDLE_VALUE)
|
||||
goto error;
|
||||
|
||||
if (!SetHandleInformation(nul, HANDLE_FLAG_INHERIT, HANDLE_FLAG_INHERIT))
|
||||
goto error;
|
||||
|
||||
result = GetModuleFileNameW(NULL, (WCHAR*)&image, sizeof(image) / sizeof(WCHAR));
|
||||
if (result == 0 || result == sizeof(image))
|
||||
goto error;
|
||||
|
||||
if (_snwprintf((wchar_t*)&args,
|
||||
sizeof(args) / sizeof(wchar_t),
|
||||
L"\"%s\" %S",
|
||||
image,
|
||||
name) < 0)
|
||||
goto error;
|
||||
|
||||
memset((void*)&si, 0, sizeof(si));
|
||||
si.cb = sizeof(si);
|
||||
si.dwFlags = STARTF_USESTDHANDLES;
|
||||
si.hStdInput = nul;
|
||||
si.hStdOutput = file;
|
||||
si.hStdError = file;
|
||||
|
||||
if (!CreateProcessW(image, args, NULL, NULL, TRUE,
|
||||
0, NULL, NULL, &si, &pi))
|
||||
goto error;
|
||||
|
||||
CloseHandle(pi.hThread);
|
||||
|
||||
SetHandleInformation(nul, HANDLE_FLAG_INHERIT, 0);
|
||||
SetHandleInformation(file, HANDLE_FLAG_INHERIT, 0);
|
||||
|
||||
p->stdio_in = nul;
|
||||
p->stdio_out = file;
|
||||
p->process = pi.hProcess;
|
||||
p->name = name;
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
if (file != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(file);
|
||||
if (nul != INVALID_HANDLE_VALUE)
|
||||
CloseHandle(nul);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/* Timeout is is msecs. Set timeout < 0 to never time out. */
|
||||
/* Returns 0 when all processes are terminated, -2 on timeout. */
|
||||
int process_wait(process_info_t *vec, int n, int timeout) {
|
||||
int i;
|
||||
HANDLE handles[MAXIMUM_WAIT_OBJECTS];
|
||||
DWORD timeout_api, result;
|
||||
|
||||
/* If there's nothing to wait for, return immedately. */
|
||||
if (n == 0)
|
||||
return 0;
|
||||
|
||||
ASSERT(n <= MAXIMUM_WAIT_OBJECTS);
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
handles[i] = vec[i].process;
|
||||
|
||||
if (timeout >= 0) {
|
||||
timeout_api = (DWORD)timeout;
|
||||
} else {
|
||||
timeout_api = INFINITE;
|
||||
}
|
||||
|
||||
result = WaitForMultipleObjects(n, handles, TRUE, timeout_api);
|
||||
|
||||
if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + n) {
|
||||
/* All processes are terminated. */
|
||||
return 0;
|
||||
}
|
||||
if (result == WAIT_TIMEOUT) {
|
||||
return -2;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
long int process_output_size(process_info_t *p) {
|
||||
LARGE_INTEGER size;
|
||||
if (!GetFileSizeEx(p->stdio_out, &size))
|
||||
return -1;
|
||||
return (long int)size.QuadPart;
|
||||
}
|
||||
|
||||
|
||||
int process_copy_output(process_info_t *p, int fd) {
|
||||
DWORD read;
|
||||
char buf[1024];
|
||||
|
||||
if (SetFilePointer(p->stdio_out, 0, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER)
|
||||
return -1;
|
||||
|
||||
while (ReadFile(p->stdio_out, (void*)&buf, sizeof(buf), &read, NULL) &&
|
||||
read > 0)
|
||||
write(fd, buf, read);
|
||||
|
||||
if (GetLastError() != ERROR_HANDLE_EOF)
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
char* process_get_name(process_info_t *p) {
|
||||
return p->name;
|
||||
}
|
||||
|
||||
|
||||
int process_terminate(process_info_t *p) {
|
||||
if (!TerminateProcess(p->process, 1))
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int process_reap(process_info_t *p) {
|
||||
DWORD exitCode;
|
||||
if (!GetExitCodeProcess(p->process, &exitCode))
|
||||
return -1;
|
||||
return (int)exitCode;
|
||||
}
|
||||
|
||||
|
||||
void process_cleanup(process_info_t *p) {
|
||||
CloseHandle(p->process);
|
||||
CloseHandle(p->stdio_in);
|
||||
CloseHandle(p->stdio_out);
|
||||
}
|
||||
|
||||
|
||||
static int clear_line() {
|
||||
HANDLE handle;
|
||||
CONSOLE_SCREEN_BUFFER_INFO info;
|
||||
COORD coord;
|
||||
DWORD written;
|
||||
|
||||
handle = (HANDLE)_get_osfhandle(fileno(stderr));
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return -1;
|
||||
|
||||
if (!GetConsoleScreenBufferInfo(handle, &info))
|
||||
return -1;
|
||||
|
||||
coord = info.dwCursorPosition;
|
||||
if (coord.Y <= 0)
|
||||
return -1;
|
||||
|
||||
coord.X = 0;
|
||||
|
||||
if (!SetConsoleCursorPosition(handle, coord))
|
||||
return -1;
|
||||
|
||||
if (!FillConsoleOutputCharacterW(handle, 0x20, info.dwSize.X, coord, &written))
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void rewind_cursor() {
|
||||
if (clear_line() == -1) {
|
||||
/* If clear_line fails (stdout is not a console), print a newline. */
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
typedef struct {
|
||||
void (*entry)(void* arg);
|
||||
void* arg;
|
||||
} thread_info_t;
|
||||
|
||||
|
||||
static unsigned __stdcall create_thread_helper(void* info) {
|
||||
/* Copy thread info locally, then free it */
|
||||
void (*entry)(void* arg) = ((thread_info_t*) info)->entry;
|
||||
void* arg = ((thread_info_t*) info)->arg;
|
||||
|
||||
free(info);
|
||||
|
||||
/* Run the actual thread proc */
|
||||
entry(arg);
|
||||
|
||||
/* Finalize */
|
||||
_endthreadex(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Create a thread. Returns the thread identifier, or 0 on failure. */
|
||||
uintptr_t uv_create_thread(void (*entry)(void* arg), void* arg) {
|
||||
uintptr_t result;
|
||||
thread_info_t* info;
|
||||
|
||||
info = (thread_info_t*) malloc(sizeof *info);
|
||||
if (info == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
info->entry = entry;
|
||||
info->arg = arg;
|
||||
|
||||
result = _beginthreadex(NULL,
|
||||
0,
|
||||
&create_thread_helper,
|
||||
(void*) info,
|
||||
0,
|
||||
NULL);
|
||||
|
||||
if (result == 0) {
|
||||
free(info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/* Wait for a thread to terminate. Should return 0 if the thread ended, -1 on
|
||||
* error.
|
||||
*/
|
||||
int uv_wait_thread(uintptr_t thread_id) {
|
||||
if (WaitForSingleObject((HANDLE)thread_id, INFINITE) != WAIT_OBJECT_0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* Pause the calling thread for a number of milliseconds. */
|
||||
void uv_sleep(int msec) {
|
||||
Sleep(msec);
|
||||
}
|
||||
42
src/rt/libuv/test/runner-win.h
Normal file
42
src/rt/libuv/test/runner-win.h
Normal file
|
|
@ -0,0 +1,42 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Don't complain about _snprintf being unsecure. */
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
|
||||
/* Dont complain about write(), fileno() etc. being deprecated. */
|
||||
#pragma warning(disable : 4996)
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
/* Windows has no snprintf, only _snprintf. */
|
||||
#define snprintf _snprintf
|
||||
|
||||
|
||||
typedef struct {
|
||||
HANDLE process;
|
||||
HANDLE stdio_in;
|
||||
HANDLE stdio_out;
|
||||
char *name;
|
||||
} process_info_t;
|
||||
171
src/rt/libuv/test/runner.c
Normal file
171
src/rt/libuv/test/runner.c
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "runner.h"
|
||||
#include "task.h"
|
||||
|
||||
char executable_path[PATHMAX] = { '\0' };
|
||||
|
||||
/* Start a specific process declared by TEST_ENTRY or TEST_HELPER. */
|
||||
/* Returns the exit code of the specific process. */
|
||||
int run_process(char* name) {
|
||||
task_entry_t *test;
|
||||
|
||||
for (test = (task_entry_t*)&TASKS; test->main; test++) {
|
||||
if (strcmp(name, test->process_name) == 0) {
|
||||
return test->main();
|
||||
}
|
||||
}
|
||||
|
||||
LOGF("Test process %s not found!\n", name);
|
||||
return 255;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Runs all processes associated with a particular test or benchmark.
|
||||
* It returns 1 if the test succeeded, 0 if it failed.
|
||||
* If the test fails it prints diagnostic information.
|
||||
* If benchmark_output is nonzero, the output from the main process is
|
||||
* always shown.
|
||||
*/
|
||||
int run_task(task_entry_t *test, int timeout, int benchmark_output) {
|
||||
int i, result, success;
|
||||
char errmsg[256];
|
||||
task_entry_t *helper;
|
||||
int process_count;
|
||||
process_info_t processes[MAX_PROCESSES];
|
||||
process_info_t *main_process;
|
||||
|
||||
success = 0;
|
||||
|
||||
process_count = 0;
|
||||
|
||||
/* Start all helpers for this test first. */
|
||||
for (helper = (task_entry_t*)&TASKS; helper->main; helper++) {
|
||||
if (helper->is_helper &&
|
||||
strcmp(test->task_name, helper->task_name) == 0) {
|
||||
if (process_start(helper->process_name, &processes[process_count]) == -1) {
|
||||
snprintf((char*)&errmsg,
|
||||
sizeof(errmsg),
|
||||
"process `%s` failed to start.",
|
||||
helper->process_name);
|
||||
goto finalize;
|
||||
}
|
||||
process_count++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Wait a little bit to allow servers to start. Racy. */
|
||||
uv_sleep(100);
|
||||
|
||||
/* Start the main test process. */
|
||||
if (process_start(test->process_name, &processes[process_count]) == -1) {
|
||||
snprintf((char*)&errmsg, sizeof(errmsg), "process `%s` failed to start.",
|
||||
test->process_name);
|
||||
goto finalize;
|
||||
}
|
||||
main_process = &processes[process_count];
|
||||
process_count++;
|
||||
|
||||
/* Wait for the main process to terminate. */
|
||||
result = process_wait(main_process, 1, timeout);
|
||||
if (result == -1) {
|
||||
FATAL("process_wait failed");
|
||||
} else if (result == -2) {
|
||||
snprintf((char*)&errmsg, sizeof(errmsg), "timeout.");
|
||||
goto finalize;
|
||||
}
|
||||
|
||||
/* Reap the main process. */
|
||||
result = process_reap(main_process);
|
||||
if (result != 0) {
|
||||
snprintf((char*)&errmsg, sizeof(errmsg), "exit code %d.", result);
|
||||
goto finalize;
|
||||
}
|
||||
|
||||
/* Yes! did it. */
|
||||
success = 1;
|
||||
|
||||
finalize:
|
||||
/* Kill all (helper) processes that are still running. */
|
||||
for (i = 0; i < process_count; i++) {
|
||||
/* If terminate fails the process is probably already closed. */
|
||||
process_terminate(&processes[i]);
|
||||
}
|
||||
|
||||
/* Wait until all processes have really terminated. */
|
||||
if (process_wait((process_info_t*)&processes, process_count, -1) < 0) {
|
||||
FATAL("process_wait failed");
|
||||
}
|
||||
|
||||
/* Show error and output from processes if the test failed. */
|
||||
if (!success) {
|
||||
LOGF("\n`%s` failed: %s\n", test->task_name, errmsg);
|
||||
|
||||
for (i = 0; i < process_count; i++) {
|
||||
switch (process_output_size(&processes[i])) {
|
||||
case -1:
|
||||
LOGF("Output from process `%s`: (unavailable)\n",
|
||||
process_get_name(&processes[i]));
|
||||
break;
|
||||
|
||||
case 0:
|
||||
LOGF("Output from process `%s`: (no output)\n",
|
||||
process_get_name(&processes[i]));
|
||||
break;
|
||||
|
||||
default:
|
||||
LOGF("Output from process `%s`:\n", process_get_name(&processes[i]));
|
||||
process_copy_output(&processes[i], fileno(stderr));
|
||||
break;
|
||||
}
|
||||
}
|
||||
LOG("=============================================================\n");
|
||||
|
||||
/* In benchmark mode show concise output from the main process. */
|
||||
} else if (benchmark_output) {
|
||||
switch (process_output_size(main_process)) {
|
||||
case -1:
|
||||
LOGF("%s: (unavailabe)\n", test->task_name);
|
||||
break;
|
||||
|
||||
case 0:
|
||||
LOGF("%s: (no output)\n", test->task_name);
|
||||
break;
|
||||
|
||||
default:
|
||||
for (i = 0; i < process_count; i++) {
|
||||
process_copy_output(&processes[i], fileno(stderr));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up all process handles. */
|
||||
for (i = 0; i < process_count; i++) {
|
||||
process_cleanup(&processes[i]);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
147
src/rt/libuv/test/runner.h
Normal file
147
src/rt/libuv/test/runner.h
Normal file
|
|
@ -0,0 +1,147 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef RUNNER_H_
|
||||
#define RUNNER_H_
|
||||
|
||||
|
||||
/*
|
||||
* The maximum number of processes (main + helpers) that a test / benchmark
|
||||
* can have.
|
||||
*/
|
||||
#define MAX_PROCESSES 8
|
||||
|
||||
|
||||
/*
|
||||
* Struct to store both tests and to define helper processes for tasks.
|
||||
*/
|
||||
typedef struct {
|
||||
char *task_name;
|
||||
char *process_name;
|
||||
int (*main)();
|
||||
int is_helper;
|
||||
} task_entry_t, bench_entry_t;
|
||||
|
||||
|
||||
/* Runs an individual task; returns 1 if the test succeeded, 0 if it failed. */
|
||||
/* If the test fails it prints diagnostic information. */
|
||||
/* If benchmark_output is nonzero, the output from the main process is
|
||||
/* always shown. */
|
||||
int run_task(task_entry_t *test, int timeout, int benchmark_output);
|
||||
|
||||
|
||||
/*
|
||||
* Macros used by test-list.h and benchmark-list.h.
|
||||
*/
|
||||
#define TASK_LIST_START \
|
||||
task_entry_t TASKS[] = {
|
||||
|
||||
#define TASK_LIST_END \
|
||||
{ 0, 0, 0, 0 } \
|
||||
};
|
||||
|
||||
#define TEST_DECLARE(name) \
|
||||
int run_test_##name();
|
||||
|
||||
#define TEST_ENTRY(name) \
|
||||
{ #name, #name, &run_test_##name, 0 },
|
||||
|
||||
#define BENCHMARK_DECLARE(name) \
|
||||
int run_benchmark_##name();
|
||||
|
||||
#define BENCHMARK_ENTRY(name) \
|
||||
{ #name, #name, &run_benchmark_##name, 0 },
|
||||
|
||||
#define HELPER_DECLARE(name) \
|
||||
int run_helper_##name();
|
||||
|
||||
#define HELPER_ENTRY(task_name, name) \
|
||||
{ #task_name, #name, &run_helper_##name, 1 },
|
||||
|
||||
#define TEST_HELPER HELPER_ENTRY
|
||||
#define BENCHMARK_HELPER HELPER_ENTRY
|
||||
|
||||
#define PATHMAX 1024
|
||||
extern char executable_path[PATHMAX];
|
||||
|
||||
/*
|
||||
* Include platform-dependent definitions
|
||||
*/
|
||||
#ifdef _WIN32
|
||||
# include "runner-win.h"
|
||||
#else
|
||||
# include "runner-unix.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* The array that is filled by test-list.h or benchmark-list.h */
|
||||
extern task_entry_t TASKS[];
|
||||
|
||||
/* Start a specific process declared by TEST_ENTRY or TEST_HELPER. */
|
||||
/* Returns the exit code of the specific process. */
|
||||
int run_task(task_entry_t *test, int timeout, int benchmark_output);
|
||||
|
||||
/* Start a specific process declared by TEST_ENTRY or TEST_HELPER. */
|
||||
/* Returns the exit code of the specific process. */
|
||||
int run_process(char* name);
|
||||
|
||||
|
||||
/*
|
||||
* Stuff that should be implemented by test-runner-<platform>.h
|
||||
* All functions return 0 on success, -1 on failure, unless specified
|
||||
* otherwise.
|
||||
*/
|
||||
|
||||
/* Do platform-specific initialization. */
|
||||
void platform_init();
|
||||
|
||||
/* Invoke "arv[0] test-name". Store process info in *p. */
|
||||
/* Make sure that all stdio output of the processes is buffered up. */
|
||||
int process_start(char *name, process_info_t *p);
|
||||
|
||||
/* Wait for all `n` processes in `vec` to terminate. */
|
||||
/* Time out after `timeout` msec, or never if timeout == -1 */
|
||||
/* Return 0 if all processes are terminated, -1 on error, -2 on timeout. */
|
||||
int process_wait(process_info_t *vec, int n, int timeout);
|
||||
|
||||
/* Returns the number of bytes in the stdio output buffer for process `p`. */
|
||||
long int process_output_size(process_info_t *p);
|
||||
|
||||
/* Copy the contents of the stdio output buffer to `fd`. */
|
||||
int process_copy_output(process_info_t *p, int fd);
|
||||
|
||||
/* Return the name that was specified when `p` was started by process_start */
|
||||
char* process_get_name(process_info_t *p);
|
||||
|
||||
/* Terminate process `p`. */
|
||||
int process_terminate(process_info_t *p);
|
||||
|
||||
/* Return the exit code of process p. */
|
||||
/* On error, return -1. */
|
||||
int process_reap(process_info_t *p);
|
||||
|
||||
/* Clean up after terminating process `p` (e.g. free the output buffer etc.). */
|
||||
void process_cleanup(process_info_t *p);
|
||||
|
||||
/* Move the console cursor one line up and back to the first column. */
|
||||
void rewind_cursor();
|
||||
|
||||
#endif /* RUNNER_H_ */
|
||||
89
src/rt/libuv/test/task.h
Normal file
89
src/rt/libuv/test/task.h
Normal file
|
|
@ -0,0 +1,89 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef TASK_H_
|
||||
#define TASK_H_
|
||||
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define TEST_PORT 9123
|
||||
#define TEST_PORT_2 9124
|
||||
|
||||
|
||||
/* Log to stderr. */
|
||||
#define LOG(...) fprintf(stderr, "%s", __VA_ARGS__)
|
||||
#define LOGF(...) fprintf(stderr, __VA_ARGS__)
|
||||
|
||||
/* Die with fatal error. */
|
||||
#define FATAL(msg) \
|
||||
do { \
|
||||
fprintf(stderr, \
|
||||
"Fatal error in %s on line %d: %s\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
msg); \
|
||||
abort(); \
|
||||
} while (0)
|
||||
|
||||
|
||||
|
||||
/* Have our own assert, so we are sure it does not get optimized away in
|
||||
* a release build.
|
||||
*/
|
||||
#define ASSERT(expr) \
|
||||
do { \
|
||||
if (!(expr)) { \
|
||||
fprintf(stderr, \
|
||||
"Assertion failed in %s on line %d: %s\n", \
|
||||
__FILE__, \
|
||||
__LINE__, \
|
||||
#expr); \
|
||||
abort(); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
|
||||
/* Just sugar for wrapping the main() for a task or helper. */
|
||||
#define TEST_IMPL(name) \
|
||||
int run_test_##name()
|
||||
|
||||
#define BENCHMARK_IMPL(name) \
|
||||
int run_benchmark_##name()
|
||||
|
||||
#define HELPER_IMPL(name) \
|
||||
int run_helper_##name()
|
||||
|
||||
|
||||
/* Create a thread. Returns the thread identifier, or 0 on failure. */
|
||||
uintptr_t uv_create_thread(void (*entry)(void* arg), void* arg);
|
||||
|
||||
/* Wait for a thread to terminate. Should return 0 if the thread ended, -1 on
|
||||
* error.
|
||||
*/
|
||||
int uv_wait_thread(uintptr_t thread_id);
|
||||
|
||||
/* Pause the calling thread for a number of milliseconds. */
|
||||
void uv_sleep(int msec);
|
||||
|
||||
#endif /* TASK_H_ */
|
||||
223
src/rt/libuv/test/test-async.c
Normal file
223
src/rt/libuv/test/test-async.c
Normal file
|
|
@ -0,0 +1,223 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static uv_prepare_t prepare_handle;
|
||||
|
||||
static uv_async_t async1_handle;
|
||||
/* static uv_handle_t async2_handle; */
|
||||
|
||||
static int prepare_cb_called = 0;
|
||||
|
||||
static volatile int async1_cb_called = 0;
|
||||
static int async1_closed = 0;
|
||||
/* static volatile int async2_cb_called = 0; */
|
||||
|
||||
static int close_cb_called = 0;
|
||||
|
||||
static uintptr_t thread1_id = 0;
|
||||
#if 0
|
||||
static uintptr_t thread2_id = 0;
|
||||
static uintptr_t thread3_id = 0;
|
||||
#endif
|
||||
|
||||
|
||||
/* Thread 1 makes sure that async1_cb_called reaches 3 before exiting. */
|
||||
void thread1_entry(void *arg) {
|
||||
int state = 0;
|
||||
|
||||
uv_sleep(50);
|
||||
|
||||
while (1) {
|
||||
switch (async1_cb_called) {
|
||||
case 0:
|
||||
uv_async_send(&async1_handle);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
uv_async_send(&async1_handle);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
uv_async_send(&async1_handle);
|
||||
break;
|
||||
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* Thread 2 calls uv_async_send on async_handle_2 8 times. */
|
||||
void thread2_entry(void *arg) {
|
||||
int i;
|
||||
|
||||
while (1) {
|
||||
switch (async1_cb_called) {
|
||||
case 0:
|
||||
uv_async_send(&async2_handle);
|
||||
break;
|
||||
|
||||
case 1:
|
||||
uv_async_send(&async2_handle);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
uv_async_send(&async2_handle);
|
||||
break;
|
||||
}
|
||||
uv_sleep(5);
|
||||
}
|
||||
|
||||
if (async1_cb_called == 20) {
|
||||
uv_close(handle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Thread 3 calls uv_async_send on async_handle_2 8 times
|
||||
* after waiting half a second first.
|
||||
*/
|
||||
void thread3_entry(void *arg) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 8; i++) {
|
||||
uv_async_send(&async2_handle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void async1_cb(uv_handle_t* handle, int status) {
|
||||
ASSERT(handle == (uv_handle_t*)&async1_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
async1_cb_called++;
|
||||
printf("async1_cb #%d\n", async1_cb_called);
|
||||
|
||||
if (async1_cb_called > 2 && !async1_closed) {
|
||||
async1_closed = 1;
|
||||
uv_close(handle, close_cb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 0
|
||||
static void async2_cb(uv_handle_t* handle, int status) {
|
||||
ASSERT(handle == &async2_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
async2_cb_called++;
|
||||
printf("async2_cb #%d\n", async2_cb_called);
|
||||
|
||||
if (async2_cb_called == 16) {
|
||||
uv_close(handle);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void prepare_cb(uv_handle_t* handle, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&prepare_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
switch (prepare_cb_called) {
|
||||
case 0:
|
||||
thread1_id = uv_create_thread(thread1_entry, NULL);
|
||||
ASSERT(thread1_id != 0);
|
||||
break;
|
||||
|
||||
#if 0
|
||||
case 1:
|
||||
thread2_id = uv_create_thread(thread2_entry, NULL);
|
||||
ASSERT(thread2_id != 0);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
thread3_id = uv_create_thread(thread3_entry, NULL);
|
||||
ASSERT(thread3_id != 0);
|
||||
break;
|
||||
#endif
|
||||
|
||||
case 1:
|
||||
r = uv_close(handle, close_cb);
|
||||
ASSERT(r == 0);
|
||||
break;
|
||||
|
||||
default:
|
||||
FATAL("Should never get here");
|
||||
}
|
||||
|
||||
prepare_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(async) {
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_prepare_init(&prepare_handle);
|
||||
ASSERT(r == 0);
|
||||
r = uv_prepare_start(&prepare_handle, prepare_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_async_init(&async1_handle, async1_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
#if 0
|
||||
r = uv_async_init(&async2_handle, async2_cb, close_cb, NULL);
|
||||
ASSERT(r == 0);
|
||||
#endif
|
||||
|
||||
r = uv_run();
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_wait_thread(thread1_id);
|
||||
ASSERT(r == 0);
|
||||
#if 0
|
||||
r = uv_wait_thread(thread2_id);
|
||||
ASSERT(r == 0);
|
||||
r = uv_wait_thread(thread3_id);
|
||||
ASSERT(r == 0);
|
||||
#endif
|
||||
|
||||
ASSERT(prepare_cb_called == 2);
|
||||
ASSERT(async1_cb_called > 2);
|
||||
/* ASSERT(async2_cb_called = 16); */
|
||||
ASSERT(close_cb_called == 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
173
src/rt/libuv/test/test-bind-error.c
Normal file
173
src/rt/libuv/test/test-bind-error.c
Normal file
|
|
@ -0,0 +1,173 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
static int close_cb_called = 0;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(bind_error_addrinuse) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
|
||||
uv_tcp_t server1, server2;
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_tcp_init(&server1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server1, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_tcp_init(&server2);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server2, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_listen(&server1, 128, NULL);
|
||||
ASSERT(r == 0);
|
||||
r = uv_listen(&server2, 128, NULL);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EADDRINUSE);
|
||||
|
||||
uv_close((uv_handle_t*)&server1, close_cb);
|
||||
uv_close((uv_handle_t*)&server2, close_cb);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(close_cb_called == 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(bind_error_addrnotavail_1) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("127.255.255.255", TEST_PORT);
|
||||
uv_tcp_t server;
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr);
|
||||
|
||||
/* It seems that Linux is broken here - bind succeeds. */
|
||||
if (r == -1) {
|
||||
ASSERT(uv_last_error().code == UV_EADDRNOTAVAIL);
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*)&server, close_cb);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(bind_error_addrnotavail_2) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("4.4.4.4", TEST_PORT);
|
||||
uv_tcp_t server;
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr);
|
||||
ASSERT(r == -1);
|
||||
ASSERT(uv_last_error().code == UV_EADDRNOTAVAIL);
|
||||
|
||||
uv_close((uv_handle_t*)&server, close_cb);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(bind_error_fault) {
|
||||
char garbage[] = "blah blah blah blah blah blah blah blah blah blah blah blah";
|
||||
struct sockaddr_in* garbage_addr;
|
||||
uv_tcp_t server;
|
||||
int r;
|
||||
|
||||
garbage_addr = (struct sockaddr_in*) &garbage;
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, *garbage_addr);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EFAULT);
|
||||
|
||||
uv_close((uv_handle_t*)&server, close_cb);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Notes: On Linux uv_bind(server, NULL) will segfault the program. */
|
||||
|
||||
TEST_IMPL(bind_error_inval) {
|
||||
struct sockaddr_in addr1 = uv_ip4_addr("0.0.0.0", TEST_PORT);
|
||||
struct sockaddr_in addr2 = uv_ip4_addr("0.0.0.0", TEST_PORT_2);
|
||||
uv_tcp_t server;
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr2);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EINVAL);
|
||||
|
||||
uv_close((uv_handle_t*)&server, close_cb);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(close_cb_called == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
211
src/rt/libuv/test/test-callback-stack.c
Normal file
211
src/rt/libuv/test/test-callback-stack.c
Normal file
|
|
@ -0,0 +1,211 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* TODO: Add explanation of why we want on_close to be called from fresh
|
||||
* stack.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
static const char MESSAGE[] = "Failure is for the weak. Everyone dies alone.";
|
||||
|
||||
static uv_tcp_t client;
|
||||
static uv_timer_t timer;
|
||||
static uv_req_t connect_req, write_req, shutdown_req;
|
||||
|
||||
static int nested = 0;
|
||||
static int close_cb_called = 0;
|
||||
static int connect_cb_called = 0;
|
||||
static int write_cb_called = 0;
|
||||
static int timer_cb_called = 0;
|
||||
static int bytes_received = 0;
|
||||
static int shutdown_cb_called = 0;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.len = size;
|
||||
buf.base = (char*) malloc(size);
|
||||
ASSERT(buf.base);
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(nested == 0 && "close_cb must be called from a fresh stack");
|
||||
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void shutdown_cb(uv_req_t* req, int status) {
|
||||
ASSERT(status == 0);
|
||||
ASSERT(nested == 0 && "shutdown_cb must be called from a fresh stack");
|
||||
|
||||
shutdown_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
ASSERT(nested == 0 && "read_cb must be called from a fresh stack");
|
||||
|
||||
printf("Read. nread == %d\n", nread);
|
||||
free(buf.base);
|
||||
|
||||
if (nread == 0) {
|
||||
ASSERT(uv_last_error().code == UV_EAGAIN);
|
||||
return;
|
||||
|
||||
} else if (nread == -1) {
|
||||
ASSERT(uv_last_error().code == UV_EOF);
|
||||
|
||||
nested++;
|
||||
if (uv_close((uv_handle_t*)tcp, close_cb)) {
|
||||
FATAL("uv_close failed");
|
||||
}
|
||||
nested--;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
bytes_received += nread;
|
||||
|
||||
/* We call shutdown here because when bytes_received == sizeof MESSAGE */
|
||||
/* there will be no more data sent nor received, so here it would be */
|
||||
/* possible for a backend to to call shutdown_cb immediately and *not* */
|
||||
/* from a fresh stack. */
|
||||
if (bytes_received == sizeof MESSAGE) {
|
||||
nested++;
|
||||
uv_req_init(&shutdown_req, (uv_handle_t*)tcp, shutdown_cb);
|
||||
|
||||
puts("Shutdown");
|
||||
|
||||
if (uv_shutdown(&shutdown_req)) {
|
||||
FATAL("uv_shutdown failed");
|
||||
}
|
||||
nested--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void timer_cb(uv_handle_t* handle, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&timer);
|
||||
ASSERT(status == 0);
|
||||
ASSERT(nested == 0 && "timer_cb must be called from a fresh stack");
|
||||
|
||||
puts("Timeout complete. Now read data...");
|
||||
|
||||
nested++;
|
||||
if (uv_read_start(&client, alloc_cb, read_cb)) {
|
||||
FATAL("uv_read_start failed");
|
||||
}
|
||||
nested--;
|
||||
|
||||
timer_cb_called++;
|
||||
|
||||
r = uv_close(handle, close_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static void write_cb(uv_req_t* req, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(status == 0);
|
||||
ASSERT(nested == 0 && "write_cb must be called from a fresh stack");
|
||||
|
||||
puts("Data written. 500ms timeout...");
|
||||
|
||||
/* After the data has been sent, we're going to wait for a while, then */
|
||||
/* start reading. This makes us certain that the message has been echoed */
|
||||
/* back to our receive buffer when we start reading. This maximizes the */
|
||||
/* tempation for the backend to use dirty stack for calling read_cb. */
|
||||
nested++;
|
||||
r = uv_timer_init(&timer);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(&timer, timer_cb, 500, 0);
|
||||
ASSERT(r == 0);
|
||||
nested--;
|
||||
|
||||
write_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void connect_cb(uv_req_t* req, int status) {
|
||||
uv_buf_t buf;
|
||||
|
||||
puts("Connected. Write some data to echo server...");
|
||||
|
||||
ASSERT(status == 0);
|
||||
ASSERT(nested == 0 && "connect_cb must be called from a fresh stack");
|
||||
|
||||
nested++;
|
||||
|
||||
buf.base = (char*) &MESSAGE;
|
||||
buf.len = sizeof MESSAGE;
|
||||
|
||||
uv_req_init(&write_req, req->handle, write_cb);
|
||||
|
||||
if (uv_write(&write_req, &buf, 1)) {
|
||||
FATAL("uv_write failed");
|
||||
}
|
||||
|
||||
nested--;
|
||||
|
||||
connect_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(callback_stack) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
|
||||
uv_init();
|
||||
|
||||
if (uv_tcp_init(&client)) {
|
||||
FATAL("uv_tcp_init failed");
|
||||
}
|
||||
|
||||
puts("Connecting...");
|
||||
|
||||
nested++;
|
||||
uv_req_init(&connect_req, (uv_handle_t*)&client, connect_cb);
|
||||
if (uv_connect(&connect_req, addr)) {
|
||||
FATAL("uv_connect failed");
|
||||
}
|
||||
nested--;
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(nested == 0);
|
||||
ASSERT(connect_cb_called == 1 && "connect_cb must be called exactly once");
|
||||
ASSERT(write_cb_called == 1 && "write_cb must be called exactly once");
|
||||
ASSERT(timer_cb_called == 1 && "timer_cb must be called exactly once");
|
||||
ASSERT(bytes_received == sizeof MESSAGE);
|
||||
ASSERT(shutdown_cb_called == 1 && "shutdown_cb must be called exactly once");
|
||||
ASSERT(close_cb_called == 2 && "close_cb must be called exactly twice");
|
||||
|
||||
return 0;
|
||||
}
|
||||
151
src/rt/libuv/test/test-connection-fail.c
Normal file
151
src/rt/libuv/test/test-connection-fail.c
Normal file
|
|
@ -0,0 +1,151 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
static uv_tcp_t tcp;
|
||||
static uv_req_t req;
|
||||
static int connect_cb_calls;
|
||||
static int close_cb_calls;
|
||||
|
||||
static uv_timer_t timer;
|
||||
static int timer_close_cb_calls;
|
||||
static int timer_cb_calls;
|
||||
|
||||
|
||||
static void on_close(uv_handle_t* handle) {
|
||||
close_cb_calls++;
|
||||
}
|
||||
|
||||
|
||||
static void timer_close_cb(uv_handle_t* handle) {
|
||||
timer_close_cb_calls++;
|
||||
}
|
||||
|
||||
|
||||
static void timer_cb(uv_handle_t* handle, int status) {
|
||||
ASSERT(status == 0);
|
||||
timer_cb_calls++;
|
||||
|
||||
/*
|
||||
* These are the important asserts. The connection callback has been made,
|
||||
* but libuv hasn't automatically closed the socket. The user must
|
||||
* uv_close the handle manually.
|
||||
*/
|
||||
ASSERT(close_cb_calls == 0);
|
||||
ASSERT(connect_cb_calls == 1);
|
||||
|
||||
/* Close the tcp handle. */
|
||||
uv_close((uv_handle_t*)&tcp, on_close);
|
||||
|
||||
/* Close the timer. */
|
||||
uv_close(handle, timer_close_cb);
|
||||
}
|
||||
|
||||
|
||||
static void on_connect_with_close(uv_req_t *req, int status) {
|
||||
ASSERT(&tcp == (uv_tcp_t*) req->handle);
|
||||
ASSERT(status == -1);
|
||||
ASSERT(uv_last_error().code == UV_ECONNREFUSED);
|
||||
connect_cb_calls++;
|
||||
|
||||
ASSERT(close_cb_calls == 0);
|
||||
uv_close(req->handle, on_close);
|
||||
}
|
||||
|
||||
|
||||
static void on_connect_without_close(uv_req_t *req, int status) {
|
||||
ASSERT(status == -1);
|
||||
ASSERT(uv_last_error().code == UV_ECONNREFUSED);
|
||||
connect_cb_calls++;
|
||||
|
||||
uv_timer_start(&timer, timer_cb, 100, 0);
|
||||
|
||||
ASSERT(close_cb_calls == 0);
|
||||
}
|
||||
|
||||
|
||||
void connection_fail(uv_connect_cb connect_cb) {
|
||||
struct sockaddr_in client_addr, server_addr;
|
||||
int r;
|
||||
|
||||
client_addr = uv_ip4_addr("0.0.0.0", 0);
|
||||
|
||||
/* There should be no servers listening on this port. */
|
||||
server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
|
||||
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
|
||||
r = uv_tcp_init(&tcp);
|
||||
ASSERT(!r);
|
||||
|
||||
/* We are never doing multiple reads/connects at a time anyway. */
|
||||
/* so these handles can be pre-initialized. */
|
||||
uv_req_init(&req, (uv_handle_t*)&tcp, connect_cb);
|
||||
|
||||
uv_bind(&tcp, client_addr);
|
||||
r = uv_connect(&req, server_addr);
|
||||
ASSERT(!r);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(connect_cb_calls == 1);
|
||||
ASSERT(close_cb_calls == 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This test attempts to connect to a port where no server is running. We
|
||||
* expect an error.
|
||||
*/
|
||||
TEST_IMPL(connection_fail) {
|
||||
uv_init();
|
||||
|
||||
connection_fail(on_connect_with_close);
|
||||
|
||||
ASSERT(timer_close_cb_calls == 0);
|
||||
ASSERT(timer_cb_calls == 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This test is the same as the first except it check that the close
|
||||
* callback of the tcp handle hasn't been made after the failed connection
|
||||
* attempt.
|
||||
*/
|
||||
TEST_IMPL(connection_fail_doesnt_auto_close) {
|
||||
uv_init();
|
||||
|
||||
uv_timer_init(&timer);
|
||||
|
||||
connection_fail(on_connect_without_close);
|
||||
|
||||
ASSERT(timer_close_cb_calls == 1);
|
||||
ASSERT(timer_cb_calls == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
199
src/rt/libuv/test/test-delayed-accept.c
Normal file
199
src/rt/libuv/test/test-delayed-accept.c
Normal file
|
|
@ -0,0 +1,199 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static char BUFFER[1024];
|
||||
|
||||
static int connection_cb_called = 0;
|
||||
static int do_accept_called = 0;
|
||||
static int close_cb_called = 0;
|
||||
static int connect_cb_called = 0;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
free(handle);
|
||||
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void do_accept(uv_handle_t* timer_handle, int status) {
|
||||
uv_tcp_t* server;
|
||||
uv_tcp_t* accepted_handle = (uv_tcp_t*)malloc(sizeof *accepted_handle);
|
||||
int r;
|
||||
int tcpcnt;
|
||||
|
||||
ASSERT(timer_handle != NULL);
|
||||
ASSERT(status == 0);
|
||||
ASSERT(accepted_handle != NULL);
|
||||
|
||||
uv_tcp_init(accepted_handle);
|
||||
|
||||
/* Test to that uv_counters()->tcp_init does not increase across the uv_accept. */
|
||||
tcpcnt = uv_counters()->tcp_init;
|
||||
|
||||
server = (uv_tcp_t*)timer_handle->data;
|
||||
r = uv_accept(server, accepted_handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(uv_counters()->tcp_init == tcpcnt);
|
||||
|
||||
do_accept_called++;
|
||||
|
||||
/* Immediately close the accepted handle. */
|
||||
r = uv_close((uv_handle_t*)accepted_handle, close_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* After accepting the two clients close the server handle */
|
||||
if (do_accept_called == 2) {
|
||||
r = uv_close((uv_handle_t*)server, close_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
/* Dispose the timer. */
|
||||
r = uv_close(timer_handle, close_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static void connection_cb(uv_tcp_t* tcp, int status) {
|
||||
int r;
|
||||
uv_timer_t* timer_handle;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
timer_handle = (uv_timer_t*)malloc(sizeof *timer_handle);
|
||||
ASSERT(timer_handle != NULL);
|
||||
|
||||
/* Accept the client after 1 second */
|
||||
r = uv_timer_init(timer_handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
timer_handle->data = tcp;
|
||||
|
||||
r = uv_timer_start(timer_handle, do_accept, 1000, 0);
|
||||
ASSERT(r == 0);
|
||||
|
||||
connection_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void start_server() {
|
||||
struct sockaddr_in addr = uv_ip4_addr("0.0.0.0", TEST_PORT);
|
||||
uv_tcp_t* server = (uv_tcp_t*)malloc(sizeof *server);
|
||||
int r;
|
||||
|
||||
ASSERT(server != NULL);
|
||||
|
||||
r = uv_tcp_init(server);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_counters()->tcp_init == 1);
|
||||
ASSERT(uv_counters()->handle_init == 1);
|
||||
|
||||
r = uv_bind(server, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_listen(server, 128, connection_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
/* The server will not send anything, it should close gracefully. */
|
||||
ASSERT(tcp != NULL);
|
||||
ASSERT(nread == -1);
|
||||
ASSERT(uv_last_error().code == UV_EOF);
|
||||
|
||||
if (buf.base) {
|
||||
free(buf.base);
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*)tcp, close_cb);
|
||||
}
|
||||
|
||||
|
||||
static void connect_cb(uv_req_t* req, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT(status == 0);
|
||||
|
||||
/* Not that the server will send anything, but otherwise we'll never know */
|
||||
/* when te server closes the connection. */
|
||||
r = uv_read_start((uv_tcp_t*)(req->handle), alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
connect_cb_called++;
|
||||
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void client_connect() {
|
||||
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client);
|
||||
uv_req_t* connect_req = (uv_req_t*)malloc(sizeof *connect_req);
|
||||
int r;
|
||||
|
||||
ASSERT(client != NULL);
|
||||
ASSERT(connect_req != NULL);
|
||||
|
||||
r = uv_tcp_init(client);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_req_init(connect_req, (uv_handle_t*)client, connect_cb);
|
||||
r = uv_connect(connect_req, addr);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
TEST_IMPL(delayed_accept) {
|
||||
uv_init();
|
||||
|
||||
start_server();
|
||||
|
||||
client_connect();
|
||||
client_connect();
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(connection_cb_called == 2);
|
||||
ASSERT(do_accept_called == 2);
|
||||
ASSERT(connect_cb_called == 2);
|
||||
ASSERT(close_cb_called == 7);
|
||||
|
||||
return 0;
|
||||
}
|
||||
29
src/rt/libuv/test/test-fail-always.c
Normal file
29
src/rt/libuv/test/test-fail-always.c
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "task.h"
|
||||
|
||||
|
||||
TEST_IMPL(fail_always) {
|
||||
/* This test always fails. It is used to test the test runner. */
|
||||
FATAL("Yes, it always fails");
|
||||
return 2;
|
||||
}
|
||||
53
src/rt/libuv/test/test-get-currentexe.c
Normal file
53
src/rt/libuv/test/test-get-currentexe.c
Normal file
|
|
@ -0,0 +1,53 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
#include <string.h>
|
||||
|
||||
#define PATHMAX 1024
|
||||
extern char executable_path[];
|
||||
|
||||
TEST_IMPL(get_currentexe) {
|
||||
char buffer[PATHMAX];
|
||||
size_t size;
|
||||
char* match;
|
||||
int r;
|
||||
|
||||
size = sizeof(buffer) / sizeof(buffer[0]);
|
||||
r = uv_get_exepath(buffer, &size);
|
||||
ASSERT(!r);
|
||||
|
||||
match = strstr(buffer, executable_path);
|
||||
/* Verify that the path returned from uv_get_exepath is a subdirectory of executable_path */
|
||||
ASSERT(match && !strcmp(match, executable_path));
|
||||
ASSERT(size == strlen(buffer));
|
||||
|
||||
/* Negative tests */
|
||||
size = sizeof(buffer) / sizeof(buffer[0]);
|
||||
r = uv_get_exepath(NULL, &size);
|
||||
ASSERT(r == -1);
|
||||
|
||||
r = uv_get_exepath(buffer, NULL);
|
||||
ASSERT(r == -1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
98
src/rt/libuv/test/test-list.h
Normal file
98
src/rt/libuv/test/test-list.h
Normal file
|
|
@ -0,0 +1,98 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
TEST_DECLARE (ping_pong)
|
||||
TEST_DECLARE (delayed_accept)
|
||||
TEST_DECLARE (tcp_writealot)
|
||||
TEST_DECLARE (bind_error_addrinuse)
|
||||
TEST_DECLARE (bind_error_addrnotavail_1)
|
||||
TEST_DECLARE (bind_error_addrnotavail_2)
|
||||
TEST_DECLARE (bind_error_fault)
|
||||
TEST_DECLARE (bind_error_inval)
|
||||
TEST_DECLARE (connection_fail)
|
||||
TEST_DECLARE (connection_fail_doesnt_auto_close)
|
||||
TEST_DECLARE (shutdown_eof)
|
||||
TEST_DECLARE (callback_stack)
|
||||
TEST_DECLARE (timer)
|
||||
TEST_DECLARE (timer_again)
|
||||
TEST_DECLARE (loop_handles)
|
||||
TEST_DECLARE (ref)
|
||||
TEST_DECLARE (idle_ref)
|
||||
TEST_DECLARE (async_ref)
|
||||
TEST_DECLARE (prepare_ref)
|
||||
TEST_DECLARE (check_ref)
|
||||
TEST_DECLARE (async)
|
||||
TEST_DECLARE (get_currentexe)
|
||||
TEST_DECLARE (fail_always)
|
||||
TEST_DECLARE (pass_always)
|
||||
HELPER_DECLARE (echo_server)
|
||||
|
||||
TASK_LIST_START
|
||||
TEST_ENTRY (ping_pong)
|
||||
TEST_HELPER (ping_pong, echo_server)
|
||||
|
||||
TEST_ENTRY (delayed_accept)
|
||||
|
||||
TEST_ENTRY (tcp_writealot)
|
||||
TEST_HELPER (tcp_writealot, echo_server)
|
||||
|
||||
TEST_ENTRY (bind_error_addrinuse)
|
||||
|
||||
TEST_ENTRY (bind_error_addrnotavail_1)
|
||||
|
||||
TEST_ENTRY (bind_error_addrnotavail_2)
|
||||
|
||||
TEST_ENTRY (bind_error_fault)
|
||||
|
||||
TEST_ENTRY (bind_error_inval)
|
||||
|
||||
TEST_ENTRY (connection_fail)
|
||||
TEST_ENTRY (connection_fail_doesnt_auto_close)
|
||||
|
||||
TEST_ENTRY (shutdown_eof)
|
||||
TEST_HELPER (shutdown_eof, echo_server)
|
||||
|
||||
TEST_ENTRY (callback_stack)
|
||||
TEST_HELPER (callback_stack, echo_server)
|
||||
|
||||
TEST_ENTRY (timer)
|
||||
|
||||
TEST_ENTRY (timer_again)
|
||||
|
||||
TEST_ENTRY (ref)
|
||||
TEST_ENTRY (idle_ref)
|
||||
TEST_ENTRY (async_ref)
|
||||
TEST_ENTRY (prepare_ref)
|
||||
TEST_ENTRY (check_ref)
|
||||
|
||||
TEST_ENTRY (loop_handles)
|
||||
|
||||
TEST_ENTRY (async)
|
||||
|
||||
TEST_ENTRY (get_currentexe)
|
||||
|
||||
#if 0
|
||||
/* These are for testing the test runner. */
|
||||
TEST_ENTRY (fail_always)
|
||||
TEST_ENTRY (pass_always)
|
||||
#endif
|
||||
TASK_LIST_END
|
||||
|
||||
419
src/rt/libuv/test/test-loop-handles.c
Normal file
419
src/rt/libuv/test/test-loop-handles.c
Normal file
|
|
@ -0,0 +1,419 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
/* Tests commented out with XXX are ones that are failing on Linux */
|
||||
|
||||
/*
|
||||
* Purpose of this test is to check semantics of starting and stopping
|
||||
* prepare, check and idle watchers.
|
||||
*
|
||||
* - A watcher must be able to safely stop or close itself;
|
||||
* - Once a watcher is stopped or closed its callback should never be called.
|
||||
* - If a watcher is closed, it is implicitly stopped and its close_cb should
|
||||
* be called exactly once.
|
||||
* - A watcher can safely start and stop other watchers of the same type.
|
||||
* - Prepare and check watchers are called once per event loop iterations.
|
||||
* - All active idle watchers are queued when the event loop has no more work
|
||||
* to do. This is done repeatedly until all idle watchers are inactive.
|
||||
* - If a watcher starts another watcher of the same type its callback is not
|
||||
* immediately queued. For check and prepare watchers, that means that if
|
||||
* a watcher makes another of the same type active, it'll not be called until
|
||||
* the next event loop iteration. For idle. watchers this means that the
|
||||
* newly activated idle watcher might not be queued immediately.
|
||||
* - Prepare, check, idle watchers keep the event loop alive even when they're
|
||||
* not active.
|
||||
*
|
||||
* This is what the test globally does:
|
||||
*
|
||||
* - prepare_1 is always active and counts event loop iterations. It also
|
||||
* creates and starts prepare_2 every other iteration. Finally it verifies
|
||||
* that no idle watchers are active before polling.
|
||||
* - prepare_2 is started by prepare_1 every other iteration. It immediately
|
||||
* stops itself. It verifies that a watcher is not queued immediately
|
||||
* if created by another watcher of the same type.
|
||||
* - There's a check watcher that stops the event loop after a certain number
|
||||
* of iterations. It starts a varying number of idle_1 watchers.
|
||||
* - Idle_1 watchers stop themselves after being called a few times. All idle_1
|
||||
* watchers try to start the idle_2 watcher if it is not already started or
|
||||
* awaiting its close callback.
|
||||
* - The idle_2 watcher always exists but immediately closes itself after
|
||||
* being started by a check_1 watcher. It verifies that a watcher is
|
||||
* implicitly stopped when closed, and that a watcher can close itself
|
||||
* safely.
|
||||
* - There is a repeating timer. It does not keep te event loop alive
|
||||
* (ev_unref) but makes sure that the loop keeps polling the system for
|
||||
* events.
|
||||
*/
|
||||
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
|
||||
#define IDLE_COUNT 7
|
||||
#define ITERATIONS 21
|
||||
#define TIMEOUT 100
|
||||
|
||||
|
||||
static uv_prepare_t prepare_1_handle;
|
||||
static uv_prepare_t prepare_2_handle;
|
||||
|
||||
static uv_check_t check_handle;
|
||||
|
||||
static uv_idle_t idle_1_handles[IDLE_COUNT];
|
||||
static uv_idle_t idle_2_handle;
|
||||
|
||||
static uv_timer_t timer_handle;
|
||||
|
||||
|
||||
static int loop_iteration = 0;
|
||||
|
||||
static int prepare_1_cb_called = 0;
|
||||
static int prepare_1_close_cb_called = 0;
|
||||
|
||||
static int prepare_2_cb_called = 0;
|
||||
static int prepare_2_close_cb_called = 0;
|
||||
|
||||
static int check_cb_called = 0;
|
||||
static int check_close_cb_called = 0;
|
||||
|
||||
static int idle_1_cb_called = 0;
|
||||
static int idle_1_close_cb_called = 0;
|
||||
static int idles_1_active = 0;
|
||||
|
||||
static int idle_2_cb_called = 0;
|
||||
static int idle_2_close_cb_called = 0;
|
||||
static int idle_2_cb_started = 0;
|
||||
static int idle_2_is_active = 0;
|
||||
|
||||
static int timer_cb_called = 0;
|
||||
|
||||
|
||||
static void timer_cb(uv_handle_t* handle, int status) {
|
||||
ASSERT(handle == (uv_handle_t*)&timer_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
timer_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void idle_2_close_cb(uv_handle_t* handle) {
|
||||
LOG("IDLE_2_CLOSE_CB\n");
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&idle_2_handle);
|
||||
|
||||
ASSERT(idle_2_is_active);
|
||||
|
||||
idle_2_close_cb_called++;
|
||||
idle_2_is_active = 0;
|
||||
}
|
||||
|
||||
|
||||
static void idle_2_cb(uv_handle_t* handle, int status) {
|
||||
int r;
|
||||
|
||||
LOG("IDLE_2_CB\n");
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&idle_2_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
idle_2_cb_called++;
|
||||
|
||||
r = uv_close(handle, idle_2_close_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static void idle_1_cb(uv_handle_t* handle, int status) {
|
||||
int r;
|
||||
|
||||
LOG("IDLE_1_CB\n");
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT(status == 0);
|
||||
|
||||
ASSERT(idles_1_active > 0);
|
||||
|
||||
/* Init idle_2 and make it active */
|
||||
if (!idle_2_is_active) {
|
||||
r = uv_idle_init(&idle_2_handle);
|
||||
ASSERT(r == 0);
|
||||
r = uv_idle_start(&idle_2_handle, idle_2_cb);
|
||||
ASSERT(r == 0);
|
||||
idle_2_is_active = 1;
|
||||
idle_2_cb_started++;
|
||||
}
|
||||
|
||||
idle_1_cb_called++;
|
||||
|
||||
if (idle_1_cb_called % 5 == 0) {
|
||||
r = uv_idle_stop((uv_idle_t*)handle);
|
||||
ASSERT(r == 0);
|
||||
idles_1_active--;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void idle_1_close_cb(uv_handle_t* handle) {
|
||||
LOG("IDLE_1_CLOSE_CB\n");
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
idle_1_close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void prepare_1_close_cb(uv_handle_t* handle) {
|
||||
LOG("PREPARE_1_CLOSE_CB");
|
||||
ASSERT(handle == (uv_handle_t*)&prepare_1_handle);
|
||||
|
||||
prepare_1_close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void check_close_cb(uv_handle_t* handle) {
|
||||
LOG("CHECK_CLOSE_CB\n");
|
||||
ASSERT(handle == (uv_handle_t*)&check_handle);
|
||||
|
||||
check_close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void prepare_2_close_cb(uv_handle_t* handle) {
|
||||
LOG("PREPARE_2_CLOSE_CB\n");
|
||||
ASSERT(handle == (uv_handle_t*)&prepare_2_handle);
|
||||
|
||||
prepare_2_close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void check_cb(uv_handle_t* handle, int status) {
|
||||
int i, r;
|
||||
|
||||
LOG("CHECK_CB\n");
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&check_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
/* XXX
|
||||
ASSERT(idles_1_active == 0);
|
||||
ASSERT(idle_2_is_active == 0);
|
||||
*/
|
||||
|
||||
if (loop_iteration < ITERATIONS) {
|
||||
/* Make some idle watchers active */
|
||||
for (i = 0; i < 1 + (loop_iteration % IDLE_COUNT); i++) {
|
||||
r = uv_idle_start(&idle_1_handles[i], idle_1_cb);
|
||||
ASSERT(r == 0);
|
||||
idles_1_active++;
|
||||
}
|
||||
|
||||
} else {
|
||||
/* End of the test - close all handles */
|
||||
r = uv_close((uv_handle_t*)&prepare_1_handle, prepare_1_close_cb);
|
||||
ASSERT(r == 0);
|
||||
r = uv_close((uv_handle_t*)&check_handle, check_close_cb);
|
||||
ASSERT(r == 0);
|
||||
r = uv_close((uv_handle_t*)&prepare_2_handle, prepare_2_close_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
for (i = 0; i < IDLE_COUNT; i++) {
|
||||
r = uv_close((uv_handle_t*)&idle_1_handles[i], idle_1_close_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
/* This handle is closed/recreated every time, close it only if it is */
|
||||
/* active.*/
|
||||
if (idle_2_is_active) {
|
||||
r = uv_close((uv_handle_t*)&idle_2_handle, idle_2_close_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
}
|
||||
|
||||
check_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void prepare_2_cb(uv_handle_t* handle, int status) {
|
||||
int r;
|
||||
|
||||
LOG("PREPARE_2_CB\n");
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&prepare_2_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
/* XXX ASSERT(idles_1_active == 0); */
|
||||
/* XXX ASSERT(idle_2_is_active == 0); */
|
||||
|
||||
/* prepare_2 gets started by prepare_1 when (loop_iteration % 2 == 0), */
|
||||
/* and it stops itself immediately. A started watcher is not queued */
|
||||
/* until the next round, so when this callback is made */
|
||||
/* (loop_iteration % 2 == 0) cannot be true. */
|
||||
ASSERT(loop_iteration % 2 != 0);
|
||||
|
||||
r = uv_prepare_stop((uv_prepare_t*)handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
prepare_2_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void prepare_1_cb(uv_handle_t* handle, int status) {
|
||||
int r;
|
||||
|
||||
LOG("PREPARE_1_CB\n");
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&prepare_1_handle);
|
||||
ASSERT(status == 0);
|
||||
|
||||
/* XXX
|
||||
ASSERT(idles_1_active == 0);
|
||||
ASSERT(idle_2_is_active == 0);
|
||||
*/
|
||||
|
||||
if (loop_iteration % 2 == 0) {
|
||||
r = uv_prepare_start(&prepare_2_handle, prepare_2_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
prepare_1_cb_called++;
|
||||
loop_iteration++;
|
||||
|
||||
printf("Loop iteration %d of %d.\n", loop_iteration, ITERATIONS);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(loop_handles) {
|
||||
int i;
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_prepare_init(&prepare_1_handle);
|
||||
ASSERT(r == 0);
|
||||
r = uv_prepare_start(&prepare_1_handle, prepare_1_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_check_init(&check_handle);
|
||||
ASSERT(r == 0);
|
||||
r = uv_check_start(&check_handle, check_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* initialize only, prepare_2 is started by prepare_1_cb */
|
||||
r = uv_prepare_init(&prepare_2_handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
for (i = 0; i < IDLE_COUNT; i++) {
|
||||
/* initialize only, idle_1 handles are started by check_cb */
|
||||
r = uv_idle_init(&idle_1_handles[i]);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
/* don't init or start idle_2, both is done by idle_1_cb */
|
||||
|
||||
/* the timer callback is there to keep the event loop polling */
|
||||
/* unref it as it is not supposed to keep the loop alive */
|
||||
r = uv_timer_init(&timer_handle);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(&timer_handle, timer_cb, TIMEOUT, TIMEOUT);
|
||||
ASSERT(r == 0);
|
||||
uv_unref();
|
||||
|
||||
r = uv_run();
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(loop_iteration == ITERATIONS);
|
||||
|
||||
ASSERT(prepare_1_cb_called == ITERATIONS);
|
||||
ASSERT(prepare_1_close_cb_called == 1);
|
||||
|
||||
ASSERT(prepare_2_cb_called == floor(ITERATIONS / 2.0));
|
||||
ASSERT(prepare_2_close_cb_called == 1);
|
||||
|
||||
ASSERT(check_cb_called == ITERATIONS);
|
||||
ASSERT(check_close_cb_called == 1);
|
||||
|
||||
/* idle_1_cb should be called a lot */
|
||||
/* XXX ASSERT(idle_1_cb_called >= ITERATIONS * IDLE_COUNT * 2); */
|
||||
ASSERT(idle_1_close_cb_called == IDLE_COUNT);
|
||||
/* XXX ASSERT(idles_1_active == 0); */
|
||||
|
||||
/* XXX ASSERT(idle_2_cb_started >= ITERATIONS); */
|
||||
/* XXX ASSERT(idle_2_cb_called == idle_2_cb_started); */
|
||||
ASSERT(idle_2_close_cb_called == idle_2_cb_started);
|
||||
ASSERT(idle_2_is_active == 0);
|
||||
|
||||
ASSERT(timer_cb_called > 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(ref) {
|
||||
uv_init();
|
||||
uv_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(idle_ref) {
|
||||
uv_idle_t h;
|
||||
uv_init();
|
||||
uv_idle_init(&h);
|
||||
uv_idle_start(&h, NULL);
|
||||
uv_unref();
|
||||
uv_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(async_ref) {
|
||||
uv_async_t h;
|
||||
uv_init();
|
||||
uv_async_init(&h, NULL);
|
||||
uv_unref();
|
||||
uv_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(prepare_ref) {
|
||||
uv_prepare_t h;
|
||||
uv_init();
|
||||
uv_prepare_init(&h);
|
||||
uv_prepare_start(&h, NULL);
|
||||
uv_unref();
|
||||
uv_run();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(check_ref) {
|
||||
uv_check_t h;
|
||||
uv_init();
|
||||
uv_check_init(&h);
|
||||
uv_check_start(&h, NULL);
|
||||
uv_unref();
|
||||
uv_run();
|
||||
return 0;
|
||||
}
|
||||
28
src/rt/libuv/test/test-pass-always.c
Normal file
28
src/rt/libuv/test/test-pass-always.c
Normal file
|
|
@ -0,0 +1,28 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "task.h"
|
||||
|
||||
|
||||
TEST_IMPL(pass_always) {
|
||||
/* This test always passes. It is used to test the test runner. */
|
||||
return 0;
|
||||
}
|
||||
177
src/rt/libuv/test/test-ping-pong.c
Normal file
177
src/rt/libuv/test/test-ping-pong.c
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h> /* strlen */
|
||||
|
||||
static int completed_pingers = 0;
|
||||
|
||||
#define NUM_PINGS 1000
|
||||
|
||||
/* 64 bytes is enough for a pinger */
|
||||
#define BUFSIZE 10240
|
||||
|
||||
static char PING[] = "PING\n";
|
||||
|
||||
|
||||
typedef struct {
|
||||
int pongs;
|
||||
int state;
|
||||
uv_tcp_t tcp;
|
||||
uv_req_t connect_req;
|
||||
uv_req_t read_req;
|
||||
char read_buffer[BUFSIZE];
|
||||
} pinger_t;
|
||||
|
||||
void pinger_try_read(pinger_t* pinger);
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void pinger_on_close(uv_handle_t* handle) {
|
||||
pinger_t* pinger = (pinger_t*)handle->data;
|
||||
|
||||
ASSERT(NUM_PINGS == pinger->pongs);
|
||||
|
||||
free(pinger);
|
||||
|
||||
completed_pingers++;
|
||||
}
|
||||
|
||||
|
||||
static void pinger_after_write(uv_req_t *req, int status) {
|
||||
ASSERT(status == 0);
|
||||
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void pinger_write_ping(pinger_t* pinger) {
|
||||
uv_req_t *req;
|
||||
uv_buf_t buf;
|
||||
|
||||
buf.base = (char*)&PING;
|
||||
buf.len = strlen(PING);
|
||||
|
||||
req = (uv_req_t*)malloc(sizeof(*req));
|
||||
uv_req_init(req, (uv_handle_t*)(&pinger->tcp), pinger_after_write);
|
||||
|
||||
if (uv_write(req, &buf, 1)) {
|
||||
FATAL("uv_write failed");
|
||||
}
|
||||
|
||||
puts("PING");
|
||||
}
|
||||
|
||||
|
||||
static void pinger_read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
unsigned int i;
|
||||
pinger_t* pinger;
|
||||
|
||||
pinger = (pinger_t*)tcp->data;
|
||||
|
||||
if (nread < 0) {
|
||||
ASSERT(uv_last_error().code == UV_EOF);
|
||||
|
||||
puts("got EOF");
|
||||
|
||||
if (buf.base) {
|
||||
free(buf.base);
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*)(&pinger->tcp), pinger_on_close);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/* Now we count the pings */
|
||||
for (i = 0; i < nread; i++) {
|
||||
ASSERT(buf.base[i] == PING[pinger->state]);
|
||||
pinger->state = (pinger->state + 1) % (sizeof(PING) - 1);
|
||||
if (pinger->state == 0) {
|
||||
printf("PONG %d\n", pinger->pongs);
|
||||
pinger->pongs++;
|
||||
if (pinger->pongs < NUM_PINGS) {
|
||||
pinger_write_ping(pinger);
|
||||
} else {
|
||||
uv_close((uv_handle_t*)(&pinger->tcp), pinger_on_close);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void pinger_on_connect(uv_req_t *req, int status) {
|
||||
pinger_t *pinger = (pinger_t*)req->handle->data;
|
||||
|
||||
ASSERT(status == 0);
|
||||
|
||||
pinger_write_ping(pinger);
|
||||
|
||||
uv_read_start((uv_tcp_t*)(req->handle), alloc_cb, pinger_read_cb);
|
||||
}
|
||||
|
||||
|
||||
static void pinger_new() {
|
||||
int r;
|
||||
struct sockaddr_in server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
pinger_t *pinger;
|
||||
|
||||
pinger = (pinger_t*)malloc(sizeof(*pinger));
|
||||
pinger->state = 0;
|
||||
pinger->pongs = 0;
|
||||
|
||||
/* Try to connec to the server and do NUM_PINGS ping-pongs. */
|
||||
r = uv_tcp_init(&pinger->tcp);
|
||||
pinger->tcp.data = pinger;
|
||||
ASSERT(!r);
|
||||
|
||||
/* We are never doing multiple reads/connects at a time anyway. */
|
||||
/* so these handles can be pre-initialized. */
|
||||
uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->tcp),
|
||||
pinger_on_connect);
|
||||
|
||||
r = uv_connect(&pinger->connect_req, server_addr);
|
||||
ASSERT(!r);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(ping_pong) {
|
||||
uv_init();
|
||||
|
||||
pinger_new();
|
||||
uv_run();
|
||||
|
||||
ASSERT(completed_pingers == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
176
src/rt/libuv/test/test-shutdown-eof.c
Normal file
176
src/rt/libuv/test/test-shutdown-eof.c
Normal file
|
|
@ -0,0 +1,176 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
static uv_timer_t timer;
|
||||
static uv_tcp_t tcp;
|
||||
static uv_req_t connect_req, write_req, shutdown_req;
|
||||
static uv_buf_t qbuf;
|
||||
static int got_q;
|
||||
static int got_eof;
|
||||
static int called_connect_cb;
|
||||
static int called_shutdown_cb;
|
||||
static int called_tcp_close_cb;
|
||||
static int called_timer_close_cb;
|
||||
static int called_timer_cb;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* t, ssize_t nread, uv_buf_t buf) {
|
||||
ASSERT(t == &tcp);
|
||||
|
||||
if (!got_q) {
|
||||
ASSERT(nread == 1);
|
||||
ASSERT(!got_eof);
|
||||
ASSERT(buf.base[0] == 'Q');
|
||||
free(buf.base);
|
||||
got_q = 1;
|
||||
puts("got Q");
|
||||
} else {
|
||||
ASSERT(uv_last_error().code == UV_EOF);
|
||||
if (buf.base) {
|
||||
free(buf.base);
|
||||
}
|
||||
got_eof = 1;
|
||||
puts("got EOF");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void shutdown_cb(uv_req_t *req, int status) {
|
||||
ASSERT(req == &shutdown_req);
|
||||
|
||||
ASSERT(called_connect_cb == 1);
|
||||
ASSERT(!got_eof);
|
||||
ASSERT(called_tcp_close_cb == 0);
|
||||
ASSERT(called_timer_close_cb == 0);
|
||||
ASSERT(called_timer_cb == 0);
|
||||
|
||||
called_shutdown_cb++;
|
||||
}
|
||||
|
||||
|
||||
static void connect_cb(uv_req_t *req, int status) {
|
||||
ASSERT(status == 0);
|
||||
ASSERT(req == &connect_req);
|
||||
|
||||
/* Start reading from our connection so we can receive the EOF. */
|
||||
uv_read_start(&tcp, alloc_cb, read_cb);
|
||||
|
||||
/*
|
||||
* Write the letter 'Q' to gracefully kill the echo-server. This will not
|
||||
* effect our connection.
|
||||
*/
|
||||
uv_req_init(&write_req, (uv_handle_t*)&tcp, NULL);
|
||||
uv_write(&write_req, &qbuf, 1);
|
||||
|
||||
/* Shutdown our end of the connection. */
|
||||
uv_req_init(&shutdown_req, (uv_handle_t*)&tcp, shutdown_cb);
|
||||
uv_shutdown(&shutdown_req);
|
||||
|
||||
called_connect_cb++;
|
||||
ASSERT(called_shutdown_cb == 0);
|
||||
}
|
||||
|
||||
|
||||
void tcp_close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle == (uv_handle_t*) &tcp);
|
||||
|
||||
ASSERT(called_connect_cb == 1);
|
||||
ASSERT(got_q);
|
||||
ASSERT(got_eof);
|
||||
ASSERT(called_timer_cb == 1);
|
||||
|
||||
called_tcp_close_cb++;
|
||||
}
|
||||
|
||||
|
||||
void timer_close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle == (uv_handle_t*) &timer);
|
||||
called_timer_close_cb++;
|
||||
}
|
||||
|
||||
|
||||
void timer_cb(uv_handle_t* handle, int status) {
|
||||
ASSERT(handle == (uv_handle_t*) &timer);
|
||||
uv_close(handle, timer_close_cb);
|
||||
|
||||
/*
|
||||
* The most important assert of the test: we have not received
|
||||
* tcp_close_cb yet.
|
||||
*/
|
||||
ASSERT(called_tcp_close_cb == 0);
|
||||
uv_close((uv_handle_t*) &tcp, tcp_close_cb);
|
||||
|
||||
called_timer_cb++;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* This test has a client which connects to the echo_server and immediately
|
||||
* issues a shutdown. The echo-server, in response, will also shutdown their
|
||||
* connection. We check, with a timer, that libuv is not automatically
|
||||
* calling uv_close when the client receives the EOF from echo-server.
|
||||
*/
|
||||
TEST_IMPL(shutdown_eof) {
|
||||
struct sockaddr_in server_addr;
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
qbuf.base = "Q";
|
||||
qbuf.len = 1;
|
||||
|
||||
uv_timer_init(&timer);
|
||||
uv_timer_start(&timer, timer_cb, 100, 0);
|
||||
|
||||
server_addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
r = uv_tcp_init(&tcp);
|
||||
ASSERT(!r);
|
||||
|
||||
uv_req_init(&connect_req, (uv_handle_t*) &tcp, connect_cb);
|
||||
r = uv_connect(&connect_req, server_addr);
|
||||
ASSERT(!r);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(called_connect_cb == 1);
|
||||
ASSERT(called_shutdown_cb == 1);
|
||||
ASSERT(got_eof);
|
||||
ASSERT(got_q);
|
||||
ASSERT(called_tcp_close_cb == 1);
|
||||
ASSERT(called_timer_close_cb == 1);
|
||||
ASSERT(called_timer_cb == 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
202
src/rt/libuv/test/test-tcp-writealot.c
Normal file
202
src/rt/libuv/test/test-tcp-writealot.c
Normal file
|
|
@ -0,0 +1,202 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
#define WRITES 3
|
||||
#define CHUNKS_PER_WRITE 3
|
||||
#define CHUNK_SIZE 10485760 /* 10 MB */
|
||||
|
||||
#define TOTAL_BYTES (WRITES * CHUNKS_PER_WRITE * CHUNK_SIZE)
|
||||
|
||||
|
||||
static char* send_buffer;
|
||||
|
||||
|
||||
static int shutdown_cb_called = 0;
|
||||
static int connect_cb_called = 0;
|
||||
static int write_cb_called = 0;
|
||||
static int close_cb_called = 0;
|
||||
static int bytes_sent = 0;
|
||||
static int bytes_sent_done = 0;
|
||||
static int bytes_received = 0;
|
||||
static int bytes_received_done = 0;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
free(handle);
|
||||
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void shutdown_cb(uv_req_t* req, int status) {
|
||||
uv_tcp_t* tcp;
|
||||
|
||||
ASSERT(req);
|
||||
ASSERT(status == 0);
|
||||
|
||||
tcp = (uv_tcp_t*)(req->handle);
|
||||
|
||||
/* The write buffer should be empty by now. */
|
||||
ASSERT(tcp->write_queue_size == 0);
|
||||
|
||||
/* Now we wait for the EOF */
|
||||
shutdown_cb_called++;
|
||||
|
||||
/* We should have had all the writes called already. */
|
||||
ASSERT(write_cb_called == WRITES);
|
||||
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
ASSERT(tcp != NULL);
|
||||
|
||||
if (nread < 0) {
|
||||
ASSERT(uv_last_error().code == UV_EOF);
|
||||
printf("GOT EOF\n");
|
||||
|
||||
if (buf.base) {
|
||||
free(buf.base);
|
||||
}
|
||||
|
||||
uv_close((uv_handle_t*)tcp, close_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
bytes_received_done += nread;
|
||||
|
||||
free(buf.base);
|
||||
}
|
||||
|
||||
|
||||
static void write_cb(uv_req_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
|
||||
if (status) {
|
||||
uv_err_t err = uv_last_error();
|
||||
fprintf(stderr, "uv_write error: %s\n", uv_strerror(err));
|
||||
ASSERT(0);
|
||||
}
|
||||
|
||||
bytes_sent_done += CHUNKS_PER_WRITE * CHUNK_SIZE;
|
||||
write_cb_called++;
|
||||
|
||||
free(req);
|
||||
}
|
||||
|
||||
|
||||
static void connect_cb(uv_req_t* req, int status) {
|
||||
uv_buf_t send_bufs[CHUNKS_PER_WRITE];
|
||||
uv_tcp_t* tcp;
|
||||
int i, j, r;
|
||||
|
||||
ASSERT(req != NULL);
|
||||
ASSERT(status == 0);
|
||||
|
||||
tcp = (uv_tcp_t*)req->handle;
|
||||
|
||||
connect_cb_called++;
|
||||
free(req);
|
||||
|
||||
/* Write a lot of data */
|
||||
for (i = 0; i < WRITES; i++) {
|
||||
for (j = 0; j < CHUNKS_PER_WRITE; j++) {
|
||||
send_bufs[j].len = CHUNK_SIZE;
|
||||
send_bufs[j].base = send_buffer + bytes_sent;
|
||||
bytes_sent += CHUNK_SIZE;
|
||||
}
|
||||
|
||||
req = (uv_req_t*)malloc(sizeof *req);
|
||||
ASSERT(req != NULL);
|
||||
|
||||
uv_req_init(req, (uv_handle_t*)tcp, write_cb);
|
||||
r = uv_write(req, (uv_buf_t*)&send_bufs, CHUNKS_PER_WRITE);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
/* Shutdown on drain. FIXME: dealloc req? */
|
||||
req = (uv_req_t*) malloc(sizeof(uv_req_t));
|
||||
ASSERT(req != NULL);
|
||||
uv_req_init(req, (uv_handle_t*)tcp, shutdown_cb);
|
||||
r = uv_shutdown(req);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* Start reading */
|
||||
req = (uv_req_t*)malloc(sizeof *req);
|
||||
ASSERT(req != NULL);
|
||||
|
||||
uv_req_init(req, (uv_handle_t*)tcp, read_cb);
|
||||
r = uv_read_start(tcp, alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(tcp_writealot) {
|
||||
struct sockaddr_in addr = uv_ip4_addr("127.0.0.1", TEST_PORT);
|
||||
uv_tcp_t* client = (uv_tcp_t*)malloc(sizeof *client);
|
||||
uv_req_t* connect_req = (uv_req_t*)malloc(sizeof *connect_req);
|
||||
int r;
|
||||
|
||||
ASSERT(client != NULL);
|
||||
ASSERT(connect_req != NULL);
|
||||
|
||||
send_buffer = (char*)malloc(TOTAL_BYTES + 1);
|
||||
|
||||
ASSERT(send_buffer != NULL);
|
||||
|
||||
uv_init();
|
||||
|
||||
r = uv_tcp_init(client);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_req_init(connect_req, (uv_handle_t*)client, connect_cb);
|
||||
r = uv_connect(connect_req, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(shutdown_cb_called == 1);
|
||||
ASSERT(connect_cb_called == 1);
|
||||
ASSERT(write_cb_called == WRITES);
|
||||
ASSERT(close_cb_called == 1);
|
||||
ASSERT(bytes_sent == TOTAL_BYTES);
|
||||
ASSERT(bytes_sent_done == TOTAL_BYTES);
|
||||
ASSERT(bytes_received_done == TOTAL_BYTES);
|
||||
|
||||
return 0;
|
||||
}
|
||||
141
src/rt/libuv/test/test-timer-again.c
Normal file
141
src/rt/libuv/test/test-timer-again.c
Normal file
|
|
@ -0,0 +1,141 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
static int close_cb_called = 0;
|
||||
static int repeat_1_cb_called = 0;
|
||||
static int repeat_2_cb_called = 0;
|
||||
|
||||
static int repeat_2_cb_allowed = 0;
|
||||
|
||||
static uv_timer_t dummy, repeat_1, repeat_2;
|
||||
|
||||
static int64_t start_time;
|
||||
|
||||
|
||||
static void close_cb(uv_handle_t* handle) {
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void repeat_1_cb(uv_handle_t* handle, int status) {
|
||||
int r;
|
||||
|
||||
ASSERT(handle == (uv_handle_t*)&repeat_1);
|
||||
ASSERT(status == 0);
|
||||
|
||||
ASSERT(uv_timer_get_repeat((uv_timer_t*)handle) == 50);
|
||||
|
||||
LOGF("repeat_1_cb called after %ld ms\n", (long int)(uv_now() - start_time));
|
||||
|
||||
repeat_1_cb_called++;
|
||||
|
||||
r = uv_timer_again(&repeat_2);
|
||||
ASSERT(r == 0);
|
||||
|
||||
if (uv_now() >= start_time + 500) {
|
||||
uv_close(handle, close_cb);
|
||||
/* We're not calling uv_timer_again on repeat_2 any more, so after this */
|
||||
/* timer_2_cb is expected. */
|
||||
repeat_2_cb_allowed = 1;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void repeat_2_cb(uv_handle_t* handle, int status) {
|
||||
ASSERT(handle == (uv_handle_t*) &repeat_2);
|
||||
ASSERT(status == 0);
|
||||
ASSERT(repeat_2_cb_allowed);
|
||||
|
||||
LOGF("repeat_2_cb called after %ld ms\n", (long int)(uv_now() - start_time));
|
||||
|
||||
repeat_2_cb_called++;
|
||||
|
||||
if (uv_timer_get_repeat(&repeat_2) == 0) {
|
||||
ASSERT(!uv_is_active(handle));
|
||||
uv_close(handle, close_cb);
|
||||
return;
|
||||
}
|
||||
|
||||
LOGF("uv_timer_get_repeat %ld ms\n",
|
||||
(long int)uv_timer_get_repeat(&repeat_2));
|
||||
ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
|
||||
|
||||
/* This shouldn't take effect immediately. */
|
||||
uv_timer_set_repeat(&repeat_2, 0);
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(timer_again) {
|
||||
int r;
|
||||
|
||||
uv_init();
|
||||
|
||||
start_time = uv_now();
|
||||
ASSERT(0 < start_time);
|
||||
|
||||
/* Verify that it is not possible to uv_timer_again a never-started timer. */
|
||||
r = uv_timer_init(&dummy);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_again(&dummy);
|
||||
ASSERT(r == -1);
|
||||
ASSERT(uv_last_error().code == UV_EINVAL);
|
||||
uv_unref();
|
||||
|
||||
/* Start timer repeat_1. */
|
||||
r = uv_timer_init(&repeat_1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(&repeat_1, repeat_1_cb, 50, 0);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_timer_get_repeat(&repeat_1) == 0);
|
||||
|
||||
/* Actually make repeat_1 repeating. */
|
||||
uv_timer_set_repeat(&repeat_1, 50);
|
||||
ASSERT(uv_timer_get_repeat(&repeat_1) == 50);
|
||||
|
||||
/*
|
||||
* Start another repeating timer. It'll be again()ed by the repeat_1 so
|
||||
* it should not time out until repeat_1 stops.
|
||||
*/
|
||||
r = uv_timer_init(&repeat_2);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(&repeat_2, repeat_2_cb, 100, 100);
|
||||
ASSERT(r == 0);
|
||||
ASSERT(uv_timer_get_repeat(&repeat_2) == 100);
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(repeat_1_cb_called == 10);
|
||||
ASSERT(repeat_2_cb_called == 2);
|
||||
ASSERT(close_cb_called == 2);
|
||||
|
||||
LOGF("Test took %ld ms (expected ~700 ms)\n",
|
||||
(long int)(uv_now() - start_time));
|
||||
ASSERT(700 <= uv_now() - start_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
134
src/rt/libuv/test/test-timer.c
Normal file
134
src/rt/libuv/test/test-timer.c
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "../uv.h"
|
||||
#include "task.h"
|
||||
|
||||
|
||||
static int once_cb_called = 0;
|
||||
static int once_close_cb_called = 0;
|
||||
static int repeat_cb_called = 0;
|
||||
static int repeat_close_cb_called = 0;
|
||||
|
||||
static int64_t start_time;
|
||||
|
||||
|
||||
static void once_close_cb(uv_handle_t* handle) {
|
||||
printf("ONCE_CLOSE_CB\n");
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
once_close_cb_called++;
|
||||
|
||||
free(handle);
|
||||
}
|
||||
|
||||
|
||||
static void once_cb(uv_handle_t* handle, int status) {
|
||||
printf("ONCE_CB %d\n", once_cb_called);
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT(status == 0);
|
||||
|
||||
once_cb_called++;
|
||||
|
||||
uv_close(handle, once_close_cb);
|
||||
|
||||
/* Just call this randomly for the code coverage. */
|
||||
uv_update_time();
|
||||
}
|
||||
|
||||
|
||||
static void repeat_close_cb(uv_handle_t* handle) {
|
||||
printf("REPEAT_CLOSE_CB\n");
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
|
||||
repeat_close_cb_called++;
|
||||
}
|
||||
|
||||
|
||||
static void repeat_cb(uv_handle_t* handle, int status) {
|
||||
printf("REPEAT_CB\n");
|
||||
|
||||
ASSERT(handle != NULL);
|
||||
ASSERT(status == 0);
|
||||
|
||||
repeat_cb_called++;
|
||||
|
||||
if (repeat_cb_called == 5) {
|
||||
uv_close(handle, repeat_close_cb);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void never_cb(uv_handle_t* handle, int status) {
|
||||
FATAL("never_cb should never be called");
|
||||
}
|
||||
|
||||
|
||||
TEST_IMPL(timer) {
|
||||
uv_timer_t *once;
|
||||
uv_timer_t repeat, never;
|
||||
int i, r;
|
||||
|
||||
uv_init();
|
||||
|
||||
start_time = uv_now();
|
||||
ASSERT(0 < start_time);
|
||||
|
||||
/* Let 10 timers time out in 500 ms total. */
|
||||
for (i = 0; i < 10; i++) {
|
||||
once = (uv_timer_t*)malloc(sizeof(*once));
|
||||
ASSERT(once != NULL);
|
||||
r = uv_timer_init(once);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(once, once_cb, i * 50, 0);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
/* The 11th timer is a repeating timer that runs 4 times */
|
||||
r = uv_timer_init(&repeat);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(&repeat, repeat_cb, 100, 100);
|
||||
ASSERT(r == 0);
|
||||
|
||||
/* The 12th timer should not do anything. */
|
||||
r = uv_timer_init(&never);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_start(&never, never_cb, 100, 100);
|
||||
ASSERT(r == 0);
|
||||
r = uv_timer_stop(&never);
|
||||
ASSERT(r == 0);
|
||||
uv_unref();
|
||||
|
||||
uv_run();
|
||||
|
||||
ASSERT(once_cb_called == 10);
|
||||
ASSERT(once_close_cb_called == 10);
|
||||
printf("repeat_cb_called %d\n", repeat_cb_called);
|
||||
ASSERT(repeat_cb_called == 5);
|
||||
ASSERT(repeat_close_cb_called == 1);
|
||||
|
||||
ASSERT(500 <= uv_now() - start_time);
|
||||
|
||||
return 0;
|
||||
}
|
||||
762
src/rt/libuv/tree.h
Normal file
762
src/rt/libuv/tree.h
Normal file
|
|
@ -0,0 +1,762 @@
|
|||
/*-
|
||||
* Copyright 2002 Niels Provos <provos@citi.umich.edu>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, 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 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
|
||||
* INCIDENTAL, SPECIAL, 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 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _UV_TREE_H_
|
||||
#define _UV_TREE_H_
|
||||
|
||||
#define __unused
|
||||
|
||||
/*
|
||||
* This file defines data structures for different types of trees:
|
||||
* splay trees and red-black trees.
|
||||
*
|
||||
* A splay tree is a self-organizing data structure. Every operation
|
||||
* on the tree causes a splay to happen. The splay moves the requested
|
||||
* node to the root of the tree and partly rebalances it.
|
||||
*
|
||||
* This has the benefit that request locality causes faster lookups as
|
||||
* the requested nodes move to the top of the tree. On the other hand,
|
||||
* every lookup causes memory writes.
|
||||
*
|
||||
* The Balance Theorem bounds the total access time for m operations
|
||||
* and n inserts on an initially empty tree as O((m + n)lg n). The
|
||||
* amortized cost for a sequence of m accesses to a splay tree is O(lg n);
|
||||
*
|
||||
* A red-black tree is a binary search tree with the node color as an
|
||||
* extra attribute. It fulfills a set of conditions:
|
||||
* - every search path from the root to a leaf consists of the
|
||||
* same number of black nodes,
|
||||
* - each red node (except for the root) has a black parent,
|
||||
* - each leaf node is black.
|
||||
*
|
||||
* Every operation on a red-black tree is bounded as O(lg n).
|
||||
* The maximum height of a red-black tree is 2lg (n+1).
|
||||
*/
|
||||
|
||||
#define SPLAY_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *sph_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define SPLAY_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define SPLAY_INIT(root) do { \
|
||||
(root)->sph_root = NULL; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *spe_left; /* left element */ \
|
||||
struct type *spe_right; /* right element */ \
|
||||
}
|
||||
|
||||
#define SPLAY_LEFT(elm, field) (elm)->field.spe_left
|
||||
#define SPLAY_RIGHT(elm, field) (elm)->field.spe_right
|
||||
#define SPLAY_ROOT(head) (head)->sph_root
|
||||
#define SPLAY_EMPTY(head) (SPLAY_ROOT(head) == NULL)
|
||||
|
||||
/* SPLAY_ROTATE_{LEFT,RIGHT} expect that tmp hold SPLAY_{RIGHT,LEFT} */
|
||||
#define SPLAY_ROTATE_RIGHT(head, tmp, field) do { \
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(tmp, field); \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_ROTATE_LEFT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(tmp, field); \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
(head)->sph_root = tmp; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_LINKLEFT(head, tmp, field) do { \
|
||||
SPLAY_LEFT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_LINKRIGHT(head, tmp, field) do { \
|
||||
SPLAY_RIGHT(tmp, field) = (head)->sph_root; \
|
||||
tmp = (head)->sph_root; \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define SPLAY_ASSEMBLE(head, node, left, right, field) do { \
|
||||
SPLAY_RIGHT(left, field) = SPLAY_LEFT((head)->sph_root, field); \
|
||||
SPLAY_LEFT(right, field) = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
SPLAY_LEFT((head)->sph_root, field) = SPLAY_RIGHT(node, field); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = SPLAY_LEFT(node, field); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
|
||||
#define SPLAY_PROTOTYPE(name, type, field, cmp) \
|
||||
void name##_SPLAY(struct name *, struct type *); \
|
||||
void name##_SPLAY_MINMAX(struct name *, int); \
|
||||
struct type *name##_SPLAY_INSERT(struct name *, struct type *); \
|
||||
struct type *name##_SPLAY_REMOVE(struct name *, struct type *); \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return(NULL); \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) \
|
||||
return (head->sph_root); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_NEXT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
name##_SPLAY(head, elm); \
|
||||
if (SPLAY_RIGHT(elm, field) != NULL) { \
|
||||
elm = SPLAY_RIGHT(elm, field); \
|
||||
while (SPLAY_LEFT(elm, field) != NULL) { \
|
||||
elm = SPLAY_LEFT(elm, field); \
|
||||
} \
|
||||
} else \
|
||||
elm = NULL; \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
static __inline struct type * \
|
||||
name##_SPLAY_MIN_MAX(struct name *head, int val) \
|
||||
{ \
|
||||
name##_SPLAY_MINMAX(head, val); \
|
||||
return (SPLAY_ROOT(head)); \
|
||||
}
|
||||
|
||||
/* Main splay operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define SPLAY_GENERATE(name, type, field, cmp) \
|
||||
struct type * \
|
||||
name##_SPLAY_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
if (SPLAY_EMPTY(head)) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_RIGHT(elm, field) = NULL; \
|
||||
} else { \
|
||||
int __comp; \
|
||||
name##_SPLAY(head, elm); \
|
||||
__comp = (cmp)(elm, (head)->sph_root); \
|
||||
if(__comp < 0) { \
|
||||
SPLAY_LEFT(elm, field) = SPLAY_LEFT((head)->sph_root, field); \
|
||||
SPLAY_RIGHT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_LEFT((head)->sph_root, field) = NULL; \
|
||||
} else if (__comp > 0) { \
|
||||
SPLAY_RIGHT(elm, field) = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
SPLAY_LEFT(elm, field) = (head)->sph_root; \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = NULL; \
|
||||
} else \
|
||||
return ((head)->sph_root); \
|
||||
} \
|
||||
(head)->sph_root = (elm); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
struct type * \
|
||||
name##_SPLAY_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *__tmp; \
|
||||
if (SPLAY_EMPTY(head)) \
|
||||
return (NULL); \
|
||||
name##_SPLAY(head, elm); \
|
||||
if ((cmp)(elm, (head)->sph_root) == 0) { \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) { \
|
||||
(head)->sph_root = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
} else { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
(head)->sph_root = SPLAY_LEFT((head)->sph_root, field); \
|
||||
name##_SPLAY(head, elm); \
|
||||
SPLAY_RIGHT((head)->sph_root, field) = __tmp; \
|
||||
} \
|
||||
return (elm); \
|
||||
} \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
void \
|
||||
name##_SPLAY(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
int __comp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while ((__comp = (cmp)(elm, (head)->sph_root)) != 0) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if ((cmp)(elm, __tmp) > 0){ \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
} \
|
||||
\
|
||||
/* Splay with either the minimum or the maximum element \
|
||||
* Used to find minimum or maximum element in tree. \
|
||||
*/ \
|
||||
void name##_SPLAY_MINMAX(struct name *head, int __comp) \
|
||||
{ \
|
||||
struct type __node, *__left, *__right, *__tmp; \
|
||||
\
|
||||
SPLAY_LEFT(&__node, field) = SPLAY_RIGHT(&__node, field) = NULL; \
|
||||
__left = __right = &__node; \
|
||||
\
|
||||
while (1) { \
|
||||
if (__comp < 0) { \
|
||||
__tmp = SPLAY_LEFT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp < 0){ \
|
||||
SPLAY_ROTATE_RIGHT(head, __tmp, field); \
|
||||
if (SPLAY_LEFT((head)->sph_root, field) == NULL) \
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKLEFT(head, __right, field); \
|
||||
} else if (__comp > 0) { \
|
||||
__tmp = SPLAY_RIGHT((head)->sph_root, field); \
|
||||
if (__tmp == NULL) \
|
||||
break; \
|
||||
if (__comp > 0) { \
|
||||
SPLAY_ROTATE_LEFT(head, __tmp, field); \
|
||||
if (SPLAY_RIGHT((head)->sph_root, field) == NULL) \
|
||||
break; \
|
||||
} \
|
||||
SPLAY_LINKRIGHT(head, __left, field); \
|
||||
} \
|
||||
} \
|
||||
SPLAY_ASSEMBLE(head, &__node, __left, __right, field); \
|
||||
}
|
||||
|
||||
#define SPLAY_NEGINF -1
|
||||
#define SPLAY_INF 1
|
||||
|
||||
#define SPLAY_INSERT(name, x, y) name##_SPLAY_INSERT(x, y)
|
||||
#define SPLAY_REMOVE(name, x, y) name##_SPLAY_REMOVE(x, y)
|
||||
#define SPLAY_FIND(name, x, y) name##_SPLAY_FIND(x, y)
|
||||
#define SPLAY_NEXT(name, x, y) name##_SPLAY_NEXT(x, y)
|
||||
#define SPLAY_MIN(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_NEGINF))
|
||||
#define SPLAY_MAX(name, x) (SPLAY_EMPTY(x) ? NULL \
|
||||
: name##_SPLAY_MIN_MAX(x, SPLAY_INF))
|
||||
|
||||
#define SPLAY_FOREACH(x, name, head) \
|
||||
for ((x) = SPLAY_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = SPLAY_NEXT(name, head, x))
|
||||
|
||||
/* Macros that define a red-black tree */
|
||||
#define RB_HEAD(name, type) \
|
||||
struct name { \
|
||||
struct type *rbh_root; /* root of the tree */ \
|
||||
}
|
||||
|
||||
#define RB_INITIALIZER(root) \
|
||||
{ NULL }
|
||||
|
||||
#define RB_INIT(root) do { \
|
||||
(root)->rbh_root = NULL; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define RB_BLACK 0
|
||||
#define RB_RED 1
|
||||
#define RB_ENTRY(type) \
|
||||
struct { \
|
||||
struct type *rbe_left; /* left element */ \
|
||||
struct type *rbe_right; /* right element */ \
|
||||
struct type *rbe_parent; /* parent element */ \
|
||||
int rbe_color; /* node color */ \
|
||||
}
|
||||
|
||||
#define RB_LEFT(elm, field) (elm)->field.rbe_left
|
||||
#define RB_RIGHT(elm, field) (elm)->field.rbe_right
|
||||
#define RB_PARENT(elm, field) (elm)->field.rbe_parent
|
||||
#define RB_COLOR(elm, field) (elm)->field.rbe_color
|
||||
#define RB_ROOT(head) (head)->rbh_root
|
||||
#define RB_EMPTY(head) (RB_ROOT(head) == NULL)
|
||||
|
||||
#define RB_SET(elm, parent, field) do { \
|
||||
RB_PARENT(elm, field) = parent; \
|
||||
RB_LEFT(elm, field) = RB_RIGHT(elm, field) = NULL; \
|
||||
RB_COLOR(elm, field) = RB_RED; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define RB_SET_BLACKRED(black, red, field) do { \
|
||||
RB_COLOR(black, field) = RB_BLACK; \
|
||||
RB_COLOR(red, field) = RB_RED; \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#ifndef RB_AUGMENT
|
||||
#define RB_AUGMENT(x) do {} while (0)
|
||||
#endif
|
||||
|
||||
#define RB_ROTATE_LEFT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_RIGHT(elm, field); \
|
||||
if ((RB_RIGHT(elm, field) = RB_LEFT(tmp, field)) != NULL) { \
|
||||
RB_PARENT(RB_LEFT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_LEFT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
#define RB_ROTATE_RIGHT(head, elm, tmp, field) do { \
|
||||
(tmp) = RB_LEFT(elm, field); \
|
||||
if ((RB_LEFT(elm, field) = RB_RIGHT(tmp, field)) != NULL) { \
|
||||
RB_PARENT(RB_RIGHT(tmp, field), field) = (elm); \
|
||||
} \
|
||||
RB_AUGMENT(elm); \
|
||||
if ((RB_PARENT(tmp, field) = RB_PARENT(elm, field)) != NULL) { \
|
||||
if ((elm) == RB_LEFT(RB_PARENT(elm, field), field)) \
|
||||
RB_LEFT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(elm, field), field) = (tmp); \
|
||||
} else \
|
||||
(head)->rbh_root = (tmp); \
|
||||
RB_RIGHT(tmp, field) = (elm); \
|
||||
RB_PARENT(elm, field) = (tmp); \
|
||||
RB_AUGMENT(tmp); \
|
||||
if ((RB_PARENT(tmp, field))) \
|
||||
RB_AUGMENT(RB_PARENT(tmp, field)); \
|
||||
} while (/*CONSTCOND*/ 0)
|
||||
|
||||
/* Generates prototypes and inline functions */
|
||||
#define RB_PROTOTYPE(name, type, field, cmp) \
|
||||
RB_PROTOTYPE_INTERNAL(name, type, field, cmp,)
|
||||
#define RB_PROTOTYPE_STATIC(name, type, field, cmp) \
|
||||
RB_PROTOTYPE_INTERNAL(name, type, field, cmp, __unused static)
|
||||
#define RB_PROTOTYPE_INTERNAL(name, type, field, cmp, attr) \
|
||||
attr void name##_RB_INSERT_COLOR(struct name *, struct type *); \
|
||||
attr void name##_RB_REMOVE_COLOR(struct name *, struct type *, struct type *);\
|
||||
attr struct type *name##_RB_REMOVE(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_INSERT(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_FIND(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_NFIND(struct name *, struct type *); \
|
||||
attr struct type *name##_RB_NEXT(struct type *); \
|
||||
attr struct type *name##_RB_PREV(struct type *); \
|
||||
attr struct type *name##_RB_MINMAX(struct name *, int); \
|
||||
\
|
||||
|
||||
/* Main rb operation.
|
||||
* Moves node close to the key of elm to top
|
||||
*/
|
||||
#define RB_GENERATE(name, type, field, cmp) \
|
||||
RB_GENERATE_INTERNAL(name, type, field, cmp,)
|
||||
#define RB_GENERATE_STATIC(name, type, field, cmp) \
|
||||
RB_GENERATE_INTERNAL(name, type, field, cmp, __unused static)
|
||||
#define RB_GENERATE_INTERNAL(name, type, field, cmp, attr) \
|
||||
attr void \
|
||||
name##_RB_INSERT_COLOR(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *parent, *gparent, *tmp; \
|
||||
while ((parent = RB_PARENT(elm, field)) != NULL && \
|
||||
RB_COLOR(parent, field) == RB_RED) { \
|
||||
gparent = RB_PARENT(parent, field); \
|
||||
if (parent == RB_LEFT(gparent, field)) { \
|
||||
tmp = RB_RIGHT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_RIGHT(parent, field) == elm) { \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field); \
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_RIGHT(head, gparent, tmp, field); \
|
||||
} else { \
|
||||
tmp = RB_LEFT(gparent, field); \
|
||||
if (tmp && RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_COLOR(tmp, field) = RB_BLACK; \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
elm = gparent; \
|
||||
continue; \
|
||||
} \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field); \
|
||||
tmp = parent; \
|
||||
parent = elm; \
|
||||
elm = tmp; \
|
||||
} \
|
||||
RB_SET_BLACKRED(parent, gparent, field); \
|
||||
RB_ROTATE_LEFT(head, gparent, tmp, field); \
|
||||
} \
|
||||
} \
|
||||
RB_COLOR(head->rbh_root, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
attr void \
|
||||
name##_RB_REMOVE_COLOR(struct name *head, struct type *parent, \
|
||||
struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
while ((elm == NULL || RB_COLOR(elm, field) == RB_BLACK) && \
|
||||
elm != RB_ROOT(head)) { \
|
||||
if (RB_LEFT(parent, field) == elm) { \
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field); \
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK) { \
|
||||
struct type *oleft; \
|
||||
if ((oleft = RB_LEFT(tmp, field)) \
|
||||
!= NULL) \
|
||||
RB_COLOR(oleft, field) = RB_BLACK; \
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_RIGHT(head, tmp, oleft, field); \
|
||||
tmp = RB_RIGHT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_RIGHT(tmp, field)) \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) = RB_BLACK; \
|
||||
RB_ROTATE_LEFT(head, parent, tmp, field); \
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} else { \
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
if (RB_COLOR(tmp, field) == RB_RED) { \
|
||||
RB_SET_BLACKRED(tmp, parent, field); \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field); \
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
if ((RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) && \
|
||||
(RB_RIGHT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_RIGHT(tmp, field), field) == RB_BLACK)) { \
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
elm = parent; \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
} else { \
|
||||
if (RB_LEFT(tmp, field) == NULL || \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) == RB_BLACK) { \
|
||||
struct type *oright; \
|
||||
if ((oright = RB_RIGHT(tmp, field)) \
|
||||
!= NULL) \
|
||||
RB_COLOR(oright, field) = RB_BLACK; \
|
||||
RB_COLOR(tmp, field) = RB_RED; \
|
||||
RB_ROTATE_LEFT(head, tmp, oright, field); \
|
||||
tmp = RB_LEFT(parent, field); \
|
||||
} \
|
||||
RB_COLOR(tmp, field) = RB_COLOR(parent, field); \
|
||||
RB_COLOR(parent, field) = RB_BLACK; \
|
||||
if (RB_LEFT(tmp, field)) \
|
||||
RB_COLOR(RB_LEFT(tmp, field), field) = RB_BLACK; \
|
||||
RB_ROTATE_RIGHT(head, parent, tmp, field); \
|
||||
elm = RB_ROOT(head); \
|
||||
break; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (elm) \
|
||||
RB_COLOR(elm, field) = RB_BLACK; \
|
||||
} \
|
||||
\
|
||||
attr struct type * \
|
||||
name##_RB_REMOVE(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *child, *parent, *old = elm; \
|
||||
int color; \
|
||||
if (RB_LEFT(elm, field) == NULL) \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
else if (RB_RIGHT(elm, field) == NULL) \
|
||||
child = RB_LEFT(elm, field); \
|
||||
else { \
|
||||
struct type *left; \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while ((left = RB_LEFT(elm, field)) != NULL) \
|
||||
elm = left; \
|
||||
child = RB_RIGHT(elm, field); \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
if (RB_PARENT(elm, field) == old) \
|
||||
parent = elm; \
|
||||
(elm)->field = (old)->field; \
|
||||
if (RB_PARENT(old, field)) { \
|
||||
if (RB_LEFT(RB_PARENT(old, field), field) == old) \
|
||||
RB_LEFT(RB_PARENT(old, field), field) = elm; \
|
||||
else \
|
||||
RB_RIGHT(RB_PARENT(old, field), field) = elm; \
|
||||
RB_AUGMENT(RB_PARENT(old, field)); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
RB_PARENT(RB_LEFT(old, field), field) = elm; \
|
||||
if (RB_RIGHT(old, field)) \
|
||||
RB_PARENT(RB_RIGHT(old, field), field) = elm; \
|
||||
if (parent) { \
|
||||
left = parent; \
|
||||
do { \
|
||||
RB_AUGMENT(left); \
|
||||
} while ((left = RB_PARENT(left, field)) != NULL); \
|
||||
} \
|
||||
goto color; \
|
||||
} \
|
||||
parent = RB_PARENT(elm, field); \
|
||||
color = RB_COLOR(elm, field); \
|
||||
if (child) \
|
||||
RB_PARENT(child, field) = parent; \
|
||||
if (parent) { \
|
||||
if (RB_LEFT(parent, field) == elm) \
|
||||
RB_LEFT(parent, field) = child; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = child; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = child; \
|
||||
color: \
|
||||
if (color == RB_BLACK) \
|
||||
name##_RB_REMOVE_COLOR(head, parent, child); \
|
||||
return (old); \
|
||||
} \
|
||||
\
|
||||
/* Inserts a node into the RB tree */ \
|
||||
attr struct type * \
|
||||
name##_RB_INSERT(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp; \
|
||||
struct type *parent = NULL; \
|
||||
int comp = 0; \
|
||||
tmp = RB_ROOT(head); \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
comp = (cmp)(elm, parent); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
RB_SET(elm, parent, field); \
|
||||
if (parent != NULL) { \
|
||||
if (comp < 0) \
|
||||
RB_LEFT(parent, field) = elm; \
|
||||
else \
|
||||
RB_RIGHT(parent, field) = elm; \
|
||||
RB_AUGMENT(parent); \
|
||||
} else \
|
||||
RB_ROOT(head) = elm; \
|
||||
name##_RB_INSERT_COLOR(head, elm); \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
/* Finds the node with the same key as elm */ \
|
||||
attr struct type * \
|
||||
name##_RB_FIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
int comp; \
|
||||
while (tmp) { \
|
||||
comp = cmp(elm, tmp); \
|
||||
if (comp < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
return (NULL); \
|
||||
} \
|
||||
\
|
||||
/* Finds the first node greater than or equal to the search key */ \
|
||||
attr struct type * \
|
||||
name##_RB_NFIND(struct name *head, struct type *elm) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
struct type *res = NULL; \
|
||||
int comp; \
|
||||
while (tmp) { \
|
||||
comp = cmp(elm, tmp); \
|
||||
if (comp < 0) { \
|
||||
res = tmp; \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
} \
|
||||
else if (comp > 0) \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
else \
|
||||
return (tmp); \
|
||||
} \
|
||||
return (res); \
|
||||
} \
|
||||
\
|
||||
/* ARGSUSED */ \
|
||||
attr struct type * \
|
||||
name##_RB_NEXT(struct type *elm) \
|
||||
{ \
|
||||
if (RB_RIGHT(elm, field)) { \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
while (RB_LEFT(elm, field)) \
|
||||
elm = RB_LEFT(elm, field); \
|
||||
} else { \
|
||||
if (RB_PARENT(elm, field) && \
|
||||
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
else { \
|
||||
while (RB_PARENT(elm, field) && \
|
||||
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
} \
|
||||
} \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
/* ARGSUSED */ \
|
||||
attr struct type * \
|
||||
name##_RB_PREV(struct type *elm) \
|
||||
{ \
|
||||
if (RB_LEFT(elm, field)) { \
|
||||
elm = RB_LEFT(elm, field); \
|
||||
while (RB_RIGHT(elm, field)) \
|
||||
elm = RB_RIGHT(elm, field); \
|
||||
} else { \
|
||||
if (RB_PARENT(elm, field) && \
|
||||
(elm == RB_RIGHT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
else { \
|
||||
while (RB_PARENT(elm, field) && \
|
||||
(elm == RB_LEFT(RB_PARENT(elm, field), field))) \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
elm = RB_PARENT(elm, field); \
|
||||
} \
|
||||
} \
|
||||
return (elm); \
|
||||
} \
|
||||
\
|
||||
attr struct type * \
|
||||
name##_RB_MINMAX(struct name *head, int val) \
|
||||
{ \
|
||||
struct type *tmp = RB_ROOT(head); \
|
||||
struct type *parent = NULL; \
|
||||
while (tmp) { \
|
||||
parent = tmp; \
|
||||
if (val < 0) \
|
||||
tmp = RB_LEFT(tmp, field); \
|
||||
else \
|
||||
tmp = RB_RIGHT(tmp, field); \
|
||||
} \
|
||||
return (parent); \
|
||||
}
|
||||
|
||||
#define RB_NEGINF -1
|
||||
#define RB_INF 1
|
||||
|
||||
#define RB_INSERT(name, x, y) name##_RB_INSERT(x, y)
|
||||
#define RB_REMOVE(name, x, y) name##_RB_REMOVE(x, y)
|
||||
#define RB_FIND(name, x, y) name##_RB_FIND(x, y)
|
||||
#define RB_NFIND(name, x, y) name##_RB_NFIND(x, y)
|
||||
#define RB_NEXT(name, x, y) name##_RB_NEXT(y)
|
||||
#define RB_PREV(name, x, y) name##_RB_PREV(y)
|
||||
#define RB_MIN(name, x) name##_RB_MINMAX(x, RB_NEGINF)
|
||||
#define RB_MAX(name, x) name##_RB_MINMAX(x, RB_INF)
|
||||
|
||||
#define RB_FOREACH(x, name, head) \
|
||||
for ((x) = RB_MIN(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = name##_RB_NEXT(x))
|
||||
|
||||
#define RB_FOREACH_FROM(x, name, y) \
|
||||
for ((x) = (y); \
|
||||
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#define RB_FOREACH_SAFE(x, name, head, y) \
|
||||
for ((x) = RB_MIN(name, head); \
|
||||
((x) != NULL) && ((y) = name##_RB_NEXT(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#define RB_FOREACH_REVERSE(x, name, head) \
|
||||
for ((x) = RB_MAX(name, head); \
|
||||
(x) != NULL; \
|
||||
(x) = name##_RB_PREV(x))
|
||||
|
||||
#define RB_FOREACH_REVERSE_FROM(x, name, y) \
|
||||
for ((x) = (y); \
|
||||
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#define RB_FOREACH_REVERSE_SAFE(x, name, head, y) \
|
||||
for ((x) = RB_MAX(name, head); \
|
||||
((x) != NULL) && ((y) = name##_RB_PREV(x), (x) != NULL); \
|
||||
(x) = (y))
|
||||
|
||||
#endif /* _UV_TREE_H_ */
|
||||
77
src/rt/libuv/uv-common.c
Normal file
77
src/rt/libuv/uv-common.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include "uv.h"
|
||||
|
||||
#include <assert.h>
|
||||
#include <stddef.h> /* NULL */
|
||||
|
||||
|
||||
static uv_counters_t counters;
|
||||
|
||||
|
||||
uv_counters_t* const uv_counters() {
|
||||
return &counters;
|
||||
}
|
||||
|
||||
|
||||
const char* uv_err_name(uv_err_t err) {
|
||||
switch (err.code) {
|
||||
case UV_UNKNOWN: return "UNKNOWN";
|
||||
case UV_OK: return "OK";
|
||||
case UV_EOF: return "EOF";
|
||||
case UV_EACCESS: return "EACCESS";
|
||||
case UV_EAGAIN: return "EAGAIN";
|
||||
case UV_EADDRINUSE: return "EADDRINUSE";
|
||||
case UV_EADDRNOTAVAIL: return "EADDRNOTAVAIL";
|
||||
case UV_EAFNOSUPPORT: return "EAFNOSUPPORT";
|
||||
case UV_EALREADY: return "EALREADY";
|
||||
case UV_EBADF: return "EBADF";
|
||||
case UV_EBUSY: return "EBUSY";
|
||||
case UV_ECONNABORTED: return "ECONNABORTED";
|
||||
case UV_ECONNREFUSED: return "ECONNREFUSED";
|
||||
case UV_ECONNRESET: return "ECONNRESET";
|
||||
case UV_EDESTADDRREQ: return "EDESTADDRREQ";
|
||||
case UV_EFAULT: return "EFAULT";
|
||||
case UV_EHOSTUNREACH: return "EHOSTUNREACH";
|
||||
case UV_EINTR: return "EINTR";
|
||||
case UV_EINVAL: return "EINVAL";
|
||||
case UV_EISCONN: return "EISCONN";
|
||||
case UV_EMFILE: return "EMFILE";
|
||||
case UV_ENETDOWN: return "ENETDOWN";
|
||||
case UV_ENETUNREACH: return "ENETUNREACH";
|
||||
case UV_ENFILE: return "ENFILE";
|
||||
case UV_ENOBUFS: return "ENOBUFS";
|
||||
case UV_ENOMEM: return "ENOMEM";
|
||||
case UV_ENONET: return "ENONET";
|
||||
case UV_ENOPROTOOPT: return "ENOPROTOOPT";
|
||||
case UV_ENOTCONN: return "ENOTCONN";
|
||||
case UV_ENOTSOCK: return "ENOTSOCK";
|
||||
case UV_ENOTSUP: return "ENOTSUP";
|
||||
case UV_EPROTO: return "EPROTO";
|
||||
case UV_EPROTONOSUPPORT: return "EPROTONOSUPPORT";
|
||||
case UV_EPROTOTYPE: return "EPROTOTYPE";
|
||||
case UV_ETIMEDOUT: return "ETIMEDOUT";
|
||||
default:
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
1301
src/rt/libuv/uv-unix.c
Normal file
1301
src/rt/libuv/uv-unix.c
Normal file
File diff suppressed because it is too large
Load diff
100
src/rt/libuv/uv-unix.h
Normal file
100
src/rt/libuv/uv-unix.h
Normal file
|
|
@ -0,0 +1,100 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UV_UNIX_H
|
||||
#define UV_UNIX_H
|
||||
|
||||
#include "ngx-queue.h"
|
||||
|
||||
#include "ev/ev.h"
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
|
||||
/* Note: May be cast to struct iovec. See writev(2). */
|
||||
typedef struct {
|
||||
char* base;
|
||||
size_t len;
|
||||
} uv_buf_t;
|
||||
|
||||
|
||||
#define UV_REQ_PRIVATE_FIELDS \
|
||||
int write_index; \
|
||||
ev_timer timer; \
|
||||
ngx_queue_t queue; \
|
||||
uv_buf_t* bufs; \
|
||||
int bufcnt;
|
||||
|
||||
|
||||
/* TODO: union or classes please! */
|
||||
#define UV_HANDLE_PRIVATE_FIELDS \
|
||||
int fd; \
|
||||
int flags; \
|
||||
ev_idle next_watcher;
|
||||
|
||||
|
||||
/* UV_TCP */
|
||||
#define UV_TCP_PRIVATE_FIELDS \
|
||||
int delayed_error; \
|
||||
uv_read_cb read_cb; \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
uv_connection_cb connection_cb; \
|
||||
int accepted_fd; \
|
||||
uv_req_t *connect_req; \
|
||||
uv_req_t *shutdown_req; \
|
||||
ev_io read_watcher; \
|
||||
ev_io write_watcher; \
|
||||
ngx_queue_t write_queue;
|
||||
|
||||
|
||||
/* UV_PREPARE */ \
|
||||
#define UV_PREPARE_PRIVATE_FIELDS \
|
||||
ev_prepare prepare_watcher; \
|
||||
uv_loop_cb prepare_cb;
|
||||
|
||||
|
||||
/* UV_CHECK */
|
||||
#define UV_CHECK_PRIVATE_FIELDS \
|
||||
ev_check check_watcher; \
|
||||
uv_loop_cb check_cb;
|
||||
|
||||
|
||||
/* UV_IDLE */
|
||||
#define UV_IDLE_PRIVATE_FIELDS \
|
||||
ev_idle idle_watcher; \
|
||||
uv_loop_cb idle_cb;
|
||||
|
||||
|
||||
/* UV_ASYNC */
|
||||
#define UV_ASYNC_PRIVATE_FIELDS \
|
||||
ev_async async_watcher; \
|
||||
uv_loop_cb async_cb;
|
||||
|
||||
|
||||
/* UV_TIMER */
|
||||
#define UV_TIMER_PRIVATE_FIELDS \
|
||||
ev_timer timer_watcher; \
|
||||
uv_loop_cb timer_cb;
|
||||
|
||||
|
||||
#endif /* UV_UNIX_H */
|
||||
1766
src/rt/libuv/uv-win.c
Normal file
1766
src/rt/libuv/uv-win.c
Normal file
File diff suppressed because it is too large
Load diff
112
src/rt/libuv/uv-win.h
Normal file
112
src/rt/libuv/uv-win.h
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef _WIN32_WINNT
|
||||
# define _WIN32_WINNT 0x0501
|
||||
#endif
|
||||
|
||||
#include <stdint.h>
|
||||
#include <winsock2.h>
|
||||
#include <mswsock.h>
|
||||
#include <ws2tcpip.h>
|
||||
#include <windows.h>
|
||||
|
||||
#include "tree.h"
|
||||
|
||||
|
||||
/**
|
||||
* It should be possible to cast uv_buf_t[] to WSABUF[]
|
||||
* see http://msdn.microsoft.com/en-us/library/ms741542(v=vs.85).aspx
|
||||
*/
|
||||
typedef struct uv_buf_t {
|
||||
ULONG len;
|
||||
char* base;
|
||||
} uv_buf_t;
|
||||
|
||||
#define UV_REQ_PRIVATE_FIELDS \
|
||||
union { \
|
||||
/* Used by I/O operations */ \
|
||||
struct { \
|
||||
OVERLAPPED overlapped; \
|
||||
size_t queued_bytes; \
|
||||
}; \
|
||||
}; \
|
||||
int flags; \
|
||||
uv_err_t error; \
|
||||
struct uv_req_s* next_req;
|
||||
|
||||
#define uv_tcp_connection_fields \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
uv_read_cb read_cb; \
|
||||
struct uv_req_s read_req; \
|
||||
unsigned int write_reqs_pending; \
|
||||
uv_req_t* shutdown_req;
|
||||
|
||||
#define uv_tcp_server_fields \
|
||||
uv_connection_cb connection_cb; \
|
||||
SOCKET accept_socket; \
|
||||
struct uv_req_s accept_req; \
|
||||
char accept_buffer[sizeof(struct sockaddr_storage) * 2 + 32];
|
||||
|
||||
#define UV_TCP_PRIVATE_FIELDS \
|
||||
unsigned int reqs_pending; \
|
||||
union { \
|
||||
SOCKET socket; \
|
||||
HANDLE handle; \
|
||||
}; \
|
||||
union { \
|
||||
struct { uv_tcp_connection_fields }; \
|
||||
struct { uv_tcp_server_fields }; \
|
||||
};
|
||||
|
||||
#define UV_TIMER_PRIVATE_FIELDS \
|
||||
RB_ENTRY(uv_timer_s) tree_entry; \
|
||||
int64_t due; \
|
||||
int64_t repeat; \
|
||||
uv_loop_cb timer_cb;
|
||||
|
||||
#define UV_LOOP_PRIVATE_FIELDS \
|
||||
uv_handle_t* loop_prev; \
|
||||
uv_handle_t* loop_next; \
|
||||
uv_loop_cb loop_cb;
|
||||
|
||||
#define UV_ASYNC_PRIVATE_FIELDS \
|
||||
struct uv_req_s async_req; \
|
||||
/* char to avoid alignment issues */ \
|
||||
char volatile async_sent;
|
||||
|
||||
#define UV_PREPARE_PRIVATE_FIELDS /* empty */
|
||||
#define UV_CHECK_PRIVATE_FIELDS /* empty */
|
||||
#define UV_IDLE_PRIVATE_FIELDS /* empty */
|
||||
|
||||
/*
|
||||
* TODO: remove UV_LOOP_PRIVATE_FIELDS from UV_HANDLE_PRIVATE_FIELDS and
|
||||
* use it in UV_(PREPARE|CHECK|IDLE)_PRIVATE_FIELDS instead.
|
||||
*/
|
||||
|
||||
#define UV_HANDLE_PRIVATE_FIELDS \
|
||||
uv_handle_t* endgame_next; \
|
||||
unsigned int flags; \
|
||||
uv_err_t error; \
|
||||
UV_LOOP_PRIVATE_FIELDS
|
||||
|
||||
|
||||
int uv_utf16_to_utf8(wchar_t* utf16Buffer, size_t utf16Size, char* utf8Buffer, size_t utf8Size);
|
||||
394
src/rt/libuv/uv.h
Normal file
394
src/rt/libuv/uv.h
Normal file
|
|
@ -0,0 +1,394 @@
|
|||
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
|
||||
*
|
||||
* 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
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||
* IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef UV_H
|
||||
#define UV_H
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define UV_VERSION_MAJOR 0
|
||||
#define UV_VERSION_MINOR 1
|
||||
|
||||
#include <stdint.h> /* int64_t */
|
||||
#include <sys/types.h> /* size_t */
|
||||
|
||||
#ifndef ssize_t
|
||||
typedef intptr_t ssize_t;
|
||||
#endif
|
||||
|
||||
typedef struct uv_err_s uv_err_t;
|
||||
typedef struct uv_handle_s uv_handle_t;
|
||||
typedef struct uv_tcp_s uv_tcp_t;
|
||||
typedef struct uv_timer_s uv_timer_t;
|
||||
typedef struct uv_prepare_s uv_prepare_t;
|
||||
typedef struct uv_check_s uv_check_t;
|
||||
typedef struct uv_idle_s uv_idle_t;
|
||||
typedef struct uv_req_s uv_req_t;
|
||||
|
||||
|
||||
#if defined(__unix__) || defined(__POSIX__) || defined(__APPLE__)
|
||||
# include "uv-unix.h"
|
||||
#else
|
||||
# include "uv-win.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* The status parameter is 0 if the request completed successfully,
|
||||
* and should be -1 if the request was cancelled or failed.
|
||||
* For uv_close_cb, -1 means that the handle was closed due to an error.
|
||||
* Error details can be obtained by calling uv_last_error().
|
||||
*
|
||||
* In the case of uv_read_cb the uv_buf_t returned should be freed by the
|
||||
* user.
|
||||
*/
|
||||
typedef uv_buf_t (*uv_alloc_cb)(uv_tcp_t* tcp, size_t suggested_size);
|
||||
typedef void (*uv_read_cb)(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf);
|
||||
typedef void (*uv_write_cb)(uv_req_t* req, int status);
|
||||
typedef void (*uv_connect_cb)(uv_req_t* req, int status);
|
||||
typedef void (*uv_shutdown_cb)(uv_req_t* req, int status);
|
||||
typedef void (*uv_connection_cb)(uv_tcp_t* server, int status);
|
||||
typedef void (*uv_close_cb)(uv_handle_t* handle);
|
||||
/* TODO: do loop_cb and async_cb really need a status argument? */
|
||||
typedef void (*uv_loop_cb)(uv_handle_t* handle, int status);
|
||||
typedef void (*uv_async_cb)(uv_handle_t* handle, int status);
|
||||
|
||||
|
||||
/* Expand this list if necessary. */
|
||||
typedef enum {
|
||||
UV_UNKNOWN = -1,
|
||||
UV_OK = 0,
|
||||
UV_EOF,
|
||||
UV_EACCESS,
|
||||
UV_EAGAIN,
|
||||
UV_EADDRINUSE,
|
||||
UV_EADDRNOTAVAIL,
|
||||
UV_EAFNOSUPPORT,
|
||||
UV_EALREADY,
|
||||
UV_EBADF,
|
||||
UV_EBUSY,
|
||||
UV_ECONNABORTED,
|
||||
UV_ECONNREFUSED,
|
||||
UV_ECONNRESET,
|
||||
UV_EDESTADDRREQ,
|
||||
UV_EFAULT,
|
||||
UV_EHOSTUNREACH,
|
||||
UV_EINTR,
|
||||
UV_EINVAL,
|
||||
UV_EISCONN,
|
||||
UV_EMFILE,
|
||||
UV_ENETDOWN,
|
||||
UV_ENETUNREACH,
|
||||
UV_ENFILE,
|
||||
UV_ENOBUFS,
|
||||
UV_ENOMEM,
|
||||
UV_ENONET,
|
||||
UV_ENOPROTOOPT,
|
||||
UV_ENOTCONN,
|
||||
UV_ENOTSOCK,
|
||||
UV_ENOTSUP,
|
||||
UV_EPROTO,
|
||||
UV_EPROTONOSUPPORT,
|
||||
UV_EPROTOTYPE,
|
||||
UV_ETIMEDOUT
|
||||
} uv_err_code;
|
||||
|
||||
typedef enum {
|
||||
UV_UNKNOWN_HANDLE = 0,
|
||||
UV_TCP,
|
||||
UV_NAMED_PIPE,
|
||||
UV_TTY,
|
||||
UV_FILE,
|
||||
UV_TIMER,
|
||||
UV_PREPARE,
|
||||
UV_CHECK,
|
||||
UV_IDLE,
|
||||
UV_ASYNC
|
||||
} uv_handle_type;
|
||||
|
||||
typedef enum {
|
||||
UV_UNKNOWN_REQ = 0,
|
||||
UV_CONNECT,
|
||||
UV_ACCEPT,
|
||||
UV_READ,
|
||||
UV_WRITE,
|
||||
UV_SHUTDOWN,
|
||||
UV_WAKEUP
|
||||
} uv_req_type;
|
||||
|
||||
|
||||
struct uv_err_s {
|
||||
/* read-only */
|
||||
uv_err_code code;
|
||||
/* private */
|
||||
int sys_errno_;
|
||||
};
|
||||
|
||||
|
||||
struct uv_req_s {
|
||||
/* read-only */
|
||||
uv_req_type type;
|
||||
/* public */
|
||||
uv_handle_t* handle;
|
||||
void* cb;
|
||||
void* data;
|
||||
/* private */
|
||||
UV_REQ_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
/*
|
||||
* Initialize a request for use with uv_write, uv_shutdown, or uv_connect.
|
||||
*/
|
||||
void uv_req_init(uv_req_t* req, uv_handle_t* handle, void* cb);
|
||||
|
||||
|
||||
#define UV_HANDLE_FIELDS \
|
||||
/* read-only */ \
|
||||
uv_handle_type type; \
|
||||
/* public */ \
|
||||
uv_close_cb close_cb; \
|
||||
void* data; \
|
||||
/* private */ \
|
||||
UV_HANDLE_PRIVATE_FIELDS \
|
||||
|
||||
/* The abstract base class of all handles. */
|
||||
struct uv_handle_s {
|
||||
UV_HANDLE_FIELDS
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns 1 if the prepare/check/idle handle has been started, 0 otherwise.
|
||||
* For other handle types this always returns 1.
|
||||
*/
|
||||
int uv_is_active(uv_handle_t* handle);
|
||||
|
||||
/*
|
||||
* Request handle to be closed. close_cb will be called asynchronously after
|
||||
* this call. This MUST be called on each handle before memory is released.
|
||||
*/
|
||||
int uv_close(uv_handle_t* handle, uv_close_cb close_cb);
|
||||
|
||||
|
||||
/*
|
||||
* A subclass of uv_handle_t representing a TCP stream or TCP server. In the
|
||||
* future this will probably be split into two classes - one a stream and
|
||||
* the other a server.
|
||||
*/
|
||||
struct uv_tcp_s {
|
||||
UV_HANDLE_FIELDS
|
||||
size_t write_queue_size; /* number of bytes queued for writing */
|
||||
UV_TCP_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
int uv_tcp_init(uv_tcp_t* handle);
|
||||
|
||||
int uv_bind(uv_tcp_t* handle, struct sockaddr_in);
|
||||
|
||||
int uv_connect(uv_req_t* req, struct sockaddr_in);
|
||||
|
||||
int uv_shutdown(uv_req_t* req);
|
||||
|
||||
int uv_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
|
||||
|
||||
/* This call is used in conjunction with uv_listen() to accept incoming TCP
|
||||
* connections. Call uv_accept after receiving a uv_connection_cb to accept
|
||||
* the connection. Before calling uv_accept use uv_tcp_init() must be
|
||||
* called on the client. Non-zero return value indicates an error.
|
||||
*/
|
||||
int uv_accept(uv_tcp_t* server, uv_tcp_t* client);
|
||||
|
||||
/* Read data from an incoming stream. The callback will be made several
|
||||
* several times until there is no more data to read or uv_read_stop is
|
||||
* called. When we've reached EOF nread will be set to -1 and the error is
|
||||
* set to UV_EOF. When nread == -1 the buf parameter might not point to a
|
||||
* valid buffer; in that case buf.len and buf.base are both set to 0.
|
||||
* Note that nread might also be 0, which does *not* indicate an error or
|
||||
* eof; it happens when libuv requested a buffer through the alloc callback
|
||||
* but then decided that it didn't need that buffer.
|
||||
*/
|
||||
int uv_read_start(uv_tcp_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb);
|
||||
|
||||
int uv_read_stop(uv_tcp_t*);
|
||||
|
||||
int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt);
|
||||
|
||||
|
||||
/*
|
||||
* Subclass of uv_handle_t. libev wrapper. Every active prepare handle gets
|
||||
* its callback called exactly once per loop iteration, just before the
|
||||
* system blocks to wait for completed i/o.
|
||||
*/
|
||||
struct uv_prepare_s {
|
||||
UV_HANDLE_FIELDS
|
||||
UV_PREPARE_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
int uv_prepare_init(uv_prepare_t* prepare);
|
||||
|
||||
int uv_prepare_start(uv_prepare_t* prepare, uv_loop_cb cb);
|
||||
|
||||
int uv_prepare_stop(uv_prepare_t* prepare);
|
||||
|
||||
|
||||
/*
|
||||
* Subclass of uv_handle_t. libev wrapper. Every active check handle gets
|
||||
* its callback called exactly once per loop iteration, just after the
|
||||
* system returns from blocking.
|
||||
*/
|
||||
struct uv_check_s {
|
||||
UV_HANDLE_FIELDS
|
||||
UV_CHECK_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
int uv_check_init(uv_check_t* check);
|
||||
|
||||
int uv_check_start(uv_check_t* check, uv_loop_cb cb);
|
||||
|
||||
int uv_check_stop(uv_check_t* check);
|
||||
|
||||
|
||||
/*
|
||||
* Subclass of uv_handle_t. libev wrapper. Every active idle handle gets its
|
||||
* callback called repeatedly until it is stopped. This happens after all
|
||||
* other types of callbacks are processed. When there are multiple "idle"
|
||||
* handles active, their callbacks are called in turn.
|
||||
*/
|
||||
struct uv_idle_s {
|
||||
UV_HANDLE_FIELDS
|
||||
UV_IDLE_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
int uv_idle_init(uv_idle_t* idle);
|
||||
|
||||
int uv_idle_start(uv_idle_t* idle, uv_loop_cb cb);
|
||||
|
||||
int uv_idle_stop(uv_idle_t* idle);
|
||||
|
||||
|
||||
/*
|
||||
* Subclass of uv_handle_t. libev wrapper. uv_async_send wakes up the event
|
||||
* loop and calls the async handle's callback There is no guarantee that
|
||||
* every uv_async_send call leads to exactly one invocation of the callback;
|
||||
* The only guarantee is that the callback function is called at least once
|
||||
* after the call to async_send. Unlike all other libuv functions,
|
||||
* uv_async_send can be called from another thread.
|
||||
*/
|
||||
typedef struct {
|
||||
UV_HANDLE_FIELDS
|
||||
UV_ASYNC_PRIVATE_FIELDS
|
||||
} uv_async_t;
|
||||
|
||||
int uv_async_init(uv_async_t* async, uv_async_cb async_cb);
|
||||
|
||||
int uv_async_send(uv_async_t* async);
|
||||
|
||||
|
||||
/*
|
||||
* Subclass of uv_handle_t. Wraps libev's ev_timer watcher. Used to get
|
||||
* woken up at a specified time in the future.
|
||||
*/
|
||||
struct uv_timer_s {
|
||||
UV_HANDLE_FIELDS
|
||||
UV_TIMER_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
int uv_timer_init(uv_timer_t* timer);
|
||||
|
||||
int uv_timer_start(uv_timer_t* timer, uv_loop_cb cb, int64_t timeout, int64_t repeat);
|
||||
|
||||
int uv_timer_stop(uv_timer_t* timer);
|
||||
|
||||
/*
|
||||
* Stop the timer, and if it is repeating restart it using the repeat value
|
||||
* as the timeout. If the timer has never been started before it returns -1 and
|
||||
* sets the error to UV_EINVAL.
|
||||
*/
|
||||
int uv_timer_again(uv_timer_t* timer);
|
||||
|
||||
/*
|
||||
* Set the repeat value. Note that if the repeat value is set from a timer
|
||||
* callback it does not immediately take effect. If the timer was nonrepeating
|
||||
* before, it will have been stopped. If it was repeating, then the old repeat
|
||||
* value will have been used to schedule the next timeout.
|
||||
*/
|
||||
void uv_timer_set_repeat(uv_timer_t* timer, int64_t repeat);
|
||||
|
||||
int64_t uv_timer_get_repeat(uv_timer_t* timer);
|
||||
|
||||
|
||||
/*
|
||||
* Most functions return boolean: 0 for success and -1 for failure.
|
||||
* On error the user should then call uv_last_error() to determine
|
||||
* the error code.
|
||||
*/
|
||||
uv_err_t uv_last_error();
|
||||
char* uv_strerror(uv_err_t err);
|
||||
const char* uv_err_name(uv_err_t err);
|
||||
|
||||
void uv_init();
|
||||
int uv_run();
|
||||
|
||||
/*
|
||||
* Manually modify the event loop's reference count. Useful if the user wants
|
||||
* to have a handle or timeout that doesn't keep the loop alive.
|
||||
*/
|
||||
void uv_ref();
|
||||
void uv_unref();
|
||||
|
||||
void uv_update_time();
|
||||
int64_t uv_now();
|
||||
|
||||
|
||||
/* Utility */
|
||||
struct sockaddr_in uv_ip4_addr(char* ip, int port);
|
||||
|
||||
/* Gets the executable path */
|
||||
int uv_get_exepath(char* buffer, size_t* size);
|
||||
|
||||
|
||||
/* the presence of this union forces similar struct layout */
|
||||
union uv_any_handle {
|
||||
uv_tcp_t tcp;
|
||||
uv_prepare_t prepare;
|
||||
uv_check_t check;
|
||||
uv_idle_t idle;
|
||||
uv_async_t async;
|
||||
uv_timer_t timer;
|
||||
};
|
||||
|
||||
/* Diagnostic counters */
|
||||
typedef struct {
|
||||
uint64_t req_init;
|
||||
uint64_t handle_init;
|
||||
uint64_t tcp_init;
|
||||
uint64_t prepare_init;
|
||||
uint64_t check_init;
|
||||
uint64_t idle_init;
|
||||
uint64_t async_init;
|
||||
uint64_t timer_init;
|
||||
} uv_counters_t;
|
||||
|
||||
uv_counters_t* const uv_counters();
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* UV_H */
|
||||
Loading…
Add table
Add a link
Reference in a new issue