Browse Source

deps: update libuv to 1.4.1

PR-URL: https://github.com/iojs/io.js/pull/940
Reviewed-By: Fedor Indutny <fedor@indutny.com>
Reviewed-By: Rod Vagg <rod@vagg.org>
v1.8.0-commit
Ben Noordhuis 10 years ago
committed by Rod Vagg
parent
commit
739fda16a9
  1. 3
      deps/uv/.gitignore
  2. 1
      deps/uv/.mailmap
  3. 1
      deps/uv/AUTHORS
  4. 20
      deps/uv/ChangeLog
  5. 1
      deps/uv/Makefile.am
  6. 1
      deps/uv/checksparse.sh
  7. 2
      deps/uv/configure.ac
  8. 3
      deps/uv/docs/src/threading.rst
  9. 16
      deps/uv/include/uv-errno.h
  10. 2
      deps/uv/include/uv-version.h
  11. 1
      deps/uv/include/uv-win.h
  12. 1
      deps/uv/include/uv.h
  13. 42
      deps/uv/src/unix/async.c
  14. 12
      deps/uv/src/unix/stream.c
  15. 2
      deps/uv/src/unix/thread.c
  16. 20
      deps/uv/src/unix/tty.c
  17. 25
      deps/uv/src/unix/uv-dtrace.d
  18. 145
      deps/uv/src/win/thread.c
  19. 24
      deps/uv/test/test-fs.c
  20. 2
      deps/uv/test/test-list.h
  21. 128
      deps/uv/test/test-tcp-oob.c
  22. 1
      deps/uv/uv.gyp

3
deps/uv/.gitignore

@ -67,3 +67,6 @@ ipch
*.xcodeproj *.xcodeproj
*.xcworkspace *.xcworkspace
# make dist output
libuv-*.tar.*

1
deps/uv/.mailmap

@ -14,6 +14,7 @@ Isaac Z. Schlueter <i@izs.me>
Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com> Justin Venus <justin.venus@gmail.com> <justin.venus@orbitz.com>
Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu> Keno Fischer <kenof@stanford.edu> <kfischer+github@college.harvard.edu>
Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu> Keno Fischer <kenof@stanford.edu> <kfischer@college.harvard.edu>
Leith Bade <leith@leithalweapon.geek.nz> <leith@mapbox.com>
Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io> Leonard Hecker <leonard.hecker91@gmail.com> <leonard@hecker.io>
Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com> Maciej Małecki <maciej.malecki@notimplemented.org> <me@mmalecki.com>
Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com> Marc Schlaich <marc.schlaich@googlemail.com> <marc.schlaich@gmail.com>

1
deps/uv/AUTHORS

@ -180,3 +180,4 @@ Alexey Melnichuk <mimir@newmail.ru>
Johan Bergström <bugs@bergstroem.nu> Johan Bergström <bugs@bergstroem.nu>
Alex Mo <almosnow@gmail.com> Alex Mo <almosnow@gmail.com>
Luis Martinez de Bartolome <lasote@gmail.com> Luis Martinez de Bartolome <lasote@gmail.com>
Michael Penick <michael.penick@datastax.com>

20
deps/uv/ChangeLog

@ -1,3 +1,23 @@
2015.02.25, Version 1.4.1 (Stable)
Changes since version 1.4.0:
* win: don't use inline keyword in thread.c (Ben Noordhuis)
* windows: fix setting dirent types on uv_fs_scandir_next (Saúl Ibarra
Corretgé)
* unix,windows: make uv_thread_create() return errno (Ben Noordhuis)
* tty: fix build for SmartOS (Julien Gilli)
* unix: fix for uv_async data race (Michael Penick)
* unix, windows: map EHOSTDOWN errno (Ben Noordhuis)
* stream: use SO_OOBINLINE on OS X (Fedor Indutny)
2015.02.10, Version 1.4.0 (Stable), 19fb8a90648f3763240db004b77ab984264409be 2015.02.10, Version 1.4.0 (Stable), 19fb8a90648f3763240db004b77ab984264409be
Changes since version 1.3.0: Changes since version 1.3.0:

1
deps/uv/Makefile.am

@ -222,6 +222,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
test/test-tcp-read-stop.c \ test/test-tcp-read-stop.c \
test/test-tcp-shutdown-after-write.c \ test/test-tcp-shutdown-after-write.c \
test/test-tcp-unexpected-read.c \ test/test-tcp-unexpected-read.c \
test/test-tcp-oob.c \
test/test-tcp-write-to-half-open-connection.c \ test/test-tcp-write-to-half-open-connection.c \
test/test-tcp-write-after-connect.c \ test/test-tcp-write-after-connect.c \
test/test-tcp-writealot.c \ test/test-tcp-writealot.c \

1
deps/uv/checksparse.sh

@ -145,6 +145,7 @@ test/test-tcp-open.c
test/test-tcp-read-stop.c test/test-tcp-read-stop.c
test/test-tcp-shutdown-after-write.c test/test-tcp-shutdown-after-write.c
test/test-tcp-unexpected-read.c test/test-tcp-unexpected-read.c
test/test-tcp-oob.c
test/test-tcp-write-error.c test/test-tcp-write-error.c
test/test-tcp-write-to-half-open-connection.c test/test-tcp-write-to-half-open-connection.c
test/test-tcp-writealot.c test/test-tcp-writealot.c

2
deps/uv/configure.ac

@ -13,7 +13,7 @@
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. # OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
AC_PREREQ(2.57) AC_PREREQ(2.57)
AC_INIT([libuv], [1.4.0], [https://github.com/libuv/libuv/issues]) AC_INIT([libuv], [1.4.1], [https://github.com/libuv/libuv/issues])
AC_CONFIG_MACRO_DIR([m4]) AC_CONFIG_MACRO_DIR([m4])
m4_include([m4/libuv-extra-automake-flags.m4]) m4_include([m4/libuv-extra-automake-flags.m4])
m4_include([m4/as_case.m4]) m4_include([m4/as_case.m4])

3
deps/uv/docs/src/threading.rst

@ -56,6 +56,9 @@ Threads
^^^^^^^ ^^^^^^^
.. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg) .. c:function:: int uv_thread_create(uv_thread_t* tid, uv_thread_cb entry, void* arg)
.. versionchanged:: 1.4.1 returns a UV_E* error code on failure
.. c:function:: uv_thread_t uv_thread_self(void) .. c:function:: uv_thread_t uv_thread_self(void)
.. c:function:: int uv_thread_join(uv_thread_t *tid) .. c:function:: int uv_thread_join(uv_thread_t *tid)
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) .. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)

16
deps/uv/include/uv-errno.h

@ -399,4 +399,20 @@
# define UV__EMLINK (-4032) # define UV__EMLINK (-4032)
#endif #endif
/* EHOSTDOWN is not visible on BSD-like systems when _POSIX_C_SOURCE is
* defined. Fortunately, its value is always 64 so it's possible albeit
* icky to hard-code it.
*/
#if defined(EHOSTDOWN) && !defined(_WIN32)
# define UV__EHOSTDOWN (-EHOSTDOWN)
#elif defined(__APPLE__) || \
defined(__DragonFly__) || \
defined(__FreeBSD__) || \
defined(__NetBSD__) || \
defined(__OpenBSD__)
# define UV__EHOSTDOWN (-64)
#else
# define UV__EHOSTDOWN (-4031)
#endif
#endif /* UV_ERRNO_H_ */ #endif /* UV_ERRNO_H_ */

2
deps/uv/include/uv-version.h

@ -32,7 +32,7 @@
#define UV_VERSION_MAJOR 1 #define UV_VERSION_MAJOR 1
#define UV_VERSION_MINOR 4 #define UV_VERSION_MINOR 4
#define UV_VERSION_PATCH 0 #define UV_VERSION_PATCH 1
#define UV_VERSION_IS_RELEASE 1 #define UV_VERSION_IS_RELEASE 1
#define UV_VERSION_SUFFIX "" #define UV_VERSION_SUFFIX ""

1
deps/uv/include/uv-win.h

@ -294,6 +294,7 @@ typedef struct uv__dirent_s {
char d_name[1]; char d_name[1];
} uv__dirent_t; } uv__dirent_t;
#define HAVE_DIRENT_TYPES
#define UV__DT_DIR UV_DIRENT_DIR #define UV__DT_DIR UV_DIRENT_DIR
#define UV__DT_FILE UV_DIRENT_FILE #define UV__DT_FILE UV_DIRENT_FILE
#define UV__DT_LINK UV_DIRENT_LINK #define UV__DT_LINK UV_DIRENT_LINK

1
deps/uv/include/uv.h

@ -138,6 +138,7 @@ extern "C" {
XX(EOF, "end of file") \ XX(EOF, "end of file") \
XX(ENXIO, "no such device or address") \ XX(ENXIO, "no such device or address") \
XX(EMLINK, "too many links") \ XX(EMLINK, "too many links") \
XX(EHOSTDOWN, "host is down") \
#define UV_HANDLE_TYPE_MAP(XX) \ #define UV_HANDLE_TYPE_MAP(XX) \
XX(ASYNC, async) \ XX(ASYNC, async) \

42
deps/uv/src/unix/async.c

@ -24,6 +24,7 @@
#include "uv.h" #include "uv.h"
#include "internal.h" #include "internal.h"
#include "atomic-ops.h"
#include <errno.h> #include <errno.h>
#include <stdio.h> /* snprintf() */ #include <stdio.h> /* snprintf() */
@ -35,7 +36,6 @@
static void uv__async_event(uv_loop_t* loop, static void uv__async_event(uv_loop_t* loop,
struct uv__async* w, struct uv__async* w,
unsigned int nevents); unsigned int nevents);
static int uv__async_make_pending(int* pending);
static int uv__async_eventfd(void); static int uv__async_eventfd(void);
@ -58,7 +58,11 @@ int uv_async_init(uv_loop_t* loop, uv_async_t* handle, uv_async_cb async_cb) {
int uv_async_send(uv_async_t* handle) { int uv_async_send(uv_async_t* handle) {
if (uv__async_make_pending(&handle->pending) == 0) /* Do a cheap read first. */
if (ACCESS_ONCE(int, handle->pending) != 0)
return 0;
if (cmpxchgi(&handle->pending, 0, 1) == 0)
uv__async_send(&handle->loop->async_watcher); uv__async_send(&handle->loop->async_watcher);
return 0; return 0;
@ -80,9 +84,8 @@ static void uv__async_event(uv_loop_t* loop,
QUEUE_FOREACH(q, &loop->async_handles) { QUEUE_FOREACH(q, &loop->async_handles) {
h = QUEUE_DATA(q, uv_async_t, queue); h = QUEUE_DATA(q, uv_async_t, queue);
if (h->pending == 0) if (cmpxchgi(&h->pending, 1, 0) == 0)
continue; continue;
h->pending = 0;
if (h->async_cb == NULL) if (h->async_cb == NULL)
continue; continue;
@ -91,37 +94,6 @@ static void uv__async_event(uv_loop_t* loop,
} }
static int uv__async_make_pending(int* pending) {
/* Do a cheap read first. */
if (ACCESS_ONCE(int, *pending) != 0)
return 1;
/* Micro-optimization: use atomic memory operations to detect if we've been
* preempted by another thread and don't have to make an expensive syscall.
* This speeds up the heavily contended case by about 1-2% and has little
* if any impact on the non-contended case.
*
* Use XCHG instead of the CMPXCHG that __sync_val_compare_and_swap() emits
* on x86, it's about 4x faster. It probably makes zero difference in the
* grand scheme of things but I'm OCD enough not to let this one pass.
*/
#if defined(__i386__) || defined(__x86_64__)
{
unsigned int val = 1;
__asm__ __volatile__ ("xchgl %0, %1"
: "+r" (val)
: "m" (*pending));
return val != 0;
}
#elif defined(__GNUC__) && (__GNUC__ > 4 || __GNUC__ == 4 && __GNUC_MINOR__ > 0)
return __sync_val_compare_and_swap(pending, 0, 1) != 0;
#else
ACCESS_ONCE(int, *pending) = 1;
return 0;
#endif
}
static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) { static void uv__async_io(uv_loop_t* loop, uv__io_t* w, unsigned int events) {
struct uv__async* wa; struct uv__async* wa;
char buf[1024]; char buf[1024];

12
deps/uv/src/unix/stream.c

@ -375,6 +375,10 @@ failed_malloc:
int uv__stream_open(uv_stream_t* stream, int fd, int flags) { int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
#if defined(__APPLE__)
int enable;
#endif
assert(fd >= 0); assert(fd >= 0);
stream->flags |= flags; stream->flags |= flags;
@ -387,6 +391,14 @@ int uv__stream_open(uv_stream_t* stream, int fd, int flags) {
return -errno; return -errno;
} }
#if defined(__APPLE__)
enable = 1;
if (setsockopt(fd, SOL_SOCKET, SO_OOBINLINE, &enable, sizeof(enable)) &&
errno != ENOTSOCK) {
return -errno;
}
#endif
stream->io_watcher.fd = fd; stream->io_watcher.fd = fd;
return 0; return 0;

2
deps/uv/src/unix/thread.c

@ -68,7 +68,7 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
if (err) if (err)
free(ctx); free(ctx);
return err ? -1 : 0; return -err;
} }

20
deps/uv/src/unix/tty.c

@ -103,6 +103,24 @@ skip:
return 0; return 0;
} }
static void uv__tty_make_raw(struct termios* tio) {
assert(tio != NULL);
#ifdef __sun
/*
* This implementation of cfmakeraw for Solaris and derivatives is taken from
* http://www.perkin.org.uk/posts/solaris-portability-cfmakeraw.html.
*/
tio->c_iflag &= ~(IMAXBEL | IGNBRK | BRKINT | PARMRK | ISTRIP | INLCR |
IGNCR | ICRNL | IXON);
tio->c_oflag &= ~OPOST;
tio->c_lflag &= ~(ECHO | ECHONL | ICANON | ISIG | IEXTEN);
tio->c_cflag &= ~(CSIZE | PARENB);
tio->c_cflag |= CS8;
#else
cfmakeraw(tio);
#endif /* #ifdef __sun */
}
int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) { int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
struct termios tmp; struct termios tmp;
@ -138,7 +156,7 @@ int uv_tty_set_mode(uv_tty_t* tty, uv_tty_mode_t mode) {
tmp.c_cc[VTIME] = 0; tmp.c_cc[VTIME] = 0;
break; break;
case UV_TTY_MODE_IO: case UV_TTY_MODE_IO:
cfmakeraw(&tmp); uv__tty_make_raw(&tmp);
break; break;
} }

25
deps/uv/src/unix/uv-dtrace.d

@ -1,25 +0,0 @@
/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
provider uv {
probe tick__start(void* loop, int mode);
probe tick__stop(void* loop, int mode);
};

145
deps/uv/src/win/thread.c

@ -30,53 +30,43 @@
#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL) #define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL)
#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL) #define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
#ifdef _MSC_VER /* msvc */ static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock);
# define inline __inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock);
# define NOINLINE __declspec (noinline) static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock);
#else /* gcc */ static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock);
# define inline inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock);
# define NOINLINE __attribute__ ((noinline)) static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock);
#endif static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock);
static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock);
inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock); static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock);
inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock); static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock);
inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock); static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock);
inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock); static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock);
inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock); static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock);
inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock); static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock);
inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock); static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock);
inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock); static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock);
inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock);
inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock); static int uv_cond_fallback_init(uv_cond_t* cond);
inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock); static void uv_cond_fallback_destroy(uv_cond_t* cond);
inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock); static void uv_cond_fallback_signal(uv_cond_t* cond);
inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock); static void uv_cond_fallback_broadcast(uv_cond_t* cond);
inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock); static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex);
inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock); static int uv_cond_fallback_timedwait(uv_cond_t* cond,
inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock);
inline static int uv_cond_fallback_init(uv_cond_t* cond);
inline static void uv_cond_fallback_destroy(uv_cond_t* cond);
inline static void uv_cond_fallback_signal(uv_cond_t* cond);
inline static void uv_cond_fallback_broadcast(uv_cond_t* cond);
inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex);
inline static int uv_cond_fallback_timedwait(uv_cond_t* cond,
uv_mutex_t* mutex, uint64_t timeout); uv_mutex_t* mutex, uint64_t timeout);
inline static int uv_cond_condvar_init(uv_cond_t* cond); static int uv_cond_condvar_init(uv_cond_t* cond);
inline static void uv_cond_condvar_destroy(uv_cond_t* cond); static void uv_cond_condvar_destroy(uv_cond_t* cond);
inline static void uv_cond_condvar_signal(uv_cond_t* cond); static void uv_cond_condvar_signal(uv_cond_t* cond);
inline static void uv_cond_condvar_broadcast(uv_cond_t* cond); static void uv_cond_condvar_broadcast(uv_cond_t* cond);
inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex); static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex);
inline static int uv_cond_condvar_timedwait(uv_cond_t* cond, static int uv_cond_condvar_timedwait(uv_cond_t* cond,
uv_mutex_t* mutex, uint64_t timeout); uv_mutex_t* mutex, uint64_t timeout);
static NOINLINE void uv__once_inner(uv_once_t* guard, static void uv__once_inner(uv_once_t* guard, void (*callback)(void)) {
void (*callback)(void)) {
DWORD result; DWORD result;
HANDLE existing_event, created_event; HANDLE existing_event, created_event;
@ -185,7 +175,18 @@ int uv_thread_create(uv_thread_t *tid, void (*entry)(void *arg), void *arg) {
ResumeThread(thread); ResumeThread(thread);
} }
return err; switch (err) {
case 0:
return 0;
case EACCES:
return UV_EACCES;
case EAGAIN:
return UV_EAGAIN;
case EINVAL:
return UV_EINVAL;
}
return UV_EIO;
} }
@ -346,23 +347,23 @@ int uv_sem_trywait(uv_sem_t* sem) {
} }
inline static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock) { static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock) {
pInitializeSRWLock(&rwlock->srwlock_); pInitializeSRWLock(&rwlock->srwlock_);
return 0; return 0;
} }
inline static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock) { static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock) {
(void) rwlock; (void) rwlock;
} }
inline static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock) { static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock) {
pAcquireSRWLockShared(&rwlock->srwlock_); pAcquireSRWLockShared(&rwlock->srwlock_);
} }
inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock) { static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock) {
if (pTryAcquireSRWLockShared(&rwlock->srwlock_)) if (pTryAcquireSRWLockShared(&rwlock->srwlock_))
return 0; return 0;
else else
@ -370,17 +371,17 @@ inline static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock) {
} }
inline static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock) { static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock) {
pReleaseSRWLockShared(&rwlock->srwlock_); pReleaseSRWLockShared(&rwlock->srwlock_);
} }
inline static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock) { static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock) {
pAcquireSRWLockExclusive(&rwlock->srwlock_); pAcquireSRWLockExclusive(&rwlock->srwlock_);
} }
inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock) { static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock) {
if (pTryAcquireSRWLockExclusive(&rwlock->srwlock_)) if (pTryAcquireSRWLockExclusive(&rwlock->srwlock_))
return 0; return 0;
else else
@ -388,12 +389,12 @@ inline static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock) {
} }
inline static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock) { static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock) {
pReleaseSRWLockExclusive(&rwlock->srwlock_); pReleaseSRWLockExclusive(&rwlock->srwlock_);
} }
inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) { static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) {
int err; int err;
err = uv_mutex_init(&rwlock->fallback_.read_mutex_); err = uv_mutex_init(&rwlock->fallback_.read_mutex_);
@ -412,13 +413,13 @@ inline static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) {
} }
inline static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock) { static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock) {
uv_mutex_destroy(&rwlock->fallback_.read_mutex_); uv_mutex_destroy(&rwlock->fallback_.read_mutex_);
uv_mutex_destroy(&rwlock->fallback_.write_mutex_); uv_mutex_destroy(&rwlock->fallback_.write_mutex_);
} }
inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock) { static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock) {
uv_mutex_lock(&rwlock->fallback_.read_mutex_); uv_mutex_lock(&rwlock->fallback_.read_mutex_);
if (++rwlock->fallback_.num_readers_ == 1) if (++rwlock->fallback_.num_readers_ == 1)
@ -428,7 +429,7 @@ inline static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock) {
} }
inline static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock) { static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock) {
int err; int err;
err = uv_mutex_trylock(&rwlock->fallback_.read_mutex_); err = uv_mutex_trylock(&rwlock->fallback_.read_mutex_);
@ -449,7 +450,7 @@ out:
} }
inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock) { static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock) {
uv_mutex_lock(&rwlock->fallback_.read_mutex_); uv_mutex_lock(&rwlock->fallback_.read_mutex_);
if (--rwlock->fallback_.num_readers_ == 0) if (--rwlock->fallback_.num_readers_ == 0)
@ -459,17 +460,17 @@ inline static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock) {
} }
inline static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock) { static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock) {
uv_mutex_lock(&rwlock->fallback_.write_mutex_); uv_mutex_lock(&rwlock->fallback_.write_mutex_);
} }
inline static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock) { static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock) {
return uv_mutex_trylock(&rwlock->fallback_.write_mutex_); return uv_mutex_trylock(&rwlock->fallback_.write_mutex_);
} }
inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) { static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) {
uv_mutex_unlock(&rwlock->fallback_.write_mutex_); uv_mutex_unlock(&rwlock->fallback_.write_mutex_);
} }
@ -482,7 +483,7 @@ inline static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) {
* uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs. * uv_cond_timedwait() to be HANDLEs, but we use CRITICAL_SECTIONs.
*/ */
inline static int uv_cond_fallback_init(uv_cond_t* cond) { static int uv_cond_fallback_init(uv_cond_t* cond) {
int err; int err;
/* Initialize the count to 0. */ /* Initialize the count to 0. */
@ -520,7 +521,7 @@ error2:
} }
inline static int uv_cond_condvar_init(uv_cond_t* cond) { static int uv_cond_condvar_init(uv_cond_t* cond) {
pInitializeConditionVariable(&cond->cond_var); pInitializeConditionVariable(&cond->cond_var);
return 0; return 0;
} }
@ -536,7 +537,7 @@ int uv_cond_init(uv_cond_t* cond) {
} }
inline static void uv_cond_fallback_destroy(uv_cond_t* cond) { static void uv_cond_fallback_destroy(uv_cond_t* cond) {
if (!CloseHandle(cond->fallback.broadcast_event)) if (!CloseHandle(cond->fallback.broadcast_event))
abort(); abort();
if (!CloseHandle(cond->fallback.signal_event)) if (!CloseHandle(cond->fallback.signal_event))
@ -545,7 +546,7 @@ inline static void uv_cond_fallback_destroy(uv_cond_t* cond) {
} }
inline static void uv_cond_condvar_destroy(uv_cond_t* cond) { static void uv_cond_condvar_destroy(uv_cond_t* cond) {
/* nothing to do */ /* nothing to do */
} }
@ -558,7 +559,7 @@ void uv_cond_destroy(uv_cond_t* cond) {
} }
inline static void uv_cond_fallback_signal(uv_cond_t* cond) { static void uv_cond_fallback_signal(uv_cond_t* cond) {
int have_waiters; int have_waiters;
/* Avoid race conditions. */ /* Avoid race conditions. */
@ -571,7 +572,7 @@ inline static void uv_cond_fallback_signal(uv_cond_t* cond) {
} }
inline static void uv_cond_condvar_signal(uv_cond_t* cond) { static void uv_cond_condvar_signal(uv_cond_t* cond) {
pWakeConditionVariable(&cond->cond_var); pWakeConditionVariable(&cond->cond_var);
} }
@ -584,7 +585,7 @@ void uv_cond_signal(uv_cond_t* cond) {
} }
inline static void uv_cond_fallback_broadcast(uv_cond_t* cond) { static void uv_cond_fallback_broadcast(uv_cond_t* cond) {
int have_waiters; int have_waiters;
/* Avoid race conditions. */ /* Avoid race conditions. */
@ -597,7 +598,7 @@ inline static void uv_cond_fallback_broadcast(uv_cond_t* cond) {
} }
inline static void uv_cond_condvar_broadcast(uv_cond_t* cond) { static void uv_cond_condvar_broadcast(uv_cond_t* cond) {
pWakeAllConditionVariable(&cond->cond_var); pWakeAllConditionVariable(&cond->cond_var);
} }
@ -610,7 +611,7 @@ void uv_cond_broadcast(uv_cond_t* cond) {
} }
inline int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex, static int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex,
DWORD dwMilliseconds) { DWORD dwMilliseconds) {
DWORD result; DWORD result;
int last_waiter; int last_waiter;
@ -660,13 +661,13 @@ inline int uv_cond_wait_helper(uv_cond_t* cond, uv_mutex_t* mutex,
} }
inline static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) { static void uv_cond_fallback_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
if (uv_cond_wait_helper(cond, mutex, INFINITE)) if (uv_cond_wait_helper(cond, mutex, INFINITE))
abort(); abort();
} }
inline static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) { static void uv_cond_condvar_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE)) if (!pSleepConditionVariableCS(&cond->cond_var, mutex, INFINITE))
abort(); abort();
} }
@ -680,13 +681,13 @@ void uv_cond_wait(uv_cond_t* cond, uv_mutex_t* mutex) {
} }
inline static int uv_cond_fallback_timedwait(uv_cond_t* cond, static int uv_cond_fallback_timedwait(uv_cond_t* cond,
uv_mutex_t* mutex, uint64_t timeout) { uv_mutex_t* mutex, uint64_t timeout) {
return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6)); return uv_cond_wait_helper(cond, mutex, (DWORD)(timeout / 1e6));
} }
inline static int uv_cond_condvar_timedwait(uv_cond_t* cond, static int uv_cond_condvar_timedwait(uv_cond_t* cond,
uv_mutex_t* mutex, uint64_t timeout) { uv_mutex_t* mutex, uint64_t timeout) {
if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6))) if (pSleepConditionVariableCS(&cond->cond_var, mutex, (DWORD)(timeout / 1e6)))
return 0; return 0;

24
deps/uv/test/test-fs.c

@ -436,7 +436,11 @@ static void scandir_cb(uv_fs_t* req) {
while (UV_EOF != uv_fs_scandir_next(req, &dent)) { while (UV_EOF != uv_fs_scandir_next(req, &dent)) {
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); #ifdef HAVE_DIRENT_TYPES
ASSERT(dent.type == UV_DIRENT_FILE);
#else
ASSERT(dent.type == UV_DIRENT_UNKNOWN);
#endif
} }
scandir_cb_count++; scandir_cb_count++;
ASSERT(req->path); ASSERT(req->path);
@ -875,7 +879,11 @@ TEST_IMPL(fs_async_dir) {
ASSERT(scandir_req.ptr); ASSERT(scandir_req.ptr);
while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); #ifdef HAVE_DIRENT_TYPES
ASSERT(dent.type == UV_DIRENT_FILE);
#else
ASSERT(dent.type == UV_DIRENT_UNKNOWN);
#endif
} }
uv_fs_req_cleanup(&scandir_req); uv_fs_req_cleanup(&scandir_req);
ASSERT(!scandir_req.ptr); ASSERT(!scandir_req.ptr);
@ -1695,7 +1703,11 @@ TEST_IMPL(fs_symlink_dir) {
ASSERT(scandir_req.ptr); ASSERT(scandir_req.ptr);
while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); #ifdef HAVE_DIRENT_TYPES
ASSERT(dent.type == UV_DIRENT_FILE);
#else
ASSERT(dent.type == UV_DIRENT_UNKNOWN);
#endif
} }
uv_fs_req_cleanup(&scandir_req); uv_fs_req_cleanup(&scandir_req);
ASSERT(!scandir_req.ptr); ASSERT(!scandir_req.ptr);
@ -1715,7 +1727,11 @@ TEST_IMPL(fs_symlink_dir) {
ASSERT(scandir_req.ptr); ASSERT(scandir_req.ptr);
while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) { while (UV_EOF != uv_fs_scandir_next(&scandir_req, &dent)) {
ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0); ASSERT(strcmp(dent.name, "file1") == 0 || strcmp(dent.name, "file2") == 0);
ASSERT(dent.type == UV_DIRENT_FILE || dent.type == UV_DIRENT_UNKNOWN); #ifdef HAVE_DIRENT_TYPES
ASSERT(dent.type == UV_DIRENT_FILE);
#else
ASSERT(dent.type == UV_DIRENT_UNKNOWN);
#endif
} }
uv_fs_req_cleanup(&scandir_req); uv_fs_req_cleanup(&scandir_req);
ASSERT(!scandir_req.ptr); ASSERT(!scandir_req.ptr);

2
deps/uv/test/test-list.h

@ -80,6 +80,7 @@ TEST_DECLARE (tcp_close_while_connecting)
TEST_DECLARE (tcp_close) TEST_DECLARE (tcp_close)
#ifndef _WIN32 #ifndef _WIN32
TEST_DECLARE (tcp_close_accept) TEST_DECLARE (tcp_close_accept)
TEST_DECLARE (tcp_oob)
#endif #endif
TEST_DECLARE (tcp_flags) TEST_DECLARE (tcp_flags)
TEST_DECLARE (tcp_write_to_half_open_connection) TEST_DECLARE (tcp_write_to_half_open_connection)
@ -396,6 +397,7 @@ TASK_LIST_START
TEST_ENTRY (tcp_close) TEST_ENTRY (tcp_close)
#ifndef _WIN32 #ifndef _WIN32
TEST_ENTRY (tcp_close_accept) TEST_ENTRY (tcp_close_accept)
TEST_ENTRY (tcp_oob)
#endif #endif
TEST_ENTRY (tcp_flags) TEST_ENTRY (tcp_flags)
TEST_ENTRY (tcp_write_to_half_open_connection) TEST_ENTRY (tcp_write_to_half_open_connection)

128
deps/uv/test/test-tcp-oob.c

@ -0,0 +1,128 @@
/* Copyright Fedor Indutny. All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
*/
#if !defined(_WIN32)
#include "uv.h"
#include "task.h"
#include <errno.h>
#include <sys/socket.h>
#include <unistd.h>
static uv_tcp_t server_handle;
static uv_tcp_t client_handle;
static uv_tcp_t peer_handle;
static uv_idle_t idle;
static uv_connect_t connect_req;
static int ticks;
static const int kMaxTicks = 10;
static void alloc_cb(uv_handle_t* handle,
size_t suggested_size,
uv_buf_t* buf) {
static char storage[1024];
*buf = uv_buf_init(storage, sizeof(storage));
}
static void idle_cb(uv_idle_t* idle) {
if (++ticks < kMaxTicks)
return;
uv_close((uv_handle_t*) &server_handle, NULL);
uv_close((uv_handle_t*) &client_handle, NULL);
uv_close((uv_handle_t*) &peer_handle, NULL);
uv_close((uv_handle_t*) idle, NULL);
}
static void read_cb(uv_stream_t* handle, ssize_t nread, const uv_buf_t* buf) {
ASSERT(nread > 0);
ASSERT(0 == uv_idle_start(&idle, idle_cb));
}
static void connect_cb(uv_connect_t* req, int status) {
ASSERT(req->handle == (uv_stream_t*) &client_handle);
ASSERT(0 == status);
}
static void connection_cb(uv_stream_t* handle, int status) {
int r;
uv_os_fd_t fd;
ASSERT(0 == status);
ASSERT(0 == uv_accept(handle, (uv_stream_t*) &peer_handle));
ASSERT(0 == uv_read_start((uv_stream_t*) &peer_handle, alloc_cb, read_cb));
/* Send some OOB data */
ASSERT(0 == uv_fileno((uv_handle_t*) &client_handle, &fd));
ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &client_handle, 1));
/* The problem triggers only on a second message, it seem that xnu is not
* triggering `kevent()` for the first one
*/
do {
r = send(fd, "hello", 5, MSG_OOB);
} while (r < 0 && errno == EINTR);
ASSERT(5 == r);
do {
r = send(fd, "hello", 5, MSG_OOB);
} while (r < 0 && errno == EINTR);
ASSERT(5 == r);
ASSERT(0 == uv_stream_set_blocking((uv_stream_t*) &client_handle, 0));
}
TEST_IMPL(tcp_oob) {
struct sockaddr_in addr;
uv_loop_t* loop;
ASSERT(0 == uv_ip4_addr("127.0.0.1", TEST_PORT, &addr));
loop = uv_default_loop();
ASSERT(0 == uv_tcp_init(loop, &server_handle));
ASSERT(0 == uv_tcp_init(loop, &client_handle));
ASSERT(0 == uv_tcp_init(loop, &peer_handle));
ASSERT(0 == uv_idle_init(loop, &idle));
ASSERT(0 == uv_tcp_bind(&server_handle, (const struct sockaddr*) &addr, 0));
ASSERT(0 == uv_listen((uv_stream_t*) &server_handle, 1, connection_cb));
/* Ensure two separate packets */
ASSERT(0 == uv_tcp_nodelay(&client_handle, 1));
ASSERT(0 == uv_tcp_connect(&connect_req,
&client_handle,
(const struct sockaddr*) &addr,
connect_cb));
ASSERT(0 == uv_run(loop, UV_RUN_DEFAULT));
ASSERT(ticks == kMaxTicks);
MAKE_VALGRIND_HAPPY();
return 0;
}
#endif

1
deps/uv/uv.gyp

@ -366,6 +366,7 @@
'test/test-tcp-writealot.c', 'test/test-tcp-writealot.c',
'test/test-tcp-try-write.c', 'test/test-tcp-try-write.c',
'test/test-tcp-unexpected-read.c', 'test/test-tcp-unexpected-read.c',
'test/test-tcp-oob.c',
'test/test-tcp-read-stop.c', 'test/test-tcp-read-stop.c',
'test/test-tcp-write-queue-order.c', 'test/test-tcp-write-queue-order.c',
'test/test-threadpool.c', 'test/test-threadpool.c',

Loading…
Cancel
Save