mirror of
https://github.com/nodejs/node.git
synced 2026-11-09 15:11:11 -05:00
Upgrade libuv
This commit is contained in:
1 parent
4c480551c3
commit
412e413edc
48 files changed
+352
-16287
No files matched your search
Vendored
-26
@@ -1,26 +0,0 @@
|
||||
include(CheckFunctionExists)
|
||||
include(FindThreads)
|
||||
|
||||
if(!${CMAKE_USE_PTHREADS_INIT})
|
||||
message(FATAL_ERROR "Unable to find pthreads")
|
||||
endif()
|
||||
|
||||
add_definitions(-DHAVE_CONFIG_H=1 -D_GNU_SOURCE)
|
||||
|
||||
check_function_exists(futimes HAVE_FUTIMES)
|
||||
check_function_exists(readahead HAVE_READAHEAD)
|
||||
check_function_exists(fdatasync HAVE_FDATASYNC)
|
||||
check_function_exists(pread HAVE_PREAD)
|
||||
check_function_exists(pwrite HAVE_PWRITE)
|
||||
check_function_exists(sendfile HAVE_SENDFILE)
|
||||
check_function_exists(sync_file_range HAVE_SYNC_FILE_RANGE)
|
||||
|
||||
if(${HAVE_PREAD} AND ${HAVE_PWRITE})
|
||||
set(HAVE_PREADWRITE 1)
|
||||
endif()
|
||||
|
||||
configure_file(config.h.cmake ${PROJECT_BINARY_DIR}/deps/libeio/config.h)
|
||||
include_directories(${PROJECT_BINARY_DIR}/deps/libeio)
|
||||
|
||||
add_library(eio eio.c)
|
||||
target_link_libraries(eio ${CMAKE_THREAD_LIBS_INIT})
|
||||
Vendored
-35
@@ -1,35 +0,0 @@
|
||||
Revision history for libeio
|
||||
|
||||
TODO: maybe add mincore support? available on at least darwin, solaris, linux, freebsd
|
||||
TODO: openbsd requites stdint.h for intptr_t - why posix?
|
||||
|
||||
1.0
|
||||
- readdir: correctly handle malloc failures.
|
||||
- readdir: new flags argument, can return inode
|
||||
and possibly filetype, can sort in various ways.
|
||||
- readdir: stop immediately when cancelled, do
|
||||
not continue reading the directory.
|
||||
- fix return value of eio_sendfile_sync.
|
||||
- include sys/mman.h for msync.
|
||||
- added EIO_STACKSIZE.
|
||||
- added msync, mtouch support (untested).
|
||||
- added sync_file_range (untested).
|
||||
- fixed custom support.
|
||||
- use a more robust feed-add detection method.
|
||||
- "outbundled" from IO::AIO.
|
||||
- eio_set_max_polltime did not properly convert time to ticks.
|
||||
- tentatively support darwin in sendfile.
|
||||
- fix freebsd/darwin sendfile.
|
||||
- also use sendfile emulation for ENOTSUP and EOPNOTSUPP
|
||||
error codes.
|
||||
- add OS-independent EIO_MT_* and EIO_MS_* flag enums.
|
||||
- add eio_statvfs/eio_fstatvfs.
|
||||
- add eio_mlock/eio_mlockall and OS-independent MCL_* flag enums.
|
||||
- no longer set errno to 0 before making syscalls, this only lures
|
||||
people into the trap of believing errno shows success or failure.
|
||||
- "fix" demo.c so that it works as non-root.
|
||||
- suppoert utimes seperately from futimes, as some systems have
|
||||
utimes but not futimes.
|
||||
- use _POSIX_MEMLOCK_RANGE for mlock.
|
||||
- do not (errornously) overwrite CFLAGS in configure.ac.
|
||||
|
||||
Vendored
-36
@@ -1,36 +0,0 @@
|
||||
All files in libeio are Copyright (C)2007,2008 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.
|
||||
Vendored
-15
@@ -1,15 +0,0 @@
|
||||
AUTOMAKE_OPTIONS = foreign no-dependencies
|
||||
|
||||
VERSION_INFO = 1:0
|
||||
|
||||
EXTRA_DIST = LICENSE Changes autogen.sh
|
||||
|
||||
#man_MANS = ev.3
|
||||
|
||||
include_HEADERS = eio.h
|
||||
|
||||
lib_LTLIBRARIES = libeio.la
|
||||
|
||||
libeio_la_SOURCES = eio.c xthread.h config.h
|
||||
libeio_la_LDFLAGS = -version-info $(VERSION_INFO)
|
||||
|
||||
Vendored
-8957
File diff suppressed because it is too large.
Load diff
Vendored
-5
@@ -1,5 +0,0 @@
|
||||
libtoolize
|
||||
aclocal
|
||||
automake --add-missing
|
||||
autoconf
|
||||
autoheader
|
||||
Vendored
-17
@@ -1,17 +0,0 @@
|
||||
/* futimes(2) is available */
|
||||
#cmakedefine HAVE_FUTIMES 1
|
||||
|
||||
/* readahead(2) is available (linux) */
|
||||
#cmakedefine HAVE_READAHEAD 1
|
||||
|
||||
/* fdatasync(2) is available */
|
||||
#cmakedefine HAVE_FDATASYNC 1
|
||||
|
||||
/* pread(2) and pwrite(2) are available */
|
||||
#cmakedefine HAVE_PREADWRITE 1
|
||||
|
||||
/* sendfile(2) is available and supported */
|
||||
#cmakedefine HAVE_SENDFILE 1
|
||||
|
||||
/* sync_file_range(2) is available */
|
||||
#cmakedefine HAVE_SYNC_FILE_RANGE 1
|
||||
Vendored
-86
@@ -1,86 +0,0 @@
|
||||
/* config.h.in. Generated from configure.ac by autoheader. */
|
||||
|
||||
/* Define to 1 if you have the <dlfcn.h> header file. */
|
||||
#undef HAVE_DLFCN_H
|
||||
|
||||
/* fdatasync(2) is available */
|
||||
#undef HAVE_FDATASYNC
|
||||
|
||||
/* futimes(2) is available */
|
||||
#undef HAVE_FUTIMES
|
||||
|
||||
/* Define to 1 if you have the <inttypes.h> header file. */
|
||||
#undef HAVE_INTTYPES_H
|
||||
|
||||
/* Define to 1 if you have the <memory.h> header file. */
|
||||
#undef HAVE_MEMORY_H
|
||||
|
||||
/* posix_fadvise(2) is available */
|
||||
#undef HAVE_POSIX_FADVISE
|
||||
|
||||
/* posix_madvise(2) is available */
|
||||
#undef HAVE_POSIX_MADVISE
|
||||
|
||||
/* pread(2) and pwrite(2) are available */
|
||||
#undef HAVE_PREADWRITE
|
||||
|
||||
/* readahead(2) is available (linux) */
|
||||
#undef HAVE_READAHEAD
|
||||
|
||||
/* sendfile(2) is available and supported */
|
||||
#undef HAVE_SENDFILE
|
||||
|
||||
/* 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
|
||||
|
||||
/* sync_file_range(2) is available */
|
||||
#undef HAVE_SYNC_FILE_RANGE
|
||||
|
||||
/* 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
|
||||
|
||||
/* utimes(2) is available */
|
||||
#undef HAVE_UTIMES
|
||||
|
||||
/* 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
|
||||
Vendored
-22
@@ -1,22 +0,0 @@
|
||||
AC_PREREQ(2.59)
|
||||
AC_INIT
|
||||
AC_CONFIG_SRCDIR([eio.h])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
AM_INIT_AUTOMAKE(libeio,1.0)
|
||||
AM_MAINTAINER_MODE
|
||||
AC_PROG_LIBTOOL
|
||||
|
||||
AC_PROG_CC
|
||||
|
||||
if test "x$GCC" = xyes ; then
|
||||
CFLAGS="$CFLAGS -O3"
|
||||
fi
|
||||
|
||||
dnl somebody will forgive me
|
||||
CFLAGS="-D_GNU_SOURCE $CFLAGS"
|
||||
|
||||
m4_include([libeio.m4])
|
||||
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
AC_OUTPUT
|
||||
Vendored
-194
@@ -1,194 +0,0 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include "eio.h"
|
||||
|
||||
int respipe [2];
|
||||
|
||||
void
|
||||
want_poll (void)
|
||||
{
|
||||
char dummy;
|
||||
printf ("want_poll ()\n");
|
||||
write (respipe [1], &dummy, 1);
|
||||
}
|
||||
|
||||
void
|
||||
done_poll (void)
|
||||
{
|
||||
char dummy;
|
||||
printf ("done_poll ()\n");
|
||||
read (respipe [0], &dummy, 1);
|
||||
}
|
||||
|
||||
void
|
||||
event_loop (void)
|
||||
{
|
||||
// an event loop. yeah.
|
||||
struct pollfd pfd;
|
||||
pfd.fd = respipe [0];
|
||||
pfd.events = POLLIN;
|
||||
|
||||
printf ("\nentering event loop\n");
|
||||
while (eio_nreqs ())
|
||||
{
|
||||
poll (&pfd, 1, -1);
|
||||
printf ("eio_poll () = %d\n", eio_poll ());
|
||||
}
|
||||
printf ("leaving event loop\n");
|
||||
}
|
||||
|
||||
int
|
||||
res_cb (eio_req *req)
|
||||
{
|
||||
printf ("res_cb(%d|%s) = %d\n", req->type, req->data ? req->data : "?", EIO_RESULT (req));
|
||||
|
||||
if (req->result < 0)
|
||||
abort ();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
readdir_cb (eio_req *req)
|
||||
{
|
||||
char *buf = (char *)EIO_BUF (req);
|
||||
|
||||
printf ("readdir_cb = %d\n", EIO_RESULT (req));
|
||||
|
||||
if (EIO_RESULT (req) < 0)
|
||||
return 0;
|
||||
|
||||
while (EIO_RESULT (req)--)
|
||||
{
|
||||
printf ("readdir = <%s>\n", buf);
|
||||
buf += strlen (buf) + 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
stat_cb (eio_req *req)
|
||||
{
|
||||
struct stat *buf = EIO_STAT_BUF (req);
|
||||
|
||||
if (req->type == EIO_FSTAT)
|
||||
printf ("fstat_cb = %d\n", EIO_RESULT (req));
|
||||
else
|
||||
printf ("stat_cb(%s) = %d\n", EIO_PATH (req), EIO_RESULT (req));
|
||||
|
||||
if (!EIO_RESULT (req))
|
||||
printf ("stat size %d perm 0%o\n", buf->st_size, buf->st_mode & 0777);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
read_cb (eio_req *req)
|
||||
{
|
||||
unsigned char *buf = (unsigned char *)EIO_BUF (req);
|
||||
|
||||
printf ("read_cb = %d (%02x%02x%02x%02x %02x%02x%02x%02x)\n",
|
||||
EIO_RESULT (req),
|
||||
buf [0], buf [1], buf [2], buf [3],
|
||||
buf [4], buf [5], buf [6], buf [7]);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int last_fd;
|
||||
|
||||
int
|
||||
open_cb (eio_req *req)
|
||||
{
|
||||
printf ("open_cb = %d\n", EIO_RESULT (req));
|
||||
|
||||
last_fd = EIO_RESULT (req);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
printf ("pipe ()\n");
|
||||
if (pipe (respipe)) abort ();
|
||||
|
||||
printf ("eio_init ()\n");
|
||||
if (eio_init (want_poll, done_poll)) abort ();
|
||||
|
||||
do
|
||||
{
|
||||
/* avoid relative paths yourself(!) */
|
||||
eio_mkdir ("eio-test-dir", 0777, 0, res_cb, "mkdir");
|
||||
eio_nop (0, res_cb, "nop");
|
||||
event_loop ();
|
||||
|
||||
eio_stat ("eio-test-dir", 0, stat_cb, "stat");
|
||||
eio_lstat ("eio-test-dir", 0, stat_cb, "stat");
|
||||
eio_open ("eio-test-dir/eio-test-file", O_RDWR | O_CREAT, 0777, 0, open_cb, "open");
|
||||
eio_symlink ("test", "eio-test-dir/eio-symlink", 0, res_cb, "symlink");
|
||||
eio_mknod ("eio-test-dir/eio-fifo", S_IFIFO, 0, 0, res_cb, "mknod");
|
||||
event_loop ();
|
||||
|
||||
eio_utime ("eio-test-dir", 12345.678, 23456.789, 0, res_cb, "utime");
|
||||
eio_futime (last_fd, 92345.678, 93456.789, 0, res_cb, "futime");
|
||||
eio_chown ("eio-test-dir", getuid (), getgid (), 0, res_cb, "chown");
|
||||
eio_fchown (last_fd, getuid (), getgid (), 0, res_cb, "fchown");
|
||||
eio_fchmod (last_fd, 0723, 0, res_cb, "fchmod");
|
||||
eio_readdir ("eio-test-dir", 0, 0, readdir_cb, "readdir");
|
||||
eio_readdir ("/nonexistant", 0, 0, readdir_cb, "readdir");
|
||||
eio_fstat (last_fd, 0, stat_cb, "stat");
|
||||
eio_write (last_fd, "test\nfail\n", 10, 4, 0, res_cb, "write");
|
||||
event_loop ();
|
||||
|
||||
eio_read (last_fd, 0, 8, 0, EIO_PRI_DEFAULT, read_cb, "read");
|
||||
eio_readlink ("eio-test-dir/eio-symlink", 0, res_cb, "readlink");
|
||||
event_loop ();
|
||||
|
||||
eio_dup2 (1, 2, EIO_PRI_DEFAULT, res_cb, "dup"); // dup stdout to stderr
|
||||
eio_chmod ("eio-test-dir", 0765, 0, res_cb, "chmod");
|
||||
eio_ftruncate (last_fd, 9, 0, res_cb, "ftruncate");
|
||||
eio_fdatasync (last_fd, 0, res_cb, "fdatasync");
|
||||
eio_fsync (last_fd, 0, res_cb, "fsync");
|
||||
eio_sync (0, res_cb, "sync");
|
||||
eio_busy (0.5, 0, res_cb, "busy");
|
||||
event_loop ();
|
||||
|
||||
eio_sendfile (1, last_fd, 4, 5, 0, res_cb, "sendfile"); // write "test\n" to stdout
|
||||
eio_fstat (last_fd, 0, stat_cb, "stat");
|
||||
event_loop ();
|
||||
|
||||
eio_truncate ("eio-test-dir/eio-test-file", 6, 0, res_cb, "truncate");
|
||||
eio_readahead (last_fd, 0, 64, 0, res_cb, "readahead");
|
||||
event_loop ();
|
||||
|
||||
eio_close (last_fd, 0, res_cb, "close");
|
||||
eio_link ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-2", 0, res_cb, "link");
|
||||
event_loop ();
|
||||
|
||||
eio_rename ("eio-test-dir/eio-test-file", "eio-test-dir/eio-test-file-renamed", 0, res_cb, "rename");
|
||||
event_loop ();
|
||||
|
||||
eio_unlink ("eio-test-dir/eio-fifo", 0, res_cb, "unlink");
|
||||
eio_unlink ("eio-test-dir/eio-symlink", 0, res_cb, "unlink");
|
||||
eio_unlink ("eio-test-dir/eio-test-file-2", 0, res_cb, "unlink");
|
||||
eio_unlink ("eio-test-dir/eio-test-file-renamed", 0, res_cb, "unlink");
|
||||
event_loop ();
|
||||
|
||||
eio_rmdir ("eio-test-dir", 0, res_cb, "rmdir");
|
||||
event_loop ();
|
||||
}
|
||||
while (0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vendored
-3428
File diff suppressed because it is too large.
Load diff
Vendored
-2128
File diff suppressed because it is too large.
Load diff
Vendored
-356
@@ -1,356 +0,0 @@
|
||||
/*
|
||||
* libeio API header
|
||||
*
|
||||
* Copyright (c) 2007,2008,2009,2010 Marc Alexander Lehmann <libeio@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 EIO_H_
|
||||
#define EIO_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#ifdef __OpenBSD__
|
||||
# include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#ifdef _WIN32
|
||||
# define uid_t int
|
||||
# define gid_t int
|
||||
#endif
|
||||
|
||||
typedef struct eio_req eio_req;
|
||||
typedef struct eio_dirent eio_dirent;
|
||||
|
||||
typedef int (*eio_cb)(eio_req *req);
|
||||
|
||||
#ifndef EIO_REQ_MEMBERS
|
||||
# define EIO_REQ_MEMBERS
|
||||
#endif
|
||||
|
||||
#ifndef EIO_STRUCT_STAT
|
||||
# ifdef _WIN32
|
||||
# define EIO_STRUCT_STAT struct _stati64
|
||||
# else
|
||||
# define EIO_STRUCT_STAT struct stat
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifndef EIO_STRUCT_STATVFS
|
||||
# define EIO_STRUCT_STATVFS struct statvfs
|
||||
#endif
|
||||
|
||||
/* for readdir */
|
||||
|
||||
/* eio_readdir flags */
|
||||
enum
|
||||
{
|
||||
EIO_READDIR_DENTS = 0x01, /* ptr2 contains eio_dirents, not just the (unsorted) names */
|
||||
EIO_READDIR_DIRS_FIRST = 0x02, /* dirents gets sorted into a good stat() ing order to find directories first */
|
||||
EIO_READDIR_STAT_ORDER = 0x04, /* dirents gets sorted into a good stat() ing order to quickly stat all files */
|
||||
EIO_READDIR_FOUND_UNKNOWN = 0x80, /* set by eio_readdir when *_ARRAY was set and any TYPE=UNKNOWN's were found */
|
||||
|
||||
EIO_READDIR_CUSTOM1 = 0x100, /* for use by apps */
|
||||
EIO_READDIR_CUSTOM2 = 0x200 /* for use by apps */
|
||||
};
|
||||
|
||||
/* using "typical" values in the hope that the compiler will do something sensible */
|
||||
enum eio_dtype
|
||||
{
|
||||
EIO_DT_UNKNOWN = 0,
|
||||
EIO_DT_FIFO = 1,
|
||||
EIO_DT_CHR = 2,
|
||||
EIO_DT_MPC = 3, /* multiplexed char device (v7+coherent) */
|
||||
EIO_DT_DIR = 4,
|
||||
EIO_DT_NAM = 5, /* xenix special named file */
|
||||
EIO_DT_BLK = 6,
|
||||
EIO_DT_MPB = 7, /* multiplexed block device (v7+coherent) */
|
||||
EIO_DT_REG = 8,
|
||||
EIO_DT_NWK = 9, /* HP-UX network special */
|
||||
EIO_DT_CMP = 9, /* VxFS compressed */
|
||||
EIO_DT_LNK = 10,
|
||||
/* DT_SHAD = 11,*/
|
||||
EIO_DT_SOCK = 12,
|
||||
EIO_DT_DOOR = 13, /* solaris door */
|
||||
EIO_DT_WHT = 14,
|
||||
EIO_DT_MAX = 15 /* highest DT_VALUE ever, hopefully */
|
||||
};
|
||||
|
||||
struct eio_dirent
|
||||
{
|
||||
int nameofs; /* offset of null-terminated name string in (char *)req->ptr2 */
|
||||
unsigned short namelen; /* size of filename without trailing 0 */
|
||||
unsigned char type; /* one of EIO_DT_* */
|
||||
signed char score; /* internal use */
|
||||
ino_t inode; /* the inode number, if available, otherwise unspecified */
|
||||
};
|
||||
|
||||
/* eio_msync flags */
|
||||
enum
|
||||
{
|
||||
EIO_MS_ASYNC = 1,
|
||||
EIO_MS_INVALIDATE = 2,
|
||||
EIO_MS_SYNC = 4
|
||||
};
|
||||
|
||||
/* eio_mtouch flags */
|
||||
|
||||
enum
|
||||
{
|
||||
EIO_MT_MODIFY = 1
|
||||
};
|
||||
|
||||
/* eio_sync_file_range flags */
|
||||
|
||||
enum
|
||||
{
|
||||
EIO_SYNC_FILE_RANGE_WAIT_BEFORE = 1,
|
||||
EIO_SYNC_FILE_RANGE_WRITE = 2,
|
||||
EIO_SYNC_FILE_RANGE_WAIT_AFTER = 4
|
||||
};
|
||||
|
||||
typedef double eio_tstamp; /* feel free to use double in your code directly */
|
||||
|
||||
/* the eio request structure */
|
||||
|
||||
enum
|
||||
{
|
||||
EIO_CUSTOM,
|
||||
EIO_OPEN, EIO_CLOSE, EIO_DUP2,
|
||||
EIO_READ, EIO_WRITE,
|
||||
EIO_READAHEAD, EIO_SENDFILE,
|
||||
EIO_STAT, EIO_LSTAT, EIO_FSTAT,
|
||||
EIO_STATVFS, EIO_FSTATVFS,
|
||||
EIO_TRUNCATE, EIO_FTRUNCATE,
|
||||
EIO_UTIME, EIO_FUTIME,
|
||||
EIO_CHMOD, EIO_FCHMOD,
|
||||
EIO_CHOWN, EIO_FCHOWN,
|
||||
EIO_SYNC, EIO_FSYNC, EIO_FDATASYNC,
|
||||
EIO_MSYNC, EIO_MTOUCH, EIO_SYNC_FILE_RANGE,
|
||||
EIO_MLOCK, EIO_MLOCKALL,
|
||||
EIO_UNLINK, EIO_RMDIR, EIO_MKDIR, EIO_RENAME,
|
||||
EIO_MKNOD, EIO_READDIR,
|
||||
EIO_LINK, EIO_SYMLINK, EIO_READLINK,
|
||||
EIO_GROUP, EIO_NOP,
|
||||
EIO_BUSY
|
||||
};
|
||||
|
||||
/* mlockall constants */
|
||||
enum
|
||||
{
|
||||
EIO_MCL_CURRENT = 1,
|
||||
EIO_MCL_FUTURE = 2,
|
||||
};
|
||||
|
||||
/* request priorities */
|
||||
|
||||
enum {
|
||||
EIO_PRI_MIN = -4,
|
||||
EIO_PRI_MAX = 4,
|
||||
EIO_PRI_DEFAULT = 0,
|
||||
};
|
||||
|
||||
/* eio request structure */
|
||||
/* this structure is mostly read-only */
|
||||
/* when initialising it, all members must be zero-initialised */
|
||||
struct eio_req
|
||||
{
|
||||
eio_req volatile *next; /* private ETP */
|
||||
|
||||
ssize_t result; /* result of syscall, e.g. result = read (... */
|
||||
off_t offs; /* read, write, truncate, readahead, sync_file_range: file offset */
|
||||
size_t size; /* read, write, readahead, sendfile, msync, mlock, sync_file_range: length */
|
||||
void *ptr1; /* all applicable requests: pathname, old name; readdir: optional eio_dirents */
|
||||
void *ptr2; /* all applicable requests: new name or memory buffer; readdir: name strings */
|
||||
eio_tstamp nv1; /* utime, futime: atime; busy: sleep time */
|
||||
eio_tstamp nv2; /* utime, futime: mtime */
|
||||
|
||||
int type; /* EIO_xxx constant ETP */
|
||||
int int1; /* all applicable requests: file descriptor; sendfile: output fd; open, msync, mlockall, readdir: flags */
|
||||
long int2; /* chown, fchown: uid; sendfile: input fd; open, chmod, mkdir, mknod: file mode, sync_file_range: flags */
|
||||
long int3; /* chown, fchown: gid; mknod: dev_t */
|
||||
int errorno; /* errno value on syscall return */
|
||||
|
||||
unsigned char flags; /* private */
|
||||
signed char pri; /* the priority */
|
||||
|
||||
void *data;
|
||||
eio_cb finish;
|
||||
void (*destroy)(eio_req *req); /* called when requets no longer needed */
|
||||
void (*feed)(eio_req *req); /* only used for group requests */
|
||||
|
||||
EIO_REQ_MEMBERS
|
||||
|
||||
eio_req *grp, *grp_prev, *grp_next, *grp_first; /* private */
|
||||
};
|
||||
|
||||
/* _private_ request flags */
|
||||
enum {
|
||||
EIO_FLAG_CANCELLED = 0x01, /* request was cancelled */
|
||||
EIO_FLAG_PTR1_FREE = 0x02, /* need to free(ptr1) */
|
||||
EIO_FLAG_PTR2_FREE = 0x04, /* need to free(ptr2) */
|
||||
EIO_FLAG_GROUPADD = 0x08 /* some request was added to the group */
|
||||
};
|
||||
|
||||
/* undocumented/unsupported/private helper */
|
||||
/*void eio_page_align (void **addr, size_t *length);*/
|
||||
|
||||
/* returns < 0 on error, errno set
|
||||
* need_poll, if non-zero, will be called when results are available
|
||||
* and eio_poll_cb needs to be invoked (it MUST NOT call eio_poll_cb itself).
|
||||
* done_poll is called when the need to poll is gone.
|
||||
*/
|
||||
int eio_init (void (*want_poll)(void), void (*done_poll)(void));
|
||||
|
||||
/* must be called regularly to handle pending requests */
|
||||
/* returns 0 if all requests were handled, -1 if not, or the value of EIO_FINISH if != 0 */
|
||||
int eio_poll (void);
|
||||
|
||||
/* stop polling if poll took longer than duration seconds */
|
||||
void eio_set_max_poll_time (eio_tstamp nseconds);
|
||||
/* do not handle more then count requests in one call to eio_poll_cb */
|
||||
void eio_set_max_poll_reqs (unsigned int nreqs);
|
||||
|
||||
/* set minimum required number
|
||||
* maximum wanted number
|
||||
* or maximum idle number of threads */
|
||||
void eio_set_min_parallel (unsigned int nthreads);
|
||||
void eio_set_max_parallel (unsigned int nthreads);
|
||||
void eio_set_max_idle (unsigned int nthreads);
|
||||
|
||||
unsigned int eio_nreqs (void); /* number of requests in-flight */
|
||||
unsigned int eio_nready (void); /* number of not-yet handled requests */
|
||||
unsigned int eio_npending (void); /* numbe rof finished but unhandled requests */
|
||||
unsigned int eio_nthreads (void); /* number of worker threads in use currently */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* convinience wrappers */
|
||||
|
||||
#ifndef EIO_NO_WRAPPERS
|
||||
eio_req *eio_nop (int pri, eio_cb cb, void *data); /* does nothing except go through the whole process */
|
||||
eio_req *eio_busy (eio_tstamp delay, int pri, eio_cb cb, void *data); /* ties a thread for this long, simulating busyness */
|
||||
eio_req *eio_sync (int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_fsync (int fd, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_fdatasync (int fd, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_msync (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_mtouch (void *addr, size_t length, int flags, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_mlock (void *addr, size_t length, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_mlockall (int flags, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_sync_file_range (int fd, off_t offset, size_t nbytes, unsigned int flags, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_close (int fd, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_readahead (int fd, off_t offset, size_t length, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_read (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_write (int fd, void *buf, size_t length, off_t offset, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_fstat (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
|
||||
eio_req *eio_fstatvfs (int fd, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
|
||||
eio_req *eio_futime (int fd, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_ftruncate (int fd, off_t offset, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_fchmod (int fd, mode_t mode, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_fchown (int fd, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_dup2 (int fd, int fd2, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_sendfile (int out_fd, int in_fd, off_t in_offset, size_t length, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_open (const char *path, int flags, mode_t mode, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_utime (const char *path, eio_tstamp atime, eio_tstamp mtime, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_truncate (const char *path, off_t offset, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_chown (const char *path, uid_t uid, gid_t gid, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_chmod (const char *path, mode_t mode, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_mkdir (const char *path, mode_t mode, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_readdir (const char *path, int flags, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
|
||||
eio_req *eio_rmdir (const char *path, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_unlink (const char *path, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_readlink (const char *path, int pri, eio_cb cb, void *data); /* result=ptr2 allocated dynamically */
|
||||
eio_req *eio_stat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
|
||||
eio_req *eio_lstat (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
|
||||
eio_req *eio_statvfs (const char *path, int pri, eio_cb cb, void *data); /* stat buffer=ptr2 allocated dynamically */
|
||||
eio_req *eio_mknod (const char *path, mode_t mode, dev_t dev, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_link (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_symlink (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_rename (const char *path, const char *new_path, int pri, eio_cb cb, void *data);
|
||||
eio_req *eio_custom (eio_cb execute, int pri, eio_cb cb, void *data);
|
||||
#endif
|
||||
|
||||
/*****************************************************************************/
|
||||
/* groups */
|
||||
|
||||
eio_req *eio_grp (eio_cb cb, void *data);
|
||||
void eio_grp_feed (eio_req *grp, void (*feed)(eio_req *req), int limit);
|
||||
void eio_grp_limit (eio_req *grp, int limit);
|
||||
void eio_grp_add (eio_req *grp, eio_req *req);
|
||||
void eio_grp_cancel (eio_req *grp); /* cancels all sub requests but not the group */
|
||||
|
||||
/*****************************************************************************/
|
||||
/* request api */
|
||||
|
||||
/* true if the request was cancelled, useful in the invoke callback */
|
||||
#define EIO_CANCELLED(req) ((req)->flags & EIO_FLAG_CANCELLED)
|
||||
|
||||
#define EIO_RESULT(req) ((req)->result)
|
||||
/* returns a pointer to the result buffer allocated by eio */
|
||||
#define EIO_BUF(req) ((req)->ptr2)
|
||||
#define EIO_STAT_BUF(req) ((EIO_STRUCT_STAT *)EIO_BUF(req))
|
||||
#define EIO_STATVFS_BUF(req) ((EIO_STRUCT_STATVFS *)EIO_BUF(req))
|
||||
#define EIO_PATH(req) ((char *)(req)->ptr1)
|
||||
|
||||
/* submit a request for execution */
|
||||
void eio_submit (eio_req *req);
|
||||
/* cancel a request as soon fast as possible, if possible */
|
||||
void eio_cancel (eio_req *req);
|
||||
/* destroy a request that has never been submitted */
|
||||
void eio_destroy (eio_req *req);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* convinience functions */
|
||||
|
||||
ssize_t eio_sendfile_sync (int ofd, int ifd, off_t offset, size_t count);
|
||||
|
||||
/*****************************************************************************/
|
||||
/* export these so node_file can use these function instead of pread/write */
|
||||
|
||||
#if !HAVE_PREADWRITE
|
||||
ssize_t eio__pread (int fd, void *buf, size_t count, off_t offset);
|
||||
ssize_t eio__pwrite (int fd, void *buf, size_t count, off_t offset);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Vendored
-303
@@ -1,303 +0,0 @@
|
||||
=head1 NAME
|
||||
|
||||
libeio - truly asynchronous POSIX I/O
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
#include <eio.h>
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
The newest version of this document is also available as an html-formatted
|
||||
web page you might find easier to navigate when reading it for the first
|
||||
time: L<http://pod.tst.eu/http://cvs.schmorp.de/libeio/eio.pod>.
|
||||
|
||||
Note that this library is a by-product of the C<IO::AIO> perl
|
||||
module, and many of the subtler points regarding requets lifetime
|
||||
and so on are only documented in its documentation at the
|
||||
moment: L<http://pod.tst.eu/http://cvs.schmorp.de/IO-AIO/AIO.pm>.
|
||||
|
||||
=head2 FEATURES
|
||||
|
||||
This library provides fully asynchronous versions of most POSIX functions
|
||||
dealign with I/O. Unlike most asynchronous libraries, this not only
|
||||
includes C<read> and C<write>, but also C<open>, C<stat>, C<unlink> and
|
||||
similar functions, as well as less rarely ones such as C<mknod>, C<futime>
|
||||
or C<readlink>.
|
||||
|
||||
It also offers wrappers around C<sendfile> (Solaris, Linux, HP-UX and
|
||||
FreeBSD, with emulation on other platforms) and C<readahead> (Linux, with
|
||||
emulation elsewhere>).
|
||||
|
||||
The goal is to enable you to write fully non-blocking programs. For
|
||||
example, in a game server, you would not want to freeze for a few seconds
|
||||
just because the server is running a backup and you happen to call
|
||||
C<readdir>.
|
||||
|
||||
=head2 TIME REPRESENTATION
|
||||
|
||||
Libeio represents time as a single floating point number, representing the
|
||||
(fractional) number of seconds since the (POSIX) epoch (somewhere near
|
||||
the beginning of 1970, details are complicated, don't ask). This type is
|
||||
called C<eio_tstamp>, but it is guarenteed to be of type C<double> (or
|
||||
better), so you can freely use C<double> yourself.
|
||||
|
||||
Unlike the name component C<stamp> might indicate, it is also used for
|
||||
time differences throughout libeio.
|
||||
|
||||
=head2 FORK SUPPORT
|
||||
|
||||
Calling C<fork ()> is fully supported by this module. It is implemented in these steps:
|
||||
|
||||
1. wait till all requests in "execute" state have been handled
|
||||
(basically requests that are already handed over to the kernel).
|
||||
2. fork
|
||||
3. in the parent, continue business as usual, done
|
||||
4. in the child, destroy all ready and pending requests and free the
|
||||
memory used by the worker threads. This gives you a fully empty
|
||||
libeio queue.
|
||||
|
||||
=head1 INITIALISATION/INTEGRATION
|
||||
|
||||
Before you can call any eio functions you first have to initialise the
|
||||
library. The library integrates into any event loop, but can also be used
|
||||
without one, including in polling mode.
|
||||
|
||||
You have to provide the necessary glue yourself, however.
|
||||
|
||||
=over 4
|
||||
|
||||
=item int eio_init (void (*want_poll)(void), void (*done_poll)(void))
|
||||
|
||||
This function initialises the library. On success it returns C<0>, on
|
||||
failure it returns C<-1> and sets C<errno> appropriately.
|
||||
|
||||
It accepts two function pointers specifying callbacks as argument, both of
|
||||
which can be C<0>, in which case the callback isn't called.
|
||||
|
||||
=item want_poll callback
|
||||
|
||||
The C<want_poll> callback is invoked whenever libeio wants attention (i.e.
|
||||
it wants to be polled by calling C<eio_poll>). It is "edge-triggered",
|
||||
that is, it will only be called once when eio wants attention, until all
|
||||
pending requests have been handled.
|
||||
|
||||
This callback is called while locks are being held, so I<you must
|
||||
not call any libeio functions inside this callback>. That includes
|
||||
C<eio_poll>. What you should do is notify some other thread, or wake up
|
||||
your event loop, and then call C<eio_poll>.
|
||||
|
||||
=item done_poll callback
|
||||
|
||||
This callback is invoked when libeio detects that all pending requests
|
||||
have been handled. It is "edge-triggered", that is, it will only be
|
||||
called once after C<want_poll>. To put it differently, C<want_poll> and
|
||||
C<done_poll> are invoked in pairs: after C<want_poll> you have to call
|
||||
C<eio_poll ()> until either C<eio_poll> indicates that everything has been
|
||||
handled or C<done_poll> has been called, which signals the same.
|
||||
|
||||
Note that C<eio_poll> might return after C<done_poll> and C<want_poll>
|
||||
have been called again, so watch out for races in your code.
|
||||
|
||||
As with C<want_poll>, this callback is called while lcoks are being held,
|
||||
so you I<must not call any libeio functions form within this callback>.
|
||||
|
||||
=item int eio_poll ()
|
||||
|
||||
This function has to be called whenever there are pending requests that
|
||||
need finishing. You usually call this after C<want_poll> has indicated
|
||||
that you should do so, but you can also call this function regularly to
|
||||
poll for new results.
|
||||
|
||||
If any request invocation returns a non-zero value, then C<eio_poll ()>
|
||||
immediately returns with that value as return value.
|
||||
|
||||
Otherwise, if all requests could be handled, it returns C<0>. If for some
|
||||
reason not all requests have been handled, i.e. some are still pending, it
|
||||
returns C<-1>.
|
||||
|
||||
=back
|
||||
|
||||
For libev, you would typically use an C<ev_async> watcher: the
|
||||
C<want_poll> callback would invoke C<ev_async_send> to wake up the event
|
||||
loop. Inside the callback set for the watcher, one would call C<eio_poll
|
||||
()> (followed by C<ev_async_send> again if C<eio_poll> indicates that not
|
||||
all requests have been handled yet). The race is taken care of because
|
||||
libev resets/rearms the async watcher before calling your callback,
|
||||
and therefore, before calling C<eio_poll>. This might result in (some)
|
||||
spurious wake-ups, but is generally harmless.
|
||||
|
||||
For most other event loops, you would typically use a pipe - the event
|
||||
loop should be told to wait for read readyness on the read end. In
|
||||
C<want_poll> you would write a single byte, in C<done_poll> you would try
|
||||
to read that byte, and in the callback for the read end, you would call
|
||||
C<eio_poll>. The race is avoided here because the event loop should invoke
|
||||
your callback again and again until the byte has been read (as the pipe
|
||||
read callback does not read it, only C<done_poll>).
|
||||
|
||||
=head2 CONFIGURATION
|
||||
|
||||
The functions in this section can sometimes be useful, but the default
|
||||
configuration will do in most case, so you should skip this section on
|
||||
first reading.
|
||||
|
||||
=over 4
|
||||
|
||||
=item eio_set_max_poll_time (eio_tstamp nseconds)
|
||||
|
||||
This causes C<eio_poll ()> to return after it has detected that it was
|
||||
running for C<nsecond> seconds or longer (this number can be fractional).
|
||||
|
||||
This can be used to limit the amount of time spent handling eio requests,
|
||||
for example, in interactive programs, you might want to limit this time to
|
||||
C<0.01> seconds or so.
|
||||
|
||||
Note that:
|
||||
|
||||
a) libeio doesn't know how long your request callbacks take, so the time
|
||||
spent in C<eio_poll> is up to one callback invocation longer then this
|
||||
interval.
|
||||
|
||||
b) this is implemented by calling C<gettimeofday> after each request,
|
||||
which can be costly.
|
||||
|
||||
c) at least one request will be handled.
|
||||
|
||||
=item eio_set_max_poll_reqs (unsigned int nreqs)
|
||||
|
||||
When C<nreqs> is non-zero, then C<eio_poll> will not handle more than
|
||||
C<nreqs> requests per invocation. This is a less costly way to limit the
|
||||
amount of work done by C<eio_poll> then setting a time limit.
|
||||
|
||||
If you know your callbacks are generally fast, you could use this to
|
||||
encourage interactiveness in your programs by setting it to C<10>, C<100>
|
||||
or even C<1000>.
|
||||
|
||||
=item eio_set_min_parallel (unsigned int nthreads)
|
||||
|
||||
Make sure libeio can handle at least this many requests in parallel. It
|
||||
might be able handle more.
|
||||
|
||||
=item eio_set_max_parallel (unsigned int nthreads)
|
||||
|
||||
Set the maximum number of threads that libeio will spawn.
|
||||
|
||||
=item eio_set_max_idle (unsigned int nthreads)
|
||||
|
||||
Libeio uses threads internally to handle most requests, and will start and stop threads on demand.
|
||||
|
||||
This call can be used to limit the number of idle threads (threads without
|
||||
work to do): libeio will keep some threads idle in preperation for more
|
||||
requests, but never longer than C<nthreads> threads.
|
||||
|
||||
In addition to this, libeio will also stop threads when they are idle for
|
||||
a few seconds, regardless of this setting.
|
||||
|
||||
=item unsigned int eio_nthreads ()
|
||||
|
||||
Return the number of worker threads currently running.
|
||||
|
||||
=item unsigned int eio_nreqs ()
|
||||
|
||||
Return the number of requests currently handled by libeio. This is the
|
||||
total number of requests that have been submitted to libeio, but not yet
|
||||
destroyed.
|
||||
|
||||
=item unsigned int eio_nready ()
|
||||
|
||||
Returns the number of ready requests, i.e. requests that have been
|
||||
submitted but have not yet entered the execution phase.
|
||||
|
||||
=item unsigned int eio_npending ()
|
||||
|
||||
Returns the number of pending requests, i.e. requests that have been
|
||||
executed and have results, but have not been finished yet by a call to
|
||||
C<eio_poll>).
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 ANATOMY OF AN EIO REQUEST
|
||||
|
||||
#TODO
|
||||
|
||||
|
||||
=head1 HIGH LEVEL REQUEST API
|
||||
|
||||
#TODO
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 LOW LEVEL REQUEST API
|
||||
|
||||
#TODO
|
||||
|
||||
=head1 EMBEDDING
|
||||
|
||||
Libeio can be embedded directly into programs. This functionality is not
|
||||
documented and not (yet) officially supported.
|
||||
|
||||
Note that, when including C<libeio.m4>, you are responsible for defining
|
||||
the compilation environment (C<_LARGEFILE_SOURCE>, C<_GNU_SOURCE> etc.).
|
||||
|
||||
If you need to know how, check the C<IO::AIO> perl module, which does
|
||||
exactly that.
|
||||
|
||||
|
||||
=head1 COMPILETIME CONFIGURATION
|
||||
|
||||
These symbols, if used, must be defined when compiling F<eio.c>.
|
||||
|
||||
=over 4
|
||||
|
||||
=item EIO_STACKSIZE
|
||||
|
||||
This symbol governs the stack size for each eio thread. Libeio itself
|
||||
was written to use very little stackspace, but when using C<EIO_CUSTOM>
|
||||
requests, you might want to increase this.
|
||||
|
||||
If this symbol is undefined (the default) then libeio will use its default
|
||||
stack size (C<sizeof (long) * 4096> currently). If it is defined, but
|
||||
C<0>, then the default operating system stack size will be used. In all
|
||||
other cases, the value must be an expression that evaluates to the desired
|
||||
stack size.
|
||||
|
||||
=back
|
||||
|
||||
|
||||
=head1 PORTABILITY REQUIREMENTS
|
||||
|
||||
In addition to a working ISO-C implementation, libeio relies on a few
|
||||
additional extensions:
|
||||
|
||||
=over 4
|
||||
|
||||
=item POSIX threads
|
||||
|
||||
To be portable, this module uses threads, specifically, the POSIX threads
|
||||
library must be available (and working, which partially excludes many xBSD
|
||||
systems, where C<fork ()> is buggy).
|
||||
|
||||
=item POSIX-compatible filesystem API
|
||||
|
||||
This is actually a harder portability requirement: The libeio API is quite
|
||||
demanding regarding POSIX API calls (symlinks, user/group management
|
||||
etc.).
|
||||
|
||||
=item C<double> must hold a time value in seconds with enough accuracy
|
||||
|
||||
The type C<double> is used to represent timestamps. It is required to
|
||||
have at least 51 bits of mantissa (and 9 bits of exponent), which is good
|
||||
enough for at least into the year 4000. This requirement is fulfilled by
|
||||
implementations implementing IEEE 754 (basically all existing ones).
|
||||
|
||||
=back
|
||||
|
||||
If you know of other additional requirements drop me a note.
|
||||
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Marc Lehmann <libeio@schmorp.de>.
|
||||
|
||||
Vendored
-156
@@ -1,156 +0,0 @@
|
||||
AC_SEARCH_LIBS(
|
||||
pthread_create,
|
||||
[pthread pthreads pthreadVC2],
|
||||
,
|
||||
[AC_MSG_ERROR(pthread functions not found)]
|
||||
)
|
||||
|
||||
AC_CACHE_CHECK(for utimes, ac_cv_utimes, [AC_LINK_IFELSE([[
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <utime.h>
|
||||
struct timeval tv[2];
|
||||
int res;
|
||||
int main (void)
|
||||
{
|
||||
res = utimes ("/", tv);
|
||||
return 0;
|
||||
}
|
||||
]],ac_cv_utimes=yes,ac_cv_utimes=no)])
|
||||
test $ac_cv_utimes = yes && AC_DEFINE(HAVE_UTIMES, 1, utimes(2) is available)
|
||||
|
||||
AC_CACHE_CHECK(for futimes, ac_cv_futimes, [AC_LINK_IFELSE([[
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <utime.h>
|
||||
struct timeval tv[2];
|
||||
int res;
|
||||
int fd;
|
||||
int main (void)
|
||||
{
|
||||
res = futimes (fd, tv);
|
||||
return 0;
|
||||
}
|
||||
]],ac_cv_futimes=yes,ac_cv_futimes=no)])
|
||||
test $ac_cv_futimes = yes && AC_DEFINE(HAVE_FUTIMES, 1, futimes(2) is available)
|
||||
|
||||
AC_CACHE_CHECK(for readahead, ac_cv_readahead, [AC_LINK_IFELSE([
|
||||
#include <fcntl.h>
|
||||
int main (void)
|
||||
{
|
||||
int fd = 0;
|
||||
size_t count = 2;
|
||||
ssize_t res;
|
||||
res = readahead (fd, 0, count);
|
||||
return 0;
|
||||
}
|
||||
],ac_cv_readahead=yes,ac_cv_readahead=no)])
|
||||
test $ac_cv_readahead = yes && AC_DEFINE(HAVE_READAHEAD, 1, readahead(2) is available (linux))
|
||||
|
||||
AC_CACHE_CHECK(for fdatasync, ac_cv_fdatasync, [AC_LINK_IFELSE([
|
||||
#include <unistd.h>
|
||||
int main (void)
|
||||
{
|
||||
int fd = 0;
|
||||
fdatasync (fd);
|
||||
return 0;
|
||||
}
|
||||
],ac_cv_fdatasync=yes,ac_cv_fdatasync=no)])
|
||||
test $ac_cv_fdatasync = yes && AC_DEFINE(HAVE_FDATASYNC, 1, fdatasync(2) is available)
|
||||
|
||||
AC_CACHE_CHECK(for pread and pwrite, ac_cv_preadwrite, [AC_LINK_IFELSE([
|
||||
#include <unistd.h>
|
||||
int main (void)
|
||||
{
|
||||
int fd = 0;
|
||||
size_t count = 1;
|
||||
char buf;
|
||||
off_t offset = 1;
|
||||
ssize_t res;
|
||||
res = pread (fd, &buf, count, offset);
|
||||
res = pwrite (fd, &buf, count, offset);
|
||||
return 0;
|
||||
}
|
||||
],ac_cv_preadwrite=yes,ac_cv_preadwrite=no)])
|
||||
test $ac_cv_preadwrite = yes && AC_DEFINE(HAVE_PREADWRITE, 1, pread(2) and pwrite(2) are available)
|
||||
|
||||
AC_CACHE_CHECK(for sendfile, ac_cv_sendfile, [AC_LINK_IFELSE([
|
||||
# include <sys/types.h>
|
||||
#if __linux
|
||||
# include <sys/sendfile.h>
|
||||
#elif __FreeBSD__ || defined __APPLE__
|
||||
# include <sys/socket.h>
|
||||
# include <sys/uio.h>
|
||||
#elif __hpux
|
||||
# include <sys/socket.h>
|
||||
#else
|
||||
# error unsupported architecture
|
||||
#endif
|
||||
int main (void)
|
||||
{
|
||||
int fd = 0;
|
||||
off_t offset = 1;
|
||||
size_t count = 2;
|
||||
ssize_t res;
|
||||
#if __linux
|
||||
res = sendfile (fd, fd, offset, count);
|
||||
#elif __FreeBSD__
|
||||
res = sendfile (fd, fd, offset, count, 0, &offset, 0);
|
||||
#elif __hpux
|
||||
res = sendfile (fd, fd, offset, count, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
],ac_cv_sendfile=yes,ac_cv_sendfile=no)])
|
||||
test $ac_cv_sendfile = yes && AC_DEFINE(HAVE_SENDFILE, 1, sendfile(2) is available and supported)
|
||||
|
||||
AC_CACHE_CHECK(for sync_file_range, ac_cv_sync_file_range, [AC_LINK_IFELSE([
|
||||
#include <fcntl.h>
|
||||
int main (void)
|
||||
{
|
||||
int fd = 0;
|
||||
off64_t offset = 1;
|
||||
off64_t nbytes = 1;
|
||||
unsigned int flags = SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER;
|
||||
ssize_t res;
|
||||
res = sync_file_range (fd, offset, nbytes, flags);
|
||||
return 0;
|
||||
}
|
||||
],ac_cv_sync_file_range=yes,ac_cv_sync_file_range=no)])
|
||||
test $ac_cv_sync_file_range = yes && AC_DEFINE(HAVE_SYNC_FILE_RANGE, 1, sync_file_range(2) is available)
|
||||
|
||||
dnl #############################################################################
|
||||
dnl # these checks exist for the benefit of IO::AIO
|
||||
|
||||
dnl at least uclibc defines _POSIX_ADVISORY_INFO without *any* of the required
|
||||
dnl functionality actually being present. ugh.
|
||||
AC_CACHE_CHECK(for posix_madvise, ac_cv_posix_madvise, [AC_LINK_IFELSE([
|
||||
#include <sys/mman.h>
|
||||
int main (void)
|
||||
{
|
||||
int res = posix_madvise ((void *)0, (size_t)0, POSIX_MADV_NORMAL);
|
||||
int a = POSIX_MADV_SEQUENTIAL;
|
||||
int b = POSIX_MADV_RANDOM;
|
||||
int c = POSIX_MADV_WILLNEED;
|
||||
int d = POSIX_MADV_DONTNEED;
|
||||
return 0;
|
||||
}
|
||||
],ac_cv_posix_madvise=yes,ac_cv_posix_madvise=no)])
|
||||
test $ac_cv_posix_madvise = yes && AC_DEFINE(HAVE_POSIX_MADVISE, 1, posix_madvise(2) is available)
|
||||
|
||||
AC_CACHE_CHECK(for posix_fadvise, ac_cv_posix_fadvise, [AC_LINK_IFELSE([
|
||||
#define _XOPEN_SOURCE 600
|
||||
#include <fcntl.h>
|
||||
int main (void)
|
||||
{
|
||||
int res = posix_fadvise ((int)0, (off_t)0, (off_t)0, POSIX_FADV_NORMAL);
|
||||
int a = POSIX_FADV_SEQUENTIAL;
|
||||
int b = POSIX_FADV_NOREUSE;
|
||||
int c = POSIX_FADV_RANDOM;
|
||||
int d = POSIX_FADV_WILLNEED;
|
||||
int e = POSIX_FADV_DONTNEED;
|
||||
return 0;
|
||||
}
|
||||
],ac_cv_posix_fadvise=yes,ac_cv_posix_fadvise=no)])
|
||||
test $ac_cv_posix_fadvise = yes && AC_DEFINE(HAVE_POSIX_FADVISE, 1, posix_fadvise(2) is available)
|
||||
|
||||
Vendored
-131
@@ -1,131 +0,0 @@
|
||||
import Options
|
||||
import sys
|
||||
|
||||
def set_options(opt):
|
||||
pass
|
||||
#opt.tool_options('compiler_cc')
|
||||
|
||||
def configure(conf):
|
||||
print "--- libeio ---"
|
||||
#conf.check_tool('compiler_cc')
|
||||
|
||||
conf.check(lib='pthread', uselib_store='PTHREAD')
|
||||
conf.check_cc(lib="pthread", header_name="pthread.h", function_name="pthread_create", mandatory=True)
|
||||
if sys.platform.startswith("cygwin"):
|
||||
conf.check_cc(lib="pthread", header_name="unistd.h", function_name="pthread_atfork", mandatory=True)
|
||||
elif sys.platform.startswith("win32"):
|
||||
conf.check_cc(lib="pthread", header_name="pthread.h", function_name="pthread_atfork")
|
||||
else:
|
||||
conf.check_cc(lib="pthread", header_name="pthread.h", function_name="pthread_atfork", mandatory=True)
|
||||
|
||||
conf.check_cc(msg="Checking for futimes(2)", define_name="HAVE_FUTIMES", fragment="""
|
||||
#include <sys/types.h>
|
||||
#include <sys/time.h>
|
||||
#include <utime.h>
|
||||
struct timeval tv[2];
|
||||
int res;
|
||||
int fd;
|
||||
int main(void)
|
||||
{
|
||||
res = futimes (fd, tv);
|
||||
return 0;
|
||||
}
|
||||
""")
|
||||
|
||||
conf.check_cc(msg="Checking for readahead(2)", define_name="HAVE_READAHEAD", fragment="""
|
||||
#include <fcntl.h>
|
||||
int main(void)
|
||||
{
|
||||
int fd = 0;
|
||||
size_t count = 2;
|
||||
ssize_t res;
|
||||
res = readahead (fd, 0, count);
|
||||
return 0;
|
||||
}
|
||||
""")
|
||||
|
||||
conf.check_cc(msg="Checking for fdatasync(2)", define_name="HAVE_FDATASYNC", fragment="""
|
||||
#include <unistd.h>
|
||||
int main(void)
|
||||
{
|
||||
int fd = 0;
|
||||
fdatasync (fd);
|
||||
return 0;
|
||||
}
|
||||
""")
|
||||
|
||||
conf.check_cc(msg="Checking for pread(2) and pwrite(2)", define_name="HAVE_PREADWRITE", fragment="""
|
||||
#include <unistd.h>
|
||||
int main(void)
|
||||
{
|
||||
int fd = 0;
|
||||
size_t count = 1;
|
||||
char buf;
|
||||
off_t offset = 1;
|
||||
ssize_t res;
|
||||
res = pread (fd, &buf, count, offset);
|
||||
res = pwrite (fd, &buf, count, offset);
|
||||
return 0;
|
||||
}
|
||||
""")
|
||||
|
||||
conf.check_cc(msg="Checking for sendfile(2)" , define_name="HAVE_SENDFILE" , fragment="""
|
||||
# include <sys/types.h>
|
||||
#if __linux
|
||||
# include <sys/sendfile.h>
|
||||
#elif __FreeBSD__ || defined(__APPLE__)
|
||||
# include <sys/socket.h>
|
||||
# include <sys/uio.h>
|
||||
#elif __hpux
|
||||
# include <sys/socket.h>
|
||||
#else
|
||||
# error unsupported architecture
|
||||
#endif
|
||||
int main(void)
|
||||
{
|
||||
int fd = 0;
|
||||
off_t offset = 1;
|
||||
size_t count = 2;
|
||||
ssize_t res;
|
||||
#if __linux
|
||||
res = sendfile (fd, fd, offset, count);
|
||||
#elif __FreeBSD__
|
||||
res = sendfile (fd, fd, offset, count, 0, &offset, 0);
|
||||
#elif __APPLE__
|
||||
res = sendfile (fd, fd, offset, &offset, 0, 0);
|
||||
#elif __hpux
|
||||
res = sendfile (fd, fd, offset, count, 0, 0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
""")
|
||||
|
||||
conf.env.append_value("CCFLAGS", "-D_GNU_SOURCE")
|
||||
conf.check_cc(msg="Checking for sync_file_range(2) ", fragment="""
|
||||
#include <fcntl.h>
|
||||
int main(void)
|
||||
{
|
||||
int fd = 0;
|
||||
off64_t offset = 1;
|
||||
off64_t nbytes = 1;
|
||||
unsigned int flags = SYNC_FILE_RANGE_WAIT_BEFORE|SYNC_FILE_RANGE_WRITE|SYNC_FILE_RANGE_WAIT_AFTER;
|
||||
ssize_t res;
|
||||
res = sync_file_range (fd, offset, nbytes, flags);
|
||||
return 0;
|
||||
}
|
||||
""", define_name="HAVE_SYNC_FILE_RANGE")
|
||||
|
||||
def build(bld):
|
||||
libeio = bld.new_task_gen("cc")
|
||||
libeio.source = "eio.c"
|
||||
libeio.target = 'eio'
|
||||
libeio.name = 'eio'
|
||||
libeio.includes = '. ../..'
|
||||
libeio.uselib = "PTHREAD"
|
||||
libeio.install_path = None
|
||||
if bld.env["USE_DEBUG"]:
|
||||
libeio.clone("debug");
|
||||
if Options.options.product_type != 'program':
|
||||
libeio.ccflags = "-fPIC"
|
||||
bld.install_files('${PREFIX}/include/node/', 'eio.h');
|
||||
|
||||
Vendored
-159
@@ -1,159 +0,0 @@
|
||||
#ifndef XTHREAD_H_
|
||||
#define XTHREAD_H_
|
||||
|
||||
/* whether word reads are potentially non-atomic.
|
||||
* this is conservatice, likely most arches this runs
|
||||
* on have atomic word read/writes.
|
||||
*/
|
||||
#ifndef WORDACCESS_UNSAFE
|
||||
# if __i386 || __x86_64
|
||||
# define WORDACCESS_UNSAFE 0
|
||||
# else
|
||||
# define WORDACCESS_UNSAFE 1
|
||||
# endif
|
||||
#endif
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#ifndef __MINGW32__
|
||||
typedef int ssize_t
|
||||
#endif
|
||||
|
||||
#define NTDDI_VERSION NTDDI_WIN2K // needed to get win2000 api calls
|
||||
#define _WIN32_WINNT 0x400
|
||||
#include <stdio.h>//D
|
||||
#include <fcntl.h>
|
||||
#include <io.h>
|
||||
#include <time.h>
|
||||
#include <winsock2.h>
|
||||
#include <process.h>
|
||||
#include <windows.h>
|
||||
#include <pthread.h>
|
||||
#define sigset_t int
|
||||
#define pthread_sigmask(a,b,c)
|
||||
#define sigaddset(a,b)
|
||||
#define sigemptyset(s)
|
||||
#define sigfillset(s)
|
||||
|
||||
typedef pthread_mutex_t xmutex_t;
|
||||
#define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
|
||||
#define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
|
||||
#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
|
||||
|
||||
typedef pthread_cond_t xcond_t;
|
||||
#define X_COND_INIT PTHREAD_COND_INITIALIZER
|
||||
#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
|
||||
#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
|
||||
#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
|
||||
|
||||
typedef pthread_t xthread_t;
|
||||
#define X_THREAD_PROC(name) void *name (void *thr_arg)
|
||||
#define X_THREAD_ATFORK(a,b,c)
|
||||
|
||||
static int
|
||||
thread_create (xthread_t *tid, void *(*proc)(void *), void *arg)
|
||||
{
|
||||
int retval;
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
|
||||
retval = pthread_create (tid, &attr, proc, arg) == 0;
|
||||
|
||||
pthread_attr_destroy (&attr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define respipe_read(a,b,c) PerlSock_recv ((a), (b), (c), 0)
|
||||
#define respipe_write(a,b,c) send ((a), (b), (c), 0)
|
||||
#define respipe_close(a) PerlSock_closesocket ((a))
|
||||
|
||||
#else
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#if __linux && !defined(_GNU_SOURCE)
|
||||
# define _GNU_SOURCE
|
||||
#endif
|
||||
|
||||
/* just in case */
|
||||
#define _REENTRANT 1
|
||||
|
||||
#if __solaris
|
||||
# define _POSIX_PTHREAD_SEMANTICS 1
|
||||
/* try to bribe solaris headers into providing a current pthread API
|
||||
* despite environment being configured for an older version.
|
||||
*/
|
||||
# define __EXTENSIONS__ 1
|
||||
#endif
|
||||
|
||||
#include <unistd.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <limits.h>
|
||||
#include <pthread.h>
|
||||
|
||||
typedef pthread_mutex_t xmutex_t;
|
||||
#if __linux && defined (PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP)
|
||||
# define X_MUTEX_INIT PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP
|
||||
#else
|
||||
# define X_MUTEX_INIT PTHREAD_MUTEX_INITIALIZER
|
||||
#endif
|
||||
#define X_LOCK(mutex) pthread_mutex_lock (&(mutex))
|
||||
#define X_UNLOCK(mutex) pthread_mutex_unlock (&(mutex))
|
||||
|
||||
typedef pthread_cond_t xcond_t;
|
||||
#define X_COND_INIT PTHREAD_COND_INITIALIZER
|
||||
#define X_COND_SIGNAL(cond) pthread_cond_signal (&(cond))
|
||||
#define X_COND_WAIT(cond,mutex) pthread_cond_wait (&(cond), &(mutex))
|
||||
#define X_COND_TIMEDWAIT(cond,mutex,to) pthread_cond_timedwait (&(cond), &(mutex), &(to))
|
||||
|
||||
typedef pthread_t xthread_t;
|
||||
#define X_THREAD_PROC(name) static void *name (void *thr_arg)
|
||||
#define X_THREAD_ATFORK(prepare,parent,child) pthread_atfork (prepare, parent, child)
|
||||
|
||||
// the broken bsd's once more
|
||||
#ifndef PTHREAD_STACK_MIN
|
||||
# define PTHREAD_STACK_MIN 0
|
||||
#endif
|
||||
|
||||
#ifndef X_STACKSIZE
|
||||
# define X_STACKSIZE sizeof (long) * 4096
|
||||
#endif
|
||||
|
||||
static int
|
||||
thread_create (xthread_t *tid, void *(*proc)(void *), void *arg)
|
||||
{
|
||||
int retval;
|
||||
sigset_t fullsigset, oldsigset;
|
||||
pthread_attr_t attr;
|
||||
|
||||
pthread_attr_init (&attr);
|
||||
pthread_attr_setdetachstate (&attr, PTHREAD_CREATE_DETACHED);
|
||||
pthread_attr_setstacksize (&attr, PTHREAD_STACK_MIN < X_STACKSIZE ? X_STACKSIZE : PTHREAD_STACK_MIN);
|
||||
#ifdef PTHREAD_SCOPE_PROCESS
|
||||
pthread_attr_setscope (&attr, PTHREAD_SCOPE_PROCESS);
|
||||
#endif
|
||||
|
||||
sigfillset (&fullsigset);
|
||||
|
||||
pthread_sigmask (SIG_SETMASK, &fullsigset, &oldsigset);
|
||||
retval = pthread_create (tid, &attr, proc, arg) == 0;
|
||||
pthread_sigmask (SIG_SETMASK, &oldsigset, 0);
|
||||
|
||||
pthread_attr_destroy (&attr);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
#define respipe_read(a,b,c) read ((a), (b), (c))
|
||||
#define respipe_write(a,b,c) write ((a), (b), (c))
|
||||
#define respipe_close(a) close ((a))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
Vendored
+3
@@ -35,3 +35,6 @@ The externally maintained libraries used by libuv are:
|
||||
|
||||
- libev, located at ev/ is copyright Marc Alexander Lehmann, and
|
||||
dual-licensed under the MIT license and GPL2.
|
||||
|
||||
- libeio, located at eio/ is copyright Marc Alexander Lehmann, and
|
||||
dual-licensed under the MIT license and GPL2.
|
||||
Vendored
-3
@@ -96,9 +96,6 @@ typedef int ares_socklen_t;
|
||||
# include <sys/socket.h>
|
||||
# include <tcp.h>
|
||||
#elif defined(WIN32)
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# include <winsock2.h>
|
||||
# include <ws2tcpip.h>
|
||||
|
||||
Vendored
-3
@@ -108,9 +108,6 @@
|
||||
*/
|
||||
|
||||
#ifdef HAVE_WINDOWS_H
|
||||
# ifndef WIN32_LEAN_AND_MEAN
|
||||
# define WIN32_LEAN_AND_MEAN
|
||||
# endif
|
||||
# include <windows.h>
|
||||
# ifdef HAVE_WINSOCK2_H
|
||||
# include <winsock2.h>
|
||||
|
||||
-3
@@ -474,9 +474,6 @@
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.1"
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
-3
@@ -474,9 +474,6 @@
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.1"
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
-3
@@ -474,9 +474,6 @@
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.1"
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
-3
@@ -474,9 +474,6 @@
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.1"
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
-3
@@ -474,9 +474,6 @@
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.1"
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
-3
@@ -474,9 +474,6 @@
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.1"
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
/* #undef WIN32_LEAN_AND_MEAN */
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
-3
@@ -474,9 +474,6 @@
|
||||
/* Version number of package */
|
||||
#define VERSION "1.7.3"
|
||||
|
||||
/* Define to avoid automatic inclusion of winsock.h */
|
||||
#define WIN32_LEAN_AND_MEAN 1
|
||||
|
||||
/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
|
||||
significant byte first (like Motorola and SPARC, unlike Intel). */
|
||||
#if defined AC_APPLE_UNIVERSAL_BUILD
|
||||
|
||||
Vendored
+26
-3
@@ -24,8 +24,12 @@ E=
|
||||
CFLAGS=--std=gnu89 -Wno-variadic-macros -g
|
||||
LINKFLAGS=-lm
|
||||
|
||||
CPPFLAGS += -D_LARGEFILE_SOURCE
|
||||
CPPFLAGS += -D_FILE_OFFSET_BITS=64
|
||||
|
||||
ifeq (SunOS,$(uname_S))
|
||||
EV_CONFIG=config_sunos.h
|
||||
EIO_CONFIG=config_sunos.h
|
||||
CPPFLAGS += -Ic-ares/config_sunos
|
||||
LINKFLAGS+=-lsocket -lnsl
|
||||
UV_OS_FILE=uv-sunos.c
|
||||
@@ -33,6 +37,7 @@ endif
|
||||
|
||||
ifeq (Darwin,$(uname_S))
|
||||
EV_CONFIG=config_darwin.h
|
||||
EIO_CONFIG=config_darwin.h
|
||||
CPPFLAGS += -Ic-ares/config_darwin
|
||||
LINKFLAGS+=-framework CoreServices
|
||||
UV_OS_FILE=uv-darwin.c
|
||||
@@ -40,6 +45,7 @@ endif
|
||||
|
||||
ifeq (Linux,$(uname_S))
|
||||
EV_CONFIG=config_linux.h
|
||||
EIO_CONFIG=config_linux.h
|
||||
CPPFLAGS += -Ic-ares/config_linux
|
||||
LINKFLAGS+=-lrt
|
||||
UV_OS_FILE=uv-linux.c
|
||||
@@ -47,6 +53,7 @@ endif
|
||||
|
||||
ifeq (FreeBSD,$(uname_S))
|
||||
EV_CONFIG=config_freebsd.h
|
||||
EIO_CONFIG=config_freebsd.h
|
||||
CPPFLAGS += -Ic-ares/config_freebsd
|
||||
LINKFLAGS+=
|
||||
UV_OS_FILE=uv-freebsd.c
|
||||
@@ -59,14 +66,15 @@ RUNNER_LINKFLAGS=$(LINKFLAGS) -pthread
|
||||
RUNNER_LIBS=
|
||||
RUNNER_SRC=test/runner-unix.c
|
||||
|
||||
uv.a: uv-unix.o uv-common.o uv-platform.o ev/ev.o $(CARES_OBJS)
|
||||
$(AR) rcs uv.a uv-unix.o uv-platform.o uv-common.o ev/ev.o $(CARES_OBJS)
|
||||
uv.a: uv-unix.o uv-common.o uv-platform.o ev/ev.o uv-eio.o eio/eio.o $(CARES_OBJS)
|
||||
$(AR) rcs uv.a uv-unix.o uv-platform.o uv-common.o uv-eio.o ev/ev.o \
|
||||
eio/eio.o $(CARES_OBJS)
|
||||
|
||||
uv-platform.o: $(UV_OS_FILE) uv.h uv-unix.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c $(UV_OS_FILE) -o uv-platform.o
|
||||
|
||||
uv-unix.o: uv-unix.c uv.h uv-unix.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c uv-unix.c -o uv-unix.o
|
||||
$(CC) $(CPPFLAGS) -Ieio $(CFLAGS) -c uv-unix.c -o uv-unix.o
|
||||
|
||||
uv-common.o: uv-common.c uv.h uv-unix.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c uv-common.c -o uv-common.o
|
||||
@@ -74,12 +82,27 @@ uv-common.o: uv-common.c uv.h uv-unix.h
|
||||
ev/ev.o: ev/ev.c
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) -c ev/ev.c -o ev/ev.o -DEV_CONFIG_H=\"$(EV_CONFIG)\"
|
||||
|
||||
|
||||
EIO_CPPFLAGS += $(CPPFLAGS)
|
||||
EIO_CPPFLAGS += -DEIO_CONFIG_H=\"$(EIO_CONFIG)\"
|
||||
EIO_CPPFLAGS += -DEIO_STACKSIZE=65536
|
||||
EIO_CPPFLAGS += -D_GNU_SOURCE
|
||||
|
||||
eio/eio.o: eio/eio.c
|
||||
$(CC) $(EIO_CPPFLAGS) $(CFLAGS) -c eio/eio.c -o eio/eio.o
|
||||
|
||||
uv-eio.o: uv-eio.c
|
||||
$(CC) $(CPPFLAGS) -Ieio/ $(CFLAGS) -c uv-eio.c -o uv-eio.o
|
||||
|
||||
|
||||
clean-platform:
|
||||
-rm -f c-ares/*.o
|
||||
-rm -f ev/*.o
|
||||
-rm -f eio/*.o
|
||||
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM
|
||||
|
||||
distclean-platform:
|
||||
-rm -f c-ares/*.o
|
||||
-rm -f ev/*.o
|
||||
-rm -f eio/*.o
|
||||
-rm -rf test/run-tests.dSYM run-benchmarks.dSYM
|
||||
Vendored
+5
-5
@@ -52,7 +52,7 @@ static int completed_pingers = 0;
|
||||
static int64_t start_time;
|
||||
|
||||
|
||||
static uv_buf_t buf_alloc(uv_tcp_t* tcp, size_t size) {
|
||||
static uv_buf_t buf_alloc(uv_stream_t* tcp, size_t size) {
|
||||
buf_t* ab;
|
||||
|
||||
ab = buf_freelist;
|
||||
@@ -125,7 +125,7 @@ static void pinger_shutdown_cb(uv_handle_t* handle, int status) {
|
||||
}
|
||||
|
||||
|
||||
static void pinger_read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
unsigned int i;
|
||||
pinger_t* pinger;
|
||||
|
||||
@@ -171,7 +171,7 @@ static void pinger_connect_cb(uv_req_t *req, int status) {
|
||||
|
||||
pinger_write_ping(pinger);
|
||||
|
||||
if (uv_read_start((uv_tcp_t*)(req->handle), buf_alloc, pinger_read_cb)) {
|
||||
if (uv_read_start((uv_stream_t*)(req->handle), buf_alloc, pinger_read_cb)) {
|
||||
FATAL("uv_read_start failed");
|
||||
}
|
||||
}
|
||||
@@ -198,8 +198,8 @@ static void pinger_new() {
|
||||
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);
|
||||
uv_tcp_bind(&pinger->tcp, client_addr);
|
||||
r = uv_tcp_connect(&pinger->connect_req, server_addr);
|
||||
ASSERT(!r);
|
||||
}
|
||||
|
||||
|
||||
Vendored
+14
-14
@@ -35,13 +35,13 @@ static int TARGET_CONNECTIONS;
|
||||
#define STATS_COUNT 5
|
||||
|
||||
|
||||
static void do_write(uv_tcp_t*);
|
||||
static void do_write(uv_stream_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 uv_buf_t buf_alloc(uv_stream_t*, size_t size);
|
||||
static void buf_free(uv_buf_t uv_buf_t);
|
||||
|
||||
|
||||
@@ -154,7 +154,7 @@ static void start_stats_collection() {
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t bytes, uv_buf_t buf) {
|
||||
static void read_cb(uv_stream_t* tcp, ssize_t bytes, uv_buf_t buf) {
|
||||
if (nrecv_total == 0) {
|
||||
ASSERT(start_time == 0);
|
||||
uv_update_time();
|
||||
@@ -183,11 +183,11 @@ static void write_cb(uv_req_t *req, int status) {
|
||||
nsent += sizeof write_buffer;
|
||||
nsent_total += sizeof write_buffer;
|
||||
|
||||
do_write((uv_tcp_t*)req->handle);
|
||||
do_write((uv_stream_t*)req->handle);
|
||||
}
|
||||
|
||||
|
||||
static void do_write(uv_tcp_t* tcp) {
|
||||
static void do_write(uv_stream_t* tcp) {
|
||||
uv_req_t* req;
|
||||
uv_buf_t buf;
|
||||
int r;
|
||||
@@ -221,7 +221,7 @@ static void connect_cb(uv_req_t* req, int status) {
|
||||
|
||||
/* Yay! start writing */
|
||||
for (i = 0; i < write_sockets; i++) {
|
||||
do_write(&write_handles[i]);
|
||||
do_write((uv_stream_t*)&write_handles[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -241,27 +241,27 @@ static void maybe_connect_some() {
|
||||
|
||||
req = req_alloc();
|
||||
uv_req_init(req, (uv_handle_t*)tcp, connect_cb);
|
||||
r = uv_connect(req, connect_addr);
|
||||
r = uv_tcp_connect(req, connect_addr);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void connection_cb(uv_tcp_t* s, int status) {
|
||||
static void connection_cb(uv_handle_t* s, int status) {
|
||||
uv_tcp_t* tcp;
|
||||
int r;
|
||||
|
||||
ASSERT(&server == s);
|
||||
ASSERT(&server == (uv_tcp_t*)s);
|
||||
ASSERT(status == 0);
|
||||
|
||||
tcp = malloc(sizeof(uv_tcp_t));
|
||||
|
||||
uv_tcp_init(tcp);
|
||||
|
||||
r = uv_accept(s, tcp);
|
||||
r = uv_accept(s, (uv_stream_t*)tcp);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start(tcp, buf_alloc, read_cb);
|
||||
r = uv_read_start((uv_stream_t*)tcp, buf_alloc, read_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
read_sockets++;
|
||||
@@ -317,7 +317,7 @@ typedef struct buf_list_s {
|
||||
static buf_list_t* buf_freelist = NULL;
|
||||
|
||||
|
||||
static uv_buf_t buf_alloc(uv_tcp_t* tcp, size_t size) {
|
||||
static uv_buf_t buf_alloc(uv_stream_t* tcp, size_t size) {
|
||||
buf_list_t* buf;
|
||||
|
||||
buf = buf_freelist;
|
||||
@@ -351,9 +351,9 @@ HELPER_IMPL(pump_server) {
|
||||
/* Server */
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, listen_addr);
|
||||
r = uv_tcp_bind(&server, listen_addr);
|
||||
ASSERT(r == 0);
|
||||
r = uv_listen(&server, MAX_WRITE_HANDLES, connection_cb);
|
||||
r = uv_tcp_listen(&server, MAX_WRITE_HANDLES, connection_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_run();
|
||||
|
||||
Vendored
+10
-10
@@ -52,10 +52,10 @@ 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 after_read(uv_stream_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 on_connection(uv_handle_t*, int status);
|
||||
|
||||
#define WRITE_BUF_LEN (64*1024)
|
||||
#define DNSREC_LEN (4)
|
||||
@@ -115,7 +115,7 @@ static void addrsp(write_req_t* wr, char* hdr) {
|
||||
wr->buf.len += rsplen;
|
||||
}
|
||||
|
||||
static void process_req(uv_tcp_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
static void process_req(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
write_req_t *wr;
|
||||
dnshandle* dns = (dnshandle*)handle;
|
||||
char hdrbuf[DNSREC_LEN];
|
||||
@@ -216,7 +216,7 @@ static void process_req(uv_tcp_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
}
|
||||
}
|
||||
|
||||
static void after_read(uv_tcp_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
uv_req_t* req;
|
||||
|
||||
if (nread < 0) {
|
||||
@@ -249,7 +249,7 @@ static void on_close(uv_handle_t* peer) {
|
||||
}
|
||||
|
||||
|
||||
static uv_buf_t buf_alloc(uv_tcp_t* handle, size_t suggested_size) {
|
||||
static uv_buf_t buf_alloc(uv_stream_t* handle, size_t suggested_size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*) malloc(suggested_size);
|
||||
buf.len = suggested_size;
|
||||
@@ -257,7 +257,7 @@ static uv_buf_t buf_alloc(uv_tcp_t* handle, size_t suggested_size) {
|
||||
}
|
||||
|
||||
|
||||
static void on_connection(uv_tcp_t* server, int status) {
|
||||
static void on_connection(uv_handle_t* server, int status) {
|
||||
dnshandle* handle;
|
||||
int r;
|
||||
|
||||
@@ -273,10 +273,10 @@ static void on_connection(uv_tcp_t* server, int status) {
|
||||
|
||||
uv_tcp_init((uv_tcp_t*)handle);
|
||||
|
||||
r = uv_accept(server, (uv_tcp_t*)handle);
|
||||
r = uv_accept(server, (uv_stream_t*)handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start((uv_tcp_t*)handle, buf_alloc, after_read);
|
||||
r = uv_read_start((uv_stream_t*)handle, buf_alloc, after_read);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
@@ -297,14 +297,14 @@ static int dns_start(int port) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_bind(&server, addr);
|
||||
r = uv_tcp_bind(&server, addr);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Bind error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_listen(&server, 128, on_connection);
|
||||
r = uv_tcp_listen(&server, 128, on_connection);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Listen error\n");
|
||||
|
||||
Vendored
+9
-9
@@ -36,10 +36,10 @@ 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 after_read(uv_stream_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 on_connection(uv_handle_t*, int status);
|
||||
|
||||
|
||||
static void after_write(uv_req_t* req, int status) {
|
||||
@@ -65,7 +65,7 @@ static void after_shutdown(uv_req_t* req, int status) {
|
||||
}
|
||||
|
||||
|
||||
static void after_read(uv_tcp_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
static void after_read(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
int i;
|
||||
write_req_t *wr;
|
||||
uv_req_t* req;
|
||||
@@ -117,7 +117,7 @@ static void on_close(uv_handle_t* peer) {
|
||||
}
|
||||
|
||||
|
||||
static uv_buf_t echo_alloc(uv_tcp_t* handle, size_t suggested_size) {
|
||||
static uv_buf_t echo_alloc(uv_stream_t* handle, size_t suggested_size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*) malloc(suggested_size);
|
||||
buf.len = suggested_size;
|
||||
@@ -125,7 +125,7 @@ static uv_buf_t echo_alloc(uv_tcp_t* handle, size_t suggested_size) {
|
||||
}
|
||||
|
||||
|
||||
static void on_connection(uv_tcp_t* server, int status) {
|
||||
static void on_connection(uv_handle_t* server, int status) {
|
||||
uv_tcp_t* handle;
|
||||
int r;
|
||||
|
||||
@@ -136,10 +136,10 @@ static void on_connection(uv_tcp_t* server, int status) {
|
||||
|
||||
uv_tcp_init(handle);
|
||||
|
||||
r = uv_accept(server, handle);
|
||||
r = uv_accept(server, (uv_stream_t*)handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_read_start(handle, echo_alloc, after_read);
|
||||
r = uv_read_start((uv_stream_t*)handle, echo_alloc, after_read);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
@@ -160,14 +160,14 @@ static int echo_start(int port) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_bind(&server, addr);
|
||||
r = uv_tcp_bind(&server, addr);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Bind error\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
r = uv_listen(&server, 128, on_connection);
|
||||
r = uv_tcp_listen(&server, 128, on_connection);
|
||||
if (r) {
|
||||
/* TODO: Error codes */
|
||||
fprintf(stderr, "Listen error\n");
|
||||
|
||||
Vendored
+10
-10
@@ -43,17 +43,17 @@ TEST_IMPL(bind_error_addrinuse) {
|
||||
|
||||
r = uv_tcp_init(&server1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server1, addr);
|
||||
r = uv_tcp_bind(&server1, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_tcp_init(&server2);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server2, addr);
|
||||
r = uv_tcp_bind(&server2, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_listen(&server1, 128, NULL);
|
||||
r = uv_tcp_listen(&server1, 128, NULL);
|
||||
ASSERT(r == 0);
|
||||
r = uv_listen(&server2, 128, NULL);
|
||||
r = uv_tcp_listen(&server2, 128, NULL);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EADDRINUSE);
|
||||
@@ -78,7 +78,7 @@ TEST_IMPL(bind_error_addrnotavail_1) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr);
|
||||
r = uv_tcp_bind(&server, addr);
|
||||
|
||||
/* It seems that Linux is broken here - bind succeeds. */
|
||||
if (r == -1) {
|
||||
@@ -104,7 +104,7 @@ TEST_IMPL(bind_error_addrnotavail_2) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr);
|
||||
r = uv_tcp_bind(&server, addr);
|
||||
ASSERT(r == -1);
|
||||
ASSERT(uv_last_error().code == UV_EADDRNOTAVAIL);
|
||||
|
||||
@@ -130,7 +130,7 @@ TEST_IMPL(bind_error_fault) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, *garbage_addr);
|
||||
r = uv_tcp_bind(&server, *garbage_addr);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EFAULT);
|
||||
@@ -156,9 +156,9 @@ TEST_IMPL(bind_error_inval) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr1);
|
||||
r = uv_tcp_bind(&server, addr1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr2);
|
||||
r = uv_tcp_bind(&server, addr2);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EINVAL);
|
||||
@@ -183,7 +183,7 @@ TEST_IMPL(bind_localhost_ok) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind(&server, addr);
|
||||
r = uv_tcp_bind(&server, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
return 0;
|
||||
|
||||
Vendored
+9
-9
@@ -43,17 +43,17 @@ TEST_IMPL(bind6_error_addrinuse) {
|
||||
|
||||
r = uv_tcp_init(&server1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind6(&server1, addr);
|
||||
r = uv_tcp_bind6(&server1, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_tcp_init(&server2);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind6(&server2, addr);
|
||||
r = uv_tcp_bind6(&server2, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_listen(&server1, 128, NULL);
|
||||
r = uv_tcp_listen(&server1, 128, NULL);
|
||||
ASSERT(r == 0);
|
||||
r = uv_listen(&server2, 128, NULL);
|
||||
r = uv_tcp_listen(&server2, 128, NULL);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EADDRINUSE);
|
||||
@@ -78,7 +78,7 @@ TEST_IMPL(bind6_error_addrnotavail) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind6(&server, addr);
|
||||
r = uv_tcp_bind6(&server, addr);
|
||||
ASSERT(r == -1);
|
||||
ASSERT(uv_last_error().code == UV_EADDRNOTAVAIL);
|
||||
|
||||
@@ -104,7 +104,7 @@ TEST_IMPL(bind6_error_fault) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind6(&server, *garbage_addr);
|
||||
r = uv_tcp_bind6(&server, *garbage_addr);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EFAULT);
|
||||
@@ -130,9 +130,9 @@ TEST_IMPL(bind6_error_inval) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind6(&server, addr1);
|
||||
r = uv_tcp_bind6(&server, addr1);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind6(&server, addr2);
|
||||
r = uv_tcp_bind6(&server, addr2);
|
||||
ASSERT(r == -1);
|
||||
|
||||
ASSERT(uv_last_error().code == UV_EINVAL);
|
||||
@@ -157,7 +157,7 @@ TEST_IMPL(bind6_localhost_ok) {
|
||||
|
||||
r = uv_tcp_init(&server);
|
||||
ASSERT(r == 0);
|
||||
r = uv_bind6(&server, addr);
|
||||
r = uv_tcp_bind6(&server, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
return 0;
|
||||
|
||||
Vendored
+5
-5
@@ -43,7 +43,7 @@ static int bytes_received = 0;
|
||||
static int shutdown_cb_called = 0;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
static uv_buf_t alloc_cb(uv_stream_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.len = size;
|
||||
buf.base = (char*) malloc(size);
|
||||
@@ -67,7 +67,7 @@ static void shutdown_cb(uv_req_t* req, int status) {
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
static void read_cb(uv_stream_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);
|
||||
@@ -119,7 +119,7 @@ static void timer_cb(uv_timer_t* handle, int status) {
|
||||
puts("Timeout complete. Now read data...");
|
||||
|
||||
nested++;
|
||||
if (uv_read_start(&client, alloc_cb, read_cb)) {
|
||||
if (uv_read_start((uv_stream_t*)&client, alloc_cb, read_cb)) {
|
||||
FATAL("uv_read_start failed");
|
||||
}
|
||||
nested--;
|
||||
@@ -192,8 +192,8 @@ TEST_IMPL(callback_stack) {
|
||||
|
||||
nested++;
|
||||
uv_req_init(&connect_req, (uv_handle_t*)&client, connect_cb);
|
||||
if (uv_connect(&connect_req, addr)) {
|
||||
FATAL("uv_connect failed");
|
||||
if (uv_tcp_connect(&connect_req, addr)) {
|
||||
FATAL("uv_tcp_connect failed");
|
||||
}
|
||||
nested--;
|
||||
|
||||
|
||||
Vendored
+2
-2
@@ -105,8 +105,8 @@ void connection_fail(uv_connect_cb connect_cb) {
|
||||
/* 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);
|
||||
uv_tcp_bind(&tcp, client_addr);
|
||||
r = uv_tcp_connect(&req, server_addr);
|
||||
ASSERT(!r);
|
||||
|
||||
uv_run();
|
||||
|
||||
Vendored
+8
-8
@@ -32,7 +32,7 @@ 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) {
|
||||
static uv_buf_t alloc_cb(uv_stream_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
@@ -65,7 +65,7 @@ static void do_accept(uv_timer_t* timer_handle, int status) {
|
||||
tcpcnt = uv_counters()->tcp_init;
|
||||
|
||||
server = (uv_tcp_t*)timer_handle->data;
|
||||
r = uv_accept(server, accepted_handle);
|
||||
r = uv_accept((uv_handle_t*)server, (uv_stream_t*)accepted_handle);
|
||||
ASSERT(r == 0);
|
||||
|
||||
ASSERT(uv_counters()->tcp_init == tcpcnt);
|
||||
@@ -88,7 +88,7 @@ static void do_accept(uv_timer_t* timer_handle, int status) {
|
||||
}
|
||||
|
||||
|
||||
static void connection_cb(uv_tcp_t* tcp, int status) {
|
||||
static void connection_cb(uv_handle_t* tcp, int status) {
|
||||
int r;
|
||||
uv_timer_t* timer_handle;
|
||||
|
||||
@@ -122,15 +122,15 @@ static void start_server() {
|
||||
ASSERT(uv_counters()->tcp_init == 1);
|
||||
ASSERT(uv_counters()->handle_init == 1);
|
||||
|
||||
r = uv_bind(server, addr);
|
||||
r = uv_tcp_bind(server, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
r = uv_listen(server, 128, connection_cb);
|
||||
r = uv_tcp_listen(server, 128, connection_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
/* The server will not send anything, it should close gracefully. */
|
||||
|
||||
if (buf.base) {
|
||||
@@ -157,7 +157,7 @@ static void connect_cb(uv_req_t* req, int status) {
|
||||
|
||||
/* 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);
|
||||
r = uv_read_start((uv_stream_t*)(req->handle), alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
|
||||
connect_cb_called++;
|
||||
@@ -179,7 +179,7 @@ static void client_connect() {
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_req_init(connect_req, (uv_handle_t*)client, connect_cb);
|
||||
r = uv_connect(connect_req, addr);
|
||||
r = uv_tcp_connect(connect_req, addr);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
|
||||
Vendored
+4
-4
@@ -48,7 +48,7 @@ typedef struct {
|
||||
void pinger_try_read(pinger_t* pinger);
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
static uv_buf_t alloc_cb(uv_stream_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
@@ -92,7 +92,7 @@ static void pinger_write_ping(pinger_t* pinger) {
|
||||
}
|
||||
|
||||
|
||||
static void pinger_read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
static void pinger_read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
unsigned int i;
|
||||
pinger_t* pinger;
|
||||
|
||||
@@ -137,7 +137,7 @@ static void pinger_on_connect(uv_req_t *req, int status) {
|
||||
|
||||
pinger_write_ping(pinger);
|
||||
|
||||
uv_read_start((uv_tcp_t*)(req->handle), alloc_cb, pinger_read_cb);
|
||||
uv_read_start((uv_stream_t*)(req->handle), alloc_cb, pinger_read_cb);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,7 +160,7 @@ static void pinger_new() {
|
||||
uv_req_init(&pinger->connect_req, (uv_handle_t*)(&pinger->tcp),
|
||||
pinger_on_connect);
|
||||
|
||||
r = uv_connect(&pinger->connect_req, server_addr);
|
||||
r = uv_tcp_connect(&pinger->connect_req, server_addr);
|
||||
ASSERT(!r);
|
||||
}
|
||||
|
||||
|
||||
Vendored
+5
-5
@@ -37,7 +37,7 @@ static int called_timer_close_cb;
|
||||
static int called_timer_cb;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
static uv_buf_t alloc_cb(uv_stream_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
@@ -45,10 +45,10 @@ static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* t, ssize_t nread, uv_buf_t buf) {
|
||||
static void read_cb(uv_stream_t* t, ssize_t nread, uv_buf_t buf) {
|
||||
uv_err_t err = uv_last_error();
|
||||
|
||||
ASSERT(t == &tcp);
|
||||
ASSERT((uv_tcp_t*)t == &tcp);
|
||||
|
||||
if (nread == 0) {
|
||||
ASSERT(err.code == UV_EAGAIN);
|
||||
@@ -92,7 +92,7 @@ static void connect_cb(uv_req_t *req, int status) {
|
||||
ASSERT(req == &connect_req);
|
||||
|
||||
/* Start reading from our connection so we can receive the EOF. */
|
||||
uv_read_start(&tcp, alloc_cb, read_cb);
|
||||
uv_read_start((uv_stream_t*)&tcp, alloc_cb, read_cb);
|
||||
|
||||
/*
|
||||
* Write the letter 'Q' to gracefully kill the echo-server. This will not
|
||||
@@ -166,7 +166,7 @@ TEST_IMPL(shutdown_eof) {
|
||||
ASSERT(!r);
|
||||
|
||||
uv_req_init(&connect_req, (uv_handle_t*) &tcp, connect_cb);
|
||||
r = uv_connect(&connect_req, server_addr);
|
||||
r = uv_tcp_connect(&connect_req, server_addr);
|
||||
ASSERT(!r);
|
||||
|
||||
uv_run();
|
||||
|
||||
Vendored
+4
-4
@@ -45,7 +45,7 @@ static int bytes_received = 0;
|
||||
static int bytes_received_done = 0;
|
||||
|
||||
|
||||
static uv_buf_t alloc_cb(uv_tcp_t* tcp, size_t size) {
|
||||
static uv_buf_t alloc_cb(uv_stream_t* tcp, size_t size) {
|
||||
uv_buf_t buf;
|
||||
buf.base = (char*)malloc(size);
|
||||
buf.len = size;
|
||||
@@ -83,7 +83,7 @@ static void shutdown_cb(uv_req_t* req, int status) {
|
||||
}
|
||||
|
||||
|
||||
static void read_cb(uv_tcp_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
static void read_cb(uv_stream_t* tcp, ssize_t nread, uv_buf_t buf) {
|
||||
ASSERT(tcp != NULL);
|
||||
|
||||
if (nread < 0) {
|
||||
@@ -161,7 +161,7 @@ static void connect_cb(uv_req_t* req, int status) {
|
||||
ASSERT(req != NULL);
|
||||
|
||||
uv_req_init(req, (uv_handle_t*)tcp, read_cb);
|
||||
r = uv_read_start(tcp, alloc_cb, read_cb);
|
||||
r = uv_read_start((uv_stream_t*)tcp, alloc_cb, read_cb);
|
||||
ASSERT(r == 0);
|
||||
}
|
||||
|
||||
@@ -185,7 +185,7 @@ TEST_IMPL(tcp_writealot) {
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_req_init(connect_req, (uv_handle_t*)client, connect_cb);
|
||||
r = uv_connect(connect_req, addr);
|
||||
r = uv_tcp_connect(connect_req, addr);
|
||||
ASSERT(r == 0);
|
||||
|
||||
uv_run();
|
||||
|
||||
Vendored
+3
@@ -24,6 +24,9 @@
|
||||
#include <stddef.h>
|
||||
#include <time.h>
|
||||
|
||||
#undef NANOSEC
|
||||
#define NANOSEC 1000000
|
||||
|
||||
/*
|
||||
* There's probably some way to get time from Linux than gettimeofday(). What
|
||||
* it is, I don't know.
|
||||
|
||||
Vendored
+99
-25
@@ -20,6 +20,7 @@
|
||||
|
||||
#include "uv.h"
|
||||
#include "uv-common.h"
|
||||
#include "uv-eio.h"
|
||||
|
||||
#include <stddef.h> /* NULL */
|
||||
#include <stdio.h> /* printf */
|
||||
@@ -64,7 +65,6 @@ static void uv__tcp_connect(uv_tcp_t*);
|
||||
int uv_tcp_open(uv_tcp_t*, int fd);
|
||||
static void uv__finish_close(uv_handle_t* handle);
|
||||
|
||||
|
||||
/* flags */
|
||||
enum {
|
||||
UV_CLOSING = 0x00000001, /* uv_close() called but not finished. */
|
||||
@@ -310,7 +310,7 @@ int uv__bind(uv_tcp_t* tcp, int domain, struct sockaddr* addr, int addrsize) {
|
||||
}
|
||||
|
||||
|
||||
int uv_bind(uv_tcp_t* tcp, struct sockaddr_in addr) {
|
||||
int uv_tcp_bind(uv_tcp_t* tcp, struct sockaddr_in addr) {
|
||||
if (addr.sin_family != AF_INET) {
|
||||
uv_err_new((uv_handle_t*)tcp, EFAULT);
|
||||
return -1;
|
||||
@@ -320,7 +320,7 @@ int uv_bind(uv_tcp_t* tcp, struct sockaddr_in addr) {
|
||||
}
|
||||
|
||||
|
||||
int uv_bind6(uv_tcp_t* tcp, struct sockaddr_in6 addr) {
|
||||
int uv_tcp_bind6(uv_tcp_t* tcp, struct sockaddr_in6 addr) {
|
||||
if (addr.sin6_family != AF_INET6) {
|
||||
uv_err_new((uv_handle_t*)tcp, EFAULT);
|
||||
return -1;
|
||||
@@ -391,12 +391,12 @@ void uv__server_io(EV_P_ ev_io* watcher, int revents) {
|
||||
return;
|
||||
} else {
|
||||
uv_err_new((uv_handle_t*)tcp, errno);
|
||||
tcp->connection_cb(tcp, -1);
|
||||
tcp->connection_cb((uv_handle_t*)tcp, -1);
|
||||
}
|
||||
|
||||
} else {
|
||||
tcp->accepted_fd = fd;
|
||||
tcp->connection_cb(tcp, 0);
|
||||
tcp->connection_cb((uv_handle_t*)tcp, 0);
|
||||
if (tcp->accepted_fd >= 0) {
|
||||
/* The user hasn't yet accepted called uv_accept() */
|
||||
ev_io_stop(EV_DEFAULT_ &tcp->read_watcher);
|
||||
@@ -407,26 +407,29 @@ void uv__server_io(EV_P_ ev_io* watcher, int revents) {
|
||||
}
|
||||
|
||||
|
||||
int uv_accept(uv_tcp_t* server, uv_tcp_t* client) {
|
||||
if (server->accepted_fd < 0) {
|
||||
uv_err_new((uv_handle_t*) server, EAGAIN);
|
||||
int uv_accept(uv_handle_t* server, uv_stream_t* client) {
|
||||
uv_tcp_t* tcpServer = (uv_tcp_t*)server;
|
||||
uv_tcp_t* tcpClient = (uv_tcp_t*)client;
|
||||
|
||||
if (tcpServer->accepted_fd < 0) {
|
||||
uv_err_new(server, EAGAIN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uv_tcp_open(client, server->accepted_fd)) {
|
||||
if (uv_tcp_open(tcpClient, tcpServer->accepted_fd)) {
|
||||
/* Ignore error for now */
|
||||
server->accepted_fd = -1;
|
||||
close(server->accepted_fd);
|
||||
tcpServer->accepted_fd = -1;
|
||||
close(tcpServer->accepted_fd);
|
||||
return -1;
|
||||
} else {
|
||||
server->accepted_fd = -1;
|
||||
ev_io_start(EV_DEFAULT_ &server->read_watcher);
|
||||
tcpServer->accepted_fd = -1;
|
||||
ev_io_start(EV_DEFAULT_ &tcpServer->read_watcher);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int uv_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
||||
int uv_tcp_listen(uv_tcp_t* tcp, int backlog, uv_connection_cb cb) {
|
||||
int r;
|
||||
|
||||
assert(tcp->fd >= 0);
|
||||
@@ -723,7 +726,7 @@ void uv__read(uv_tcp_t* tcp) {
|
||||
*/
|
||||
while (tcp->read_cb && uv_flag_is_set((uv_handle_t*)tcp, UV_READING)) {
|
||||
assert(tcp->alloc_cb);
|
||||
buf = tcp->alloc_cb(tcp, 64 * 1024);
|
||||
buf = tcp->alloc_cb((uv_stream_t*)tcp, 64 * 1024);
|
||||
|
||||
assert(buf.len > 0);
|
||||
assert(buf.base);
|
||||
@@ -740,12 +743,12 @@ void uv__read(uv_tcp_t* tcp) {
|
||||
ev_io_start(EV_DEFAULT_UC_ &tcp->read_watcher);
|
||||
}
|
||||
uv_err_new((uv_handle_t*)tcp, EAGAIN);
|
||||
tcp->read_cb(tcp, 0, buf);
|
||||
tcp->read_cb((uv_stream_t*)tcp, 0, buf);
|
||||
return;
|
||||
} else {
|
||||
/* Error. User should call uv_close(). */
|
||||
uv_err_new((uv_handle_t*)tcp, errno);
|
||||
tcp->read_cb(tcp, -1, buf);
|
||||
tcp->read_cb((uv_stream_t*)tcp, -1, buf);
|
||||
assert(!ev_is_active(&tcp->read_watcher));
|
||||
return;
|
||||
}
|
||||
@@ -753,11 +756,11 @@ void uv__read(uv_tcp_t* tcp) {
|
||||
/* EOF */
|
||||
uv_err_new_artificial((uv_handle_t*)tcp, UV_EOF);
|
||||
ev_io_stop(EV_DEFAULT_UC_ &tcp->read_watcher);
|
||||
tcp->read_cb(tcp, -1, buf);
|
||||
tcp->read_cb((uv_stream_t*)tcp, -1, buf);
|
||||
return;
|
||||
} else {
|
||||
/* Successful read */
|
||||
tcp->read_cb(tcp, nread, buf);
|
||||
tcp->read_cb((uv_stream_t*)tcp, nread, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -873,7 +876,7 @@ static void uv__tcp_connect(uv_tcp_t* tcp) {
|
||||
}
|
||||
|
||||
|
||||
int uv_connect(uv_req_t* req, struct sockaddr_in addr) {
|
||||
int uv_tcp_connect(uv_req_t* req, struct sockaddr_in addr) {
|
||||
uv_tcp_t* tcp = (uv_tcp_t*)req->handle;
|
||||
int addrsize;
|
||||
int r;
|
||||
@@ -1027,7 +1030,9 @@ int64_t uv_now() {
|
||||
}
|
||||
|
||||
|
||||
int uv_read_start(uv_tcp_t* tcp, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
|
||||
int uv_read_start(uv_stream_t* stream, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
|
||||
uv_tcp_t* tcp = (uv_tcp_t*)stream;
|
||||
|
||||
/* The UV_READING flag is irrelevant of the state of the tcp - it just
|
||||
* expresses the desired state of the user.
|
||||
*/
|
||||
@@ -1052,7 +1057,9 @@ int uv_read_start(uv_tcp_t* tcp, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
|
||||
}
|
||||
|
||||
|
||||
int uv_read_stop(uv_tcp_t* tcp) {
|
||||
int uv_read_stop(uv_stream_t* stream) {
|
||||
uv_tcp_t* tcp = (uv_tcp_t*)stream;
|
||||
|
||||
uv_flag_unset((uv_handle_t*)tcp, UV_READING);
|
||||
|
||||
ev_io_stop(EV_DEFAULT_UC_ &tcp->read_watcher);
|
||||
@@ -1482,12 +1489,79 @@ void uv_ares_destroy(ares_channel channel) {
|
||||
}
|
||||
|
||||
|
||||
static int uv_getaddrinfo_done(eio_req* req) {
|
||||
uv_getaddrinfo_t* handle = req->data;
|
||||
|
||||
uv_unref();
|
||||
|
||||
free(handle->hints);
|
||||
free(handle->service);
|
||||
free(handle->hostname);
|
||||
|
||||
if (handle->retcode != 0) {
|
||||
/* TODO how to display gai error strings? */
|
||||
uv_err_new(NULL, handle->retcode);
|
||||
}
|
||||
|
||||
handle->cb(handle, handle->retcode, handle->res);
|
||||
|
||||
freeaddrinfo(handle->res);
|
||||
handle->res = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int getaddrinfo_thread_proc(eio_req *req) {
|
||||
uv_getaddrinfo_t* handle = req->data;
|
||||
|
||||
handle->retcode = getaddrinfo(handle->hostname,
|
||||
handle->service,
|
||||
&handle->hints,
|
||||
&handle->res);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* stub implementation of uv_getaddrinfo */
|
||||
int uv_getaddrinfo(uv_getaddrinfo_t* handle,
|
||||
uv_getaddrinfo_cb getaddrinfo_cb,
|
||||
const char* node,
|
||||
uv_getaddrinfo_cb cb,
|
||||
const char* hostname,
|
||||
const char* service,
|
||||
const struct addrinfo* hints) {
|
||||
return -1;
|
||||
uv_eio_init();
|
||||
|
||||
if (handle == NULL || cb == NULL ||
|
||||
(hostname == NULL && service == NULL)) {
|
||||
uv_err_new_artificial(NULL, UV_EINVAL);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(handle, 0, sizeof(uv_getaddrinfo_t));
|
||||
|
||||
/* TODO don't alloc so much. */
|
||||
|
||||
if (hints) {
|
||||
handle->hints = malloc(sizeof(struct addrinfo));
|
||||
memcpy(&handle->hints, hints, sizeof(struct addrinfo));
|
||||
}
|
||||
|
||||
/* TODO security! check lengths, check return values. */
|
||||
|
||||
handle->cb = cb;
|
||||
handle->hostname = hostname ? strdup(hostname) : NULL;
|
||||
handle->service = service ? strdup(service) : NULL;
|
||||
|
||||
/* TODO check handle->hostname == NULL */
|
||||
/* TODO check handle->service == NULL */
|
||||
|
||||
uv_ref();
|
||||
|
||||
eio_req* req = eio_custom(getaddrinfo_thread_proc, EIO_PRI_DEFAULT,
|
||||
uv_getaddrinfo_done, handle);
|
||||
assert(req);
|
||||
assert(req->data == handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
Vendored
+12
-6
@@ -55,11 +55,14 @@ typedef struct {
|
||||
ev_idle next_watcher;
|
||||
|
||||
|
||||
#define UV_STREAM_PRIVATE_FIELDS \
|
||||
uv_read_cb read_cb; \
|
||||
uv_alloc_cb alloc_cb;
|
||||
|
||||
|
||||
/* 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; \
|
||||
@@ -99,14 +102,17 @@ typedef struct {
|
||||
ev_timer timer_watcher; \
|
||||
uv_timer_cb timer_cb;
|
||||
|
||||
|
||||
#define UV_ARES_ACTION_PRIVATE_FIELDS /* TODO */
|
||||
|
||||
#define UV_ARES_TASK_PRIVATE_FIELDS \
|
||||
int sock; \
|
||||
ev_io read_watcher; \
|
||||
ev_io write_watcher;
|
||||
|
||||
#define UV_GETADDRINFO_PRIVATE_FIELDS /* TODO */
|
||||
#define UV_GETADDRINFO_PRIVATE_FIELDS \
|
||||
uv_getaddrinfo_cb cb; \
|
||||
struct addrinfo* hints; \
|
||||
char* hostname; \
|
||||
char* service; \
|
||||
struct addrinfo* res; \
|
||||
int retcode;
|
||||
|
||||
#endif /* UV_UNIX_H */
|
||||
Vendored
+64
-36
@@ -229,16 +229,19 @@ struct uv_ares_action_s {
|
||||
|
||||
void uv_ares_process(uv_ares_action_t* handle, uv_req_t* req);
|
||||
void uv_ares_task_cleanup(uv_ares_task_t* handle, uv_req_t* req);
|
||||
void uv_ares_poll(uv_timer_t* handle, int status);
|
||||
|
||||
/* memory used per ares_channel */
|
||||
struct uv_ares_channel_s {
|
||||
ares_channel channel;
|
||||
int activesockets;
|
||||
uv_timer_t pollingtimer;
|
||||
};
|
||||
|
||||
typedef struct uv_ares_channel_s uv_ares_channel_t;
|
||||
|
||||
/* static data to hold single ares_channel */
|
||||
static uv_ares_channel_t uv_ares_data = { NULL };
|
||||
static uv_ares_channel_t uv_ares_data = { NULL, 0 };
|
||||
|
||||
/* default timeout per socket request if ares does not specify value */
|
||||
/* use 20 sec */
|
||||
@@ -797,7 +800,7 @@ int uv__bind(uv_tcp_t* handle, int domain, struct sockaddr* addr, int addrsize)
|
||||
}
|
||||
|
||||
|
||||
int uv_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
|
||||
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
|
||||
if (addr.sin_family != AF_INET) {
|
||||
uv_set_sys_error(WSAEFAULT);
|
||||
return -1;
|
||||
@@ -807,7 +810,7 @@ int uv_bind(uv_tcp_t* handle, struct sockaddr_in addr) {
|
||||
}
|
||||
|
||||
|
||||
int uv_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
|
||||
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6 addr) {
|
||||
if (addr.sin6_family != AF_INET6) {
|
||||
uv_set_sys_error(WSAEFAULT);
|
||||
return -1;
|
||||
@@ -904,7 +907,7 @@ static void uv_queue_read(uv_tcp_t* handle) {
|
||||
}
|
||||
|
||||
|
||||
int uv_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
assert(backlog > 0);
|
||||
|
||||
if (handle->flags & UV_HANDLE_BIND_ERROR) {
|
||||
@@ -934,32 +937,34 @@ int uv_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb) {
|
||||
}
|
||||
|
||||
|
||||
int uv_accept(uv_tcp_t* server, uv_tcp_t* client) {
|
||||
int uv_accept(uv_handle_t* server, uv_stream_t* client) {
|
||||
int rv = 0;
|
||||
|
||||
if (server->accept_socket == INVALID_SOCKET) {
|
||||
uv_tcp_t* tcpServer = (uv_tcp_t*)server;
|
||||
uv_tcp_t* tcpClient = (uv_tcp_t*)client;
|
||||
|
||||
if (tcpServer->accept_socket == INVALID_SOCKET) {
|
||||
uv_set_sys_error(WSAENOTCONN);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (uv_tcp_set_socket(client, server->accept_socket) == -1) {
|
||||
closesocket(server->accept_socket);
|
||||
if (uv_tcp_set_socket(tcpClient, tcpServer->accept_socket) == -1) {
|
||||
closesocket(tcpServer->accept_socket);
|
||||
rv = -1;
|
||||
} else {
|
||||
uv_tcp_init_connection(client);
|
||||
uv_tcp_init_connection(tcpClient);
|
||||
}
|
||||
|
||||
server->accept_socket = INVALID_SOCKET;
|
||||
tcpServer->accept_socket = INVALID_SOCKET;
|
||||
|
||||
if (!(server->flags & UV_HANDLE_CLOSING)) {
|
||||
uv_queue_accept(server);
|
||||
if (!(tcpServer->flags & UV_HANDLE_CLOSING)) {
|
||||
uv_queue_accept(tcpServer);
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
int uv_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
|
||||
int uv_read_start(uv_stream_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
|
||||
if (!(handle->flags & UV_HANDLE_CONNECTION)) {
|
||||
uv_set_sys_error(WSAEINVAL);
|
||||
return -1;
|
||||
@@ -982,20 +987,20 @@ int uv_read_start(uv_tcp_t* handle, uv_alloc_cb alloc_cb, uv_read_cb read_cb) {
|
||||
/* If reading was stopped and then started again, there could stell be a */
|
||||
/* read request pending. */
|
||||
if (!(handle->read_req.flags & UV_REQ_PENDING))
|
||||
uv_queue_read(handle);
|
||||
uv_queue_read((uv_tcp_t*)handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_read_stop(uv_tcp_t* handle) {
|
||||
int uv_read_stop(uv_stream_t* handle) {
|
||||
handle->flags &= ~UV_HANDLE_READING;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int uv_connect(uv_req_t* req, struct sockaddr_in addr) {
|
||||
int uv_tcp_connect(uv_req_t* req, struct sockaddr_in addr) {
|
||||
int addrsize = sizeof(struct sockaddr_in);
|
||||
BOOL success;
|
||||
DWORD bytes;
|
||||
@@ -1014,7 +1019,7 @@ int uv_connect(uv_req_t* req, struct sockaddr_in addr) {
|
||||
}
|
||||
|
||||
if (!(handle->flags & UV_HANDLE_BOUND) &&
|
||||
uv_bind(handle, uv_addr_ip4_any_) < 0)
|
||||
uv_tcp_bind(handle, uv_addr_ip4_any_) < 0)
|
||||
return -1;
|
||||
|
||||
memset(&req->overlapped, 0, sizeof(req->overlapped));
|
||||
@@ -1167,13 +1172,13 @@ static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) {
|
||||
uv_last_error_ = req->error;
|
||||
buf.base = 0;
|
||||
buf.len = 0;
|
||||
handle->read_cb(handle, -1, buf);
|
||||
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Do nonblocking reads until the buffer is empty */
|
||||
while (handle->flags & UV_HANDLE_READING) {
|
||||
buf = handle->alloc_cb(handle, 65536);
|
||||
buf = handle->alloc_cb((uv_stream_t*)handle, 65536);
|
||||
assert(buf.len > 0);
|
||||
flags = 0;
|
||||
if (WSARecv(handle->socket,
|
||||
@@ -1185,7 +1190,7 @@ static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) {
|
||||
NULL) != SOCKET_ERROR) {
|
||||
if (bytes > 0) {
|
||||
/* Successful read */
|
||||
handle->read_cb(handle, bytes, buf);
|
||||
handle->read_cb((uv_stream_t*)handle, bytes, buf);
|
||||
/* Read again only if bytes == buf.len */
|
||||
if (bytes < buf.len) {
|
||||
break;
|
||||
@@ -1196,7 +1201,7 @@ static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) {
|
||||
handle->flags |= UV_HANDLE_EOF;
|
||||
uv_last_error_.code = UV_EOF;
|
||||
uv_last_error_.sys_errno_ = ERROR_SUCCESS;
|
||||
handle->read_cb(handle, -1, buf);
|
||||
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
@@ -1204,11 +1209,11 @@ static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) {
|
||||
if (err == WSAEWOULDBLOCK) {
|
||||
/* Read buffer was completely empty, report a 0-byte read. */
|
||||
uv_set_sys_error(WSAEWOULDBLOCK);
|
||||
handle->read_cb(handle, 0, buf);
|
||||
handle->read_cb((uv_stream_t*)handle, 0, buf);
|
||||
} else {
|
||||
/* Ouch! serious error. */
|
||||
uv_set_sys_error(err);
|
||||
handle->read_cb(handle, -1, buf);
|
||||
handle->read_cb((uv_stream_t*)handle, -1, buf);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1231,7 +1236,7 @@ static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) {
|
||||
handle->flags &= ~UV_HANDLE_LISTENING;
|
||||
if (handle->connection_cb) {
|
||||
uv_last_error_ = req->error;
|
||||
handle->connection_cb(handle, -1);
|
||||
handle->connection_cb((uv_handle_t*)handle, -1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -1244,7 +1249,7 @@ static void uv_tcp_return_req(uv_tcp_t* handle, uv_req_t* req) {
|
||||
sizeof(handle->socket)) == 0) {
|
||||
/* Accept and SO_UPDATE_ACCEPT_CONTEXT were successful. */
|
||||
if (handle->connection_cb) {
|
||||
handle->connection_cb(handle, 0);
|
||||
handle->connection_cb((uv_handle_t*)handle, 0);
|
||||
}
|
||||
} else {
|
||||
/* Error related to accepted socket is ignored because the server */
|
||||
@@ -1856,6 +1861,8 @@ VOID CALLBACK uv_ares_socksignal_tp(void* parameter, BOOLEAN timerfired) {
|
||||
void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) {
|
||||
/* look to see if we have a handle for this socket in our list */
|
||||
uv_ares_task_t* uv_handle_ares = uv_find_ares_handle(sock);
|
||||
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)data;
|
||||
|
||||
struct timeval tv;
|
||||
struct timeval* tvptr;
|
||||
int timeoutms = 0;
|
||||
@@ -1911,7 +1918,7 @@ void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) {
|
||||
}
|
||||
uv_handle_ares->type = UV_ARES_TASK;
|
||||
uv_handle_ares->close_cb = NULL;
|
||||
uv_handle_ares->data = ((uv_ares_channel_t*)data)->channel;
|
||||
uv_handle_ares->data = uv_ares_data_ptr;
|
||||
uv_handle_ares->sock = sock;
|
||||
uv_handle_ares->h_wait = NULL;
|
||||
uv_handle_ares->flags = 0;
|
||||
@@ -1930,20 +1937,24 @@ void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) {
|
||||
/* add handle to list */
|
||||
uv_add_ares_handle(uv_handle_ares);
|
||||
uv_refs_++;
|
||||
tv.tv_sec = 0;
|
||||
tvptr = ares_timeout(((uv_ares_channel_t*)data)->channel, NULL, &tv);
|
||||
if (tvptr) {
|
||||
timeoutms = (tvptr->tv_sec * 1000) + (tvptr->tv_usec / 1000);
|
||||
} else {
|
||||
timeoutms = ARES_TIMEOUT_MS;
|
||||
|
||||
/*
|
||||
* we have a single polling timer for all ares sockets.
|
||||
* This is preferred to using ares_timeout. See ares_timeout.c warning.
|
||||
* if timer is not running start it, and keep socket count
|
||||
*/
|
||||
if (uv_ares_data_ptr->activesockets == 0) {
|
||||
uv_timer_init(&uv_ares_data_ptr->pollingtimer);
|
||||
uv_timer_start(&uv_ares_data_ptr->pollingtimer, uv_ares_poll, 1000L, 1000L);
|
||||
}
|
||||
uv_ares_data_ptr->activesockets++;
|
||||
|
||||
/* specify thread pool function to call when event is signaled */
|
||||
if (RegisterWaitForSingleObject(&uv_handle_ares->h_wait,
|
||||
uv_handle_ares->h_event,
|
||||
uv_ares_socksignal_tp,
|
||||
(void*)uv_handle_ares,
|
||||
timeoutms,
|
||||
INFINITE,
|
||||
WT_EXECUTEINWAITTHREAD) == 0) {
|
||||
uv_fatal_error(GetLastError(), "RegisterWaitForSingleObject");
|
||||
}
|
||||
@@ -1958,8 +1969,9 @@ void uv_ares_sockstate_cb(void *data, ares_socket_t sock, int read, int write) {
|
||||
|
||||
/* called via uv_poll when ares completion port signaled */
|
||||
void uv_ares_process(uv_ares_action_t* handle, uv_req_t* req) {
|
||||
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)handle->data;
|
||||
|
||||
ares_process_fd( (ares_channel)handle->data,
|
||||
ares_process_fd(uv_ares_data_ptr->channel,
|
||||
handle->read ? handle->sock : INVALID_SOCKET,
|
||||
handle->write ? handle->sock : INVALID_SOCKET);
|
||||
|
||||
@@ -1969,16 +1981,25 @@ void uv_ares_process(uv_ares_action_t* handle, uv_req_t* req) {
|
||||
|
||||
/* called via uv_poll when ares is finished with socket */
|
||||
void uv_ares_task_cleanup(uv_ares_task_t* handle, uv_req_t* req) {
|
||||
/* check for event complete without waiting */
|
||||
/* check for event complete without waiting */
|
||||
unsigned int signaled = WaitForSingleObject(handle->h_close_event, 0);
|
||||
|
||||
if (signaled != WAIT_TIMEOUT) {
|
||||
uv_ares_channel_t* uv_ares_data_ptr = (uv_ares_channel_t*)handle->data;
|
||||
|
||||
uv_refs_--;
|
||||
|
||||
/* close event handle and free uv handle memory */
|
||||
CloseHandle(handle->h_close_event);
|
||||
free(handle);
|
||||
|
||||
/* decrement active count. if it becomes 0 stop polling */
|
||||
if (uv_ares_data_ptr->activesockets > 0) {
|
||||
uv_ares_data_ptr->activesockets--;
|
||||
if (uv_ares_data_ptr->activesockets == 0) {
|
||||
uv_close((uv_handle_t*)&uv_ares_data_ptr->pollingtimer, NULL);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* stil busy - repost and try again */
|
||||
if (!PostQueuedCompletionStatus(uv_iocp_,
|
||||
@@ -1990,6 +2011,13 @@ void uv_ares_task_cleanup(uv_ares_task_t* handle, uv_req_t* req) {
|
||||
}
|
||||
}
|
||||
|
||||
/* periodically call ares to check for timeouts */
|
||||
void uv_ares_poll(uv_timer_t* handle, int status) {
|
||||
if (uv_ares_data.channel != NULL && uv_ares_data.activesockets > 0) {
|
||||
ares_process_fd(uv_ares_data.channel, ARES_SOCKET_BAD, ARES_SOCKET_BAD);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* set ares SOCK_STATE callback to our handler */
|
||||
int uv_ares_init_options(ares_channel *channelptr,
|
||||
|
||||
Vendored
+3
-2
@@ -52,10 +52,12 @@ typedef struct uv_buf_t {
|
||||
uv_err_t error; \
|
||||
struct uv_req_s* next_req;
|
||||
|
||||
#define uv_tcp_connection_fields \
|
||||
#define UV_STREAM_PRIVATE_FIELDS \
|
||||
uv_alloc_cb alloc_cb; \
|
||||
uv_read_cb read_cb; \
|
||||
struct uv_req_s read_req; \
|
||||
|
||||
#define uv_tcp_connection_fields \
|
||||
unsigned int write_reqs_pending; \
|
||||
uv_req_t* shutdown_req;
|
||||
|
||||
@@ -107,7 +109,6 @@ typedef struct uv_buf_t {
|
||||
unsigned int flags; \
|
||||
uv_err_t error;
|
||||
|
||||
|
||||
#define UV_ARES_TASK_PRIVATE_FIELDS \
|
||||
struct uv_req_s ares_req; \
|
||||
SOCKET sock; \
|
||||
|
||||
Vendored
+41
-27
@@ -41,6 +41,7 @@ typedef intptr_t ssize_t;
|
||||
|
||||
typedef struct uv_err_s uv_err_t;
|
||||
typedef struct uv_handle_s uv_handle_t;
|
||||
typedef struct uv_stream_s uv_stream_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;
|
||||
@@ -66,12 +67,12 @@ typedef struct uv_getaddrinfo_s uv_getaddrinfo_t;
|
||||
* 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 uv_buf_t (*uv_alloc_cb)(uv_stream_t* tcp, size_t suggested_size);
|
||||
typedef void (*uv_read_cb)(uv_stream_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_connection_cb)(uv_handle_t* server, int status);
|
||||
typedef void (*uv_close_cb)(uv_handle_t* handle);
|
||||
typedef void (*uv_timer_cb)(uv_timer_t* handle, int status);
|
||||
/* TODO: do these really need a status argument? */
|
||||
@@ -177,6 +178,8 @@ struct uv_req_s {
|
||||
*/
|
||||
void uv_req_init(uv_req_t* req, uv_handle_t* handle, void* cb);
|
||||
|
||||
int uv_shutdown(uv_req_t* req);
|
||||
|
||||
|
||||
#define UV_HANDLE_FIELDS \
|
||||
/* read-only */ \
|
||||
@@ -205,31 +208,21 @@ int uv_is_active(uv_handle_t* handle);
|
||||
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 {
|
||||
#define UV_STREAM_FIELDS \
|
||||
/* number of bytes queued for writing */ \
|
||||
size_t write_queue_size; \
|
||||
/* private */ \
|
||||
UV_STREAM_PRIVATE_FIELDS \
|
||||
|
||||
/* The abstract base class for all streams. */
|
||||
struct uv_stream_s {
|
||||
UV_HANDLE_FIELDS
|
||||
size_t write_queue_size; /* number of bytes queued for writing */
|
||||
UV_TCP_PRIVATE_FIELDS
|
||||
UV_STREAM_FIELDS
|
||||
};
|
||||
|
||||
int uv_tcp_init(uv_tcp_t* handle);
|
||||
|
||||
int uv_bind(uv_tcp_t* handle, struct sockaddr_in);
|
||||
int uv_bind6(uv_tcp_t* handle, struct sockaddr_in6);
|
||||
|
||||
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
|
||||
/* This call is used in conjunction with uv_listen() to accept incoming
|
||||
* connections. Call uv_accept after receiving a uv_connection_cb to accept
|
||||
* the connection. Before calling uv_accept use uv_tcp_init() must be
|
||||
* the connection. Before calling uv_accept use uv_*_init() must be
|
||||
* called on the client. Non-zero return value indicates an error.
|
||||
*
|
||||
* When the uv_connection_cb is called it is guaranteed that uv_accept will
|
||||
@@ -237,7 +230,7 @@ int uv_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
|
||||
* once, it may fail. It is suggested to only call uv_accept once per
|
||||
* uv_connection_cb call.
|
||||
*/
|
||||
int uv_accept(uv_tcp_t* server, uv_tcp_t* client);
|
||||
int uv_accept(uv_handle_t* server, uv_stream_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
|
||||
@@ -248,9 +241,9 @@ int uv_accept(uv_tcp_t* server, uv_tcp_t* client);
|
||||
* 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_start(uv_stream_t*, uv_alloc_cb alloc_cb, uv_read_cb read_cb);
|
||||
|
||||
int uv_read_stop(uv_tcp_t*);
|
||||
int uv_read_stop(uv_stream_t*);
|
||||
|
||||
/* Write data to stream. Buffers are written in order. Example:
|
||||
*
|
||||
@@ -272,6 +265,27 @@ int uv_read_stop(uv_tcp_t*);
|
||||
int uv_write(uv_req_t* req, uv_buf_t bufs[], int bufcnt);
|
||||
|
||||
|
||||
/*
|
||||
* A subclass of uv_stream_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
|
||||
UV_STREAM_FIELDS
|
||||
UV_TCP_PRIVATE_FIELDS
|
||||
};
|
||||
|
||||
int uv_tcp_init(uv_tcp_t* handle);
|
||||
|
||||
int uv_tcp_bind(uv_tcp_t* handle, struct sockaddr_in);
|
||||
int uv_tcp_bind6(uv_tcp_t* handle, struct sockaddr_in6);
|
||||
|
||||
int uv_tcp_connect(uv_req_t* req, struct sockaddr_in);
|
||||
|
||||
int uv_tcp_listen(uv_tcp_t* handle, int backlog, uv_connection_cb cb);
|
||||
|
||||
|
||||
/*
|
||||
* Subclass of uv_handle_t. libev wrapper. Every active prepare handle gets
|
||||
* its callback called exactly once per loop iteration, just before the
|
||||
|
||||
+14
-14
@@ -160,7 +160,7 @@ class TCPWrap {
|
||||
int port = args[1]->Int32Value();
|
||||
|
||||
struct sockaddr_in address = uv_ip4_addr(*ip_address, port);
|
||||
int r = uv_bind(&wrap->handle_, address);
|
||||
int r = uv_tcp_bind(&wrap->handle_, address);
|
||||
|
||||
// Error starting the tcp.
|
||||
if (r) SetErrno(uv_last_error().code);
|
||||
@@ -175,7 +175,7 @@ class TCPWrap {
|
||||
|
||||
int backlog = args[0]->Int32Value();
|
||||
|
||||
int r = uv_listen(&wrap->handle_, backlog, OnConnection);
|
||||
int r = uv_tcp_listen(&wrap->handle_, backlog, OnConnection);
|
||||
|
||||
// Error starting the tcp.
|
||||
if (r) SetErrno(uv_last_error().code);
|
||||
@@ -183,12 +183,12 @@ class TCPWrap {
|
||||
return scope.Close(Integer::New(r));
|
||||
}
|
||||
|
||||
static void OnConnection(uv_tcp_t* handle, int status) {
|
||||
static void OnConnection(uv_handle_t* handle, int status) {
|
||||
HandleScope scope;
|
||||
|
||||
TCPWrap* wrap = static_cast<TCPWrap*>(handle->data);
|
||||
|
||||
assert(&wrap->handle_ == handle);
|
||||
assert(&wrap->handle_ == (uv_tcp_t*)handle);
|
||||
|
||||
if (status != 0) {
|
||||
// TODO Handle server error (call onerror?)
|
||||
@@ -205,7 +205,7 @@ class TCPWrap {
|
||||
TCPWrap* client_wrap =
|
||||
static_cast<TCPWrap*>(client_obj->GetPointerFromInternalField(0));
|
||||
|
||||
int r = uv_accept(handle, &client_wrap->handle_);
|
||||
int r = uv_accept(handle, (uv_stream_t*)&client_wrap->handle_);
|
||||
|
||||
// uv_accept should always work.
|
||||
assert(r == 0);
|
||||
@@ -220,7 +220,7 @@ class TCPWrap {
|
||||
|
||||
UNWRAP
|
||||
|
||||
int r = uv_read_start(&wrap->handle_, OnAlloc, OnRead);
|
||||
int r = uv_read_start((uv_stream_t*)&wrap->handle_, OnAlloc, OnRead);
|
||||
|
||||
// Error starting the tcp.
|
||||
if (r) SetErrno(uv_last_error().code);
|
||||
@@ -233,7 +233,7 @@ class TCPWrap {
|
||||
|
||||
UNWRAP
|
||||
|
||||
int r = uv_read_stop(&wrap->handle_);
|
||||
int r = uv_read_stop((uv_stream_t*)&wrap->handle_);
|
||||
|
||||
// Error starting the tcp.
|
||||
if (r) SetErrno(uv_last_error().code);
|
||||
@@ -250,11 +250,11 @@ class TCPWrap {
|
||||
return Buffer::Data(b);
|
||||
}
|
||||
|
||||
static uv_buf_t OnAlloc(uv_tcp_t* handle, size_t suggested_size) {
|
||||
static uv_buf_t OnAlloc(uv_stream_t* handle, size_t suggested_size) {
|
||||
HandleScope scope;
|
||||
|
||||
TCPWrap* wrap = static_cast<TCPWrap*>(handle->data);
|
||||
assert(&wrap->handle_ == handle);
|
||||
assert(&wrap->handle_ == (uv_tcp_t*)handle);
|
||||
|
||||
char* slab = NULL;
|
||||
|
||||
@@ -286,12 +286,12 @@ class TCPWrap {
|
||||
wrap->slab_offset_ = slab_used;
|
||||
slab_used += buf.len;
|
||||
|
||||
handle_that_last_alloced = handle;
|
||||
handle_that_last_alloced = (uv_tcp_t*)handle;
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void OnRead(uv_tcp_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
static void OnRead(uv_stream_t* handle, ssize_t nread, uv_buf_t buf) {
|
||||
HandleScope scope;
|
||||
|
||||
TCPWrap* wrap = static_cast<TCPWrap*>(handle->data);
|
||||
@@ -302,7 +302,7 @@ class TCPWrap {
|
||||
|
||||
if (nread < 0) {
|
||||
// EOF or Error
|
||||
if (handle_that_last_alloced == handle) {
|
||||
if (handle_that_last_alloced == (uv_tcp_t*)handle) {
|
||||
slab_used -= buf.len;
|
||||
}
|
||||
|
||||
@@ -313,7 +313,7 @@ class TCPWrap {
|
||||
|
||||
assert(nread <= buf.len);
|
||||
|
||||
if (handle_that_last_alloced == handle) {
|
||||
if (handle_that_last_alloced == (uv_tcp_t*)handle) {
|
||||
slab_used -= (buf.len - nread);
|
||||
}
|
||||
|
||||
@@ -451,7 +451,7 @@ class TCPWrap {
|
||||
ReqWrap* req_wrap = new ReqWrap((uv_handle_t*) &wrap->handle_,
|
||||
(void*)AfterConnect);
|
||||
|
||||
int r = uv_connect(&req_wrap->req_, address);
|
||||
int r = uv_tcp_connect(&req_wrap->req_, address);
|
||||
|
||||
if (r) {
|
||||
SetErrno(uv_last_error().code);
|
||||
|
||||
@@ -358,8 +358,6 @@ def configure(conf):
|
||||
if not conf.check(lib='kstat', uselib_store="KSTAT"):
|
||||
conf.fatal("Cannot find kstat library")
|
||||
|
||||
conf.sub_config('deps/libeio')
|
||||
|
||||
if conf.env['USE_SHARED_V8']:
|
||||
v8_includes = [];
|
||||
if o.shared_v8_includes: v8_includes.append(o.shared_v8_includes);
|
||||
@@ -418,8 +416,6 @@ def configure(conf):
|
||||
conf.env.append_value('CXXFLAGS', flags)
|
||||
conf.env.append_value('LINKFLAGS', flags)
|
||||
|
||||
# Needed for getaddrinfo in libeio
|
||||
conf.env.append_value("CPPFLAGS", "-DX_STACKSIZE=%d" % (1024*64))
|
||||
# LFS
|
||||
conf.env.append_value('CPPFLAGS', '-D_LARGEFILE_SOURCE')
|
||||
conf.env.append_value('CPPFLAGS', '-D_FILE_OFFSET_BITS=64')
|
||||
@@ -641,8 +637,6 @@ def build(bld):
|
||||
print "Parallel Jobs: " + str(Options.options.jobs)
|
||||
print "Product type: " + product_type
|
||||
|
||||
bld.add_subdirs('deps/libeio')
|
||||
|
||||
build_uv(bld)
|
||||
|
||||
if not bld.env['USE_SHARED_V8']: build_v8(bld)
|
||||
@@ -804,7 +798,7 @@ def build(bld):
|
||||
node.name = "node"
|
||||
node.target = "node"
|
||||
node.uselib = 'RT OPENSSL CARES EXECINFO DL KVM SOCKET NSL KSTAT UTIL OPROFILE'
|
||||
node.add_objects = 'eio http_parser'
|
||||
node.add_objects = 'http_parser'
|
||||
if product_type_is_lib:
|
||||
node.install_path = '${LIBDIR}'
|
||||
else:
|
||||
@@ -848,10 +842,10 @@ def build(bld):
|
||||
|
||||
node.includes = """
|
||||
src/
|
||||
deps/libeio
|
||||
deps/http_parser
|
||||
deps/uv
|
||||
deps/uv/ev
|
||||
deps/uv/eio
|
||||
"""
|
||||
|
||||
if not bld.env["USE_SHARED_V8"]: node.includes += ' deps/v8/include '
|
||||
|
||||
Reference in new issue
Block a user