deps: upgrade libuv to 1.7.5
PR-URL: https://github.com/nodejs/node/pull/3010 Reviewed-By: Rod Vagg <rod@vagg.org> Reviewed-By: Trevor Norris <trev.norris@gmail.com> Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
This commit is contained in:
parent
a6aab43093
commit
07a43eb129
1
deps/uv/AUTHORS
vendored
1
deps/uv/AUTHORS
vendored
@ -224,3 +224,4 @@ Jianghua Yang <jianghua.yjh@alibaba-inc.com>
|
|||||||
Colin Snover <github.com@zetafleet.com>
|
Colin Snover <github.com@zetafleet.com>
|
||||||
Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
|
Sakthipriyan Vairamani <thechargingvolcano@gmail.com>
|
||||||
Eli Skeggs <skeggse@gmail.com>
|
Eli Skeggs <skeggse@gmail.com>
|
||||||
|
nmushell <nmushell@bloomberg.net>
|
||||||
|
21
deps/uv/ChangeLog
vendored
21
deps/uv/ChangeLog
vendored
@ -1,3 +1,24 @@
|
|||||||
|
2015.09.23, Version 1.7.5 (Stable), a8c1136de2cabf25b143021488cbaab05834daa8
|
||||||
|
|
||||||
|
Changes since version 1.7.4:
|
||||||
|
|
||||||
|
* unix: Support atomic compare & swap xlC on AIX (nmushell)
|
||||||
|
|
||||||
|
* unix: Fix including uv-aix.h on AIX (nmushell)
|
||||||
|
|
||||||
|
* unix: consolidate rwlock tryrdlock trywrlock errors (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* unix, win: consolidate mutex trylock errors (Saúl Ibarra Corretgé)
|
||||||
|
|
||||||
|
* darwin: fix memory leak in uv_cpu_info (Jianghua Yang)
|
||||||
|
|
||||||
|
* test: add tests for the uv_rwlock implementation (Bert Belder)
|
||||||
|
|
||||||
|
* win: redo/fix the uv_rwlock APIs (Bert Belder)
|
||||||
|
|
||||||
|
* win: don't fetch function pointers to SRWLock APIs (Bert Belder)
|
||||||
|
|
||||||
|
|
||||||
2015.09.12, Version 1.7.4 (Stable), a7ad4f52189d89cfcba35f78bfc5ff3b1f4105c4
|
2015.09.12, Version 1.7.4 (Stable), a7ad4f52189d89cfcba35f78bfc5ff3b1f4105c4
|
||||||
|
|
||||||
Changes since version 1.7.3:
|
Changes since version 1.7.3:
|
||||||
|
1
deps/uv/Makefile.am
vendored
1
deps/uv/Makefile.am
vendored
@ -280,6 +280,7 @@ endif
|
|||||||
|
|
||||||
if AIX
|
if AIX
|
||||||
libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT
|
libuv_la_CFLAGS += -D_ALL_SOURCE -D_XOPEN_SOURCE=500 -D_LINUX_SOURCE_COMPAT
|
||||||
|
include_HEADERS += include/uv-aix.h
|
||||||
libuv_la_SOURCES += src/unix/aix.c
|
libuv_la_SOURCES += src/unix/aix.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
2
deps/uv/appveyor.yml
vendored
2
deps/uv/appveyor.yml
vendored
@ -1,4 +1,4 @@
|
|||||||
version: v1.7.4.build{build}
|
version: v1.7.5.build{build}
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- cinst -y nsis
|
- cinst -y nsis
|
||||||
|
2
deps/uv/configure.ac
vendored
2
deps/uv/configure.ac
vendored
@ -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.7.4], [https://github.com/libuv/libuv/issues])
|
AC_INIT([libuv], [1.7.5], [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])
|
||||||
|
2
deps/uv/include/uv-version.h
vendored
2
deps/uv/include/uv-version.h
vendored
@ -32,7 +32,7 @@
|
|||||||
|
|
||||||
#define UV_VERSION_MAJOR 1
|
#define UV_VERSION_MAJOR 1
|
||||||
#define UV_VERSION_MINOR 7
|
#define UV_VERSION_MINOR 7
|
||||||
#define UV_VERSION_PATCH 4
|
#define UV_VERSION_PATCH 5
|
||||||
#define UV_VERSION_IS_RELEASE 1
|
#define UV_VERSION_IS_RELEASE 1
|
||||||
#define UV_VERSION_SUFFIX ""
|
#define UV_VERSION_SUFFIX ""
|
||||||
|
|
||||||
|
26
deps/uv/include/uv-win.h
vendored
26
deps/uv/include/uv-win.h
vendored
@ -246,22 +246,20 @@ typedef union {
|
|||||||
} uv_cond_t;
|
} uv_cond_t;
|
||||||
|
|
||||||
typedef union {
|
typedef union {
|
||||||
/* srwlock_ has type SRWLOCK, but not all toolchains define this type in */
|
|
||||||
/* windows.h. */
|
|
||||||
SRWLOCK srwlock_;
|
|
||||||
struct {
|
struct {
|
||||||
union {
|
|
||||||
CRITICAL_SECTION cs;
|
|
||||||
/* TODO: remove me in v2.x. */
|
|
||||||
uv_mutex_t unused;
|
|
||||||
} read_lock_;
|
|
||||||
union {
|
|
||||||
HANDLE sem;
|
|
||||||
/* TODO: remove me in v2.x. */
|
|
||||||
uv_mutex_t unused;
|
|
||||||
} write_lock_;
|
|
||||||
unsigned int num_readers_;
|
unsigned int num_readers_;
|
||||||
} fallback_;
|
CRITICAL_SECTION num_readers_lock_;
|
||||||
|
HANDLE write_semaphore_;
|
||||||
|
} state_;
|
||||||
|
/* TODO: remove me in v2.x. */
|
||||||
|
struct {
|
||||||
|
SRWLOCK unused_;
|
||||||
|
} unused1_;
|
||||||
|
/* TODO: remove me in v2.x. */
|
||||||
|
struct {
|
||||||
|
uv_mutex_t unused1_;
|
||||||
|
uv_mutex_t unused2_;
|
||||||
|
} unused2_;
|
||||||
} uv_rwlock_t;
|
} uv_rwlock_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
12
deps/uv/src/unix/atomic-ops.h
vendored
12
deps/uv/src/unix/atomic-ops.h
vendored
@ -33,6 +33,10 @@ UV_UNUSED(static int cmpxchgi(int* ptr, int oldval, int newval)) {
|
|||||||
: "r" (newval), "0" (oldval)
|
: "r" (newval), "0" (oldval)
|
||||||
: "memory");
|
: "memory");
|
||||||
return out;
|
return out;
|
||||||
|
#elif defined(_AIX) && defined(__xlC__)
|
||||||
|
const int out = (*(volatile int*) ptr);
|
||||||
|
__compare_and_swap(ptr, &oldval, newval);
|
||||||
|
return out;
|
||||||
#else
|
#else
|
||||||
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
||||||
#endif
|
#endif
|
||||||
@ -46,6 +50,14 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
|
|||||||
: "r" (newval), "0" (oldval)
|
: "r" (newval), "0" (oldval)
|
||||||
: "memory");
|
: "memory");
|
||||||
return out;
|
return out;
|
||||||
|
#elif defined(_AIX) && defined(__xlC__)
|
||||||
|
const long out = (*(volatile int*) ptr);
|
||||||
|
# if defined(__64BIT__)
|
||||||
|
__compare_and_swaplp(ptr, &oldval, newval);
|
||||||
|
# else
|
||||||
|
__compare_and_swap(ptr, &oldval, newval);
|
||||||
|
# endif /* if defined(__64BIT__) */
|
||||||
|
return out;
|
||||||
#else
|
#else
|
||||||
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
||||||
#endif
|
#endif
|
||||||
|
6
deps/uv/src/unix/darwin.c
vendored
6
deps/uv/src/unix/darwin.c
vendored
@ -199,8 +199,10 @@ int uv_cpu_info(uv_cpu_info_t** cpu_infos, int* count) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
*cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
|
*cpu_infos = uv__malloc(numcpus * sizeof(**cpu_infos));
|
||||||
if (!(*cpu_infos))
|
if (!(*cpu_infos)) {
|
||||||
return -ENOMEM; /* FIXME(bnoordhuis) Deallocate info? */
|
vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
*count = numcpus;
|
*count = numcpus;
|
||||||
|
|
||||||
|
30
deps/uv/src/unix/thread.c
vendored
30
deps/uv/src/unix/thread.c
vendored
@ -124,14 +124,14 @@ void uv_mutex_lock(uv_mutex_t* mutex) {
|
|||||||
int uv_mutex_trylock(uv_mutex_t* mutex) {
|
int uv_mutex_trylock(uv_mutex_t* mutex) {
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* FIXME(bnoordhuis) EAGAIN means recursive lock limit reached. Arguably
|
|
||||||
* a bug, should probably abort rather than return -EAGAIN.
|
|
||||||
*/
|
|
||||||
err = pthread_mutex_trylock(mutex);
|
err = pthread_mutex_trylock(mutex);
|
||||||
if (err && err != EBUSY && err != EAGAIN)
|
if (err) {
|
||||||
abort();
|
if (err != EBUSY && err != EAGAIN)
|
||||||
|
abort();
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
return -err;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -162,10 +162,13 @@ int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = pthread_rwlock_tryrdlock(rwlock);
|
err = pthread_rwlock_tryrdlock(rwlock);
|
||||||
if (err && err != EBUSY && err != EAGAIN)
|
if (err) {
|
||||||
abort();
|
if (err != EBUSY && err != EAGAIN)
|
||||||
|
abort();
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
return -err;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -185,10 +188,13 @@ int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = pthread_rwlock_trywrlock(rwlock);
|
err = pthread_rwlock_trywrlock(rwlock);
|
||||||
if (err && err != EBUSY && err != EAGAIN)
|
if (err) {
|
||||||
abort();
|
if (err != EBUSY && err != EAGAIN)
|
||||||
|
abort();
|
||||||
|
return -EBUSY;
|
||||||
|
}
|
||||||
|
|
||||||
return -err;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
280
deps/uv/src/win/thread.c
vendored
280
deps/uv/src/win/thread.c
vendored
@ -27,28 +27,8 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
|
|
||||||
#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != NULL)
|
|
||||||
#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
|
#define HAVE_CONDVAR_API() (pInitializeConditionVariable != NULL)
|
||||||
|
|
||||||
static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock);
|
|
||||||
static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock);
|
|
||||||
static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock);
|
|
||||||
|
|
||||||
static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock);
|
|
||||||
static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock);
|
|
||||||
static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock);
|
|
||||||
static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock);
|
|
||||||
|
|
||||||
|
|
||||||
static int uv_cond_fallback_init(uv_cond_t* cond);
|
static int uv_cond_fallback_init(uv_cond_t* cond);
|
||||||
static void uv_cond_fallback_destroy(uv_cond_t* cond);
|
static void uv_cond_fallback_destroy(uv_cond_t* cond);
|
||||||
static void uv_cond_fallback_signal(uv_cond_t* cond);
|
static void uv_cond_fallback_signal(uv_cond_t* cond);
|
||||||
@ -232,7 +212,7 @@ int uv_mutex_trylock(uv_mutex_t* mutex) {
|
|||||||
if (TryEnterCriticalSection(mutex))
|
if (TryEnterCriticalSection(mutex))
|
||||||
return 0;
|
return 0;
|
||||||
else
|
else
|
||||||
return UV_EAGAIN;
|
return UV_EBUSY;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -242,68 +222,111 @@ void uv_mutex_unlock(uv_mutex_t* mutex) {
|
|||||||
|
|
||||||
|
|
||||||
int uv_rwlock_init(uv_rwlock_t* rwlock) {
|
int uv_rwlock_init(uv_rwlock_t* rwlock) {
|
||||||
uv__once_init();
|
/* Initialize the semaphore that acts as the write lock. */
|
||||||
|
HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL);
|
||||||
|
if (handle == NULL)
|
||||||
|
return uv_translate_sys_error(GetLastError());
|
||||||
|
rwlock->state_.write_semaphore_ = handle;
|
||||||
|
|
||||||
if (HAVE_SRWLOCK_API())
|
/* Initialize the critical section protecting the reader count. */
|
||||||
return uv__rwlock_srwlock_init(rwlock);
|
InitializeCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||||
else
|
|
||||||
return uv__rwlock_fallback_init(rwlock);
|
/* Initialize the reader count. */
|
||||||
|
rwlock->state_.num_readers_ = 0;
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
|
void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
|
||||||
if (HAVE_SRWLOCK_API())
|
DeleteCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||||
uv__rwlock_srwlock_destroy(rwlock);
|
CloseHandle(rwlock->state_.write_semaphore_);
|
||||||
else
|
|
||||||
uv__rwlock_fallback_destroy(rwlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
|
void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
|
||||||
if (HAVE_SRWLOCK_API())
|
/* Acquire the lock that protects the reader count. */
|
||||||
uv__rwlock_srwlock_rdlock(rwlock);
|
EnterCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||||
else
|
|
||||||
uv__rwlock_fallback_rdlock(rwlock);
|
/* Increase the reader count, and lock for write if this is the first
|
||||||
|
* reader.
|
||||||
|
*/
|
||||||
|
if (++rwlock->state_.num_readers_ == 1) {
|
||||||
|
DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE);
|
||||||
|
if (r != WAIT_OBJECT_0)
|
||||||
|
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Release the lock that protects the reader count. */
|
||||||
|
LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
|
int uv_rwlock_tryrdlock(uv_rwlock_t* rwlock) {
|
||||||
if (HAVE_SRWLOCK_API())
|
int err;
|
||||||
return uv__rwlock_srwlock_tryrdlock(rwlock);
|
|
||||||
else
|
if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_))
|
||||||
return uv__rwlock_fallback_tryrdlock(rwlock);
|
return UV_EBUSY;
|
||||||
|
|
||||||
|
err = 0;
|
||||||
|
|
||||||
|
if (rwlock->state_.num_readers_ == 0) {
|
||||||
|
/* Currently there are no other readers, which means that the write lock
|
||||||
|
* needs to be acquired.
|
||||||
|
*/
|
||||||
|
DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0);
|
||||||
|
if (r == WAIT_OBJECT_0)
|
||||||
|
rwlock->state_.num_readers_++;
|
||||||
|
else if (r == WAIT_TIMEOUT)
|
||||||
|
err = UV_EBUSY;
|
||||||
|
else if (r == WAIT_FAILED)
|
||||||
|
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
/* The write lock has already been acquired because there are other
|
||||||
|
* active readers.
|
||||||
|
*/
|
||||||
|
rwlock->state_.num_readers_++;
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||||
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
|
void uv_rwlock_rdunlock(uv_rwlock_t* rwlock) {
|
||||||
if (HAVE_SRWLOCK_API())
|
EnterCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||||
uv__rwlock_srwlock_rdunlock(rwlock);
|
|
||||||
else
|
if (--rwlock->state_.num_readers_ == 0) {
|
||||||
uv__rwlock_fallback_rdunlock(rwlock);
|
if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL))
|
||||||
|
uv_fatal_error(GetLastError(), "ReleaseSemaphore");
|
||||||
|
}
|
||||||
|
|
||||||
|
LeaveCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
|
void uv_rwlock_wrlock(uv_rwlock_t* rwlock) {
|
||||||
if (HAVE_SRWLOCK_API())
|
DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE);
|
||||||
uv__rwlock_srwlock_wrlock(rwlock);
|
if (r != WAIT_OBJECT_0)
|
||||||
else
|
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
||||||
uv__rwlock_fallback_wrlock(rwlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
|
int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
|
||||||
if (HAVE_SRWLOCK_API())
|
DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0);
|
||||||
return uv__rwlock_srwlock_trywrlock(rwlock);
|
if (r == WAIT_OBJECT_0)
|
||||||
|
return 0;
|
||||||
|
else if (r == WAIT_TIMEOUT)
|
||||||
|
return UV_EBUSY;
|
||||||
else
|
else
|
||||||
return uv__rwlock_fallback_trywrlock(rwlock);
|
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
|
void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
|
||||||
if (HAVE_SRWLOCK_API())
|
if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL))
|
||||||
uv__rwlock_srwlock_wrunlock(rwlock);
|
uv_fatal_error(GetLastError(), "ReleaseSemaphore");
|
||||||
else
|
|
||||||
uv__rwlock_fallback_wrunlock(rwlock);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -348,157 +371,6 @@ int uv_sem_trywait(uv_sem_t* sem) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int uv__rwlock_srwlock_init(uv_rwlock_t* rwlock) {
|
|
||||||
pInitializeSRWLock(&rwlock->srwlock_);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_srwlock_destroy(uv_rwlock_t* rwlock) {
|
|
||||||
(void) rwlock;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_srwlock_rdlock(uv_rwlock_t* rwlock) {
|
|
||||||
pAcquireSRWLockShared(&rwlock->srwlock_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int uv__rwlock_srwlock_tryrdlock(uv_rwlock_t* rwlock) {
|
|
||||||
if (pTryAcquireSRWLockShared(&rwlock->srwlock_))
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return UV_EBUSY; /* TODO(bnoordhuis) EAGAIN when owned by this thread. */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_srwlock_rdunlock(uv_rwlock_t* rwlock) {
|
|
||||||
pReleaseSRWLockShared(&rwlock->srwlock_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_srwlock_wrlock(uv_rwlock_t* rwlock) {
|
|
||||||
pAcquireSRWLockExclusive(&rwlock->srwlock_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int uv__rwlock_srwlock_trywrlock(uv_rwlock_t* rwlock) {
|
|
||||||
if (pTryAcquireSRWLockExclusive(&rwlock->srwlock_))
|
|
||||||
return 0;
|
|
||||||
else
|
|
||||||
return UV_EBUSY; /* TODO(bnoordhuis) EAGAIN when owned by this thread. */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_srwlock_wrunlock(uv_rwlock_t* rwlock) {
|
|
||||||
pReleaseSRWLockExclusive(&rwlock->srwlock_);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int uv__rwlock_fallback_init(uv_rwlock_t* rwlock) {
|
|
||||||
/* Initialize the semaphore that acts as the write lock. */
|
|
||||||
HANDLE handle = CreateSemaphoreW(NULL, 1, 1, NULL);
|
|
||||||
if (handle == NULL)
|
|
||||||
return uv_translate_sys_error(GetLastError());
|
|
||||||
rwlock->fallback_.write_lock_.sem = handle;
|
|
||||||
|
|
||||||
/* Initialize the critical section protecting the reader count. */
|
|
||||||
InitializeCriticalSection(&rwlock->fallback_.read_lock_.cs);
|
|
||||||
|
|
||||||
/* Initialize the reader count. */
|
|
||||||
rwlock->fallback_.num_readers_ = 0;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_fallback_destroy(uv_rwlock_t* rwlock) {
|
|
||||||
DeleteCriticalSection(&rwlock->fallback_.read_lock_.cs);
|
|
||||||
CloseHandle(rwlock->fallback_.write_lock_.sem);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_fallback_rdlock(uv_rwlock_t* rwlock) {
|
|
||||||
/* Acquire the lock that protects the reader count. */
|
|
||||||
EnterCriticalSection(&rwlock->fallback_.read_lock_.cs);
|
|
||||||
|
|
||||||
/* Increase the reader count, and lock for write if this is the first
|
|
||||||
* reader.
|
|
||||||
*/
|
|
||||||
if (++rwlock->fallback_.num_readers_ == 1) {
|
|
||||||
DWORD r = WaitForSingleObject(rwlock->fallback_.write_lock_.sem, INFINITE);
|
|
||||||
if (r != WAIT_OBJECT_0)
|
|
||||||
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Release the lock that protects the reader count. */
|
|
||||||
LeaveCriticalSection(&rwlock->fallback_.read_lock_.cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int uv__rwlock_fallback_tryrdlock(uv_rwlock_t* rwlock) {
|
|
||||||
int err;
|
|
||||||
|
|
||||||
if (!TryEnterCriticalSection(&rwlock->fallback_.read_lock_.cs))
|
|
||||||
return UV_EAGAIN;
|
|
||||||
|
|
||||||
err = 0;
|
|
||||||
if (rwlock->fallback_.num_readers_ == 0) {
|
|
||||||
DWORD r = WaitForSingleObject(rwlock->fallback_.write_lock_.sem, 0);
|
|
||||||
if (r == WAIT_OBJECT_0)
|
|
||||||
rwlock->fallback_.num_readers_++;
|
|
||||||
else if (r == WAIT_TIMEOUT)
|
|
||||||
err = UV_EAGAIN;
|
|
||||||
else if (r == WAIT_FAILED)
|
|
||||||
err = uv_translate_sys_error(GetLastError());
|
|
||||||
else
|
|
||||||
err = UV_EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&rwlock->fallback_.read_lock_.cs);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_fallback_rdunlock(uv_rwlock_t* rwlock) {
|
|
||||||
EnterCriticalSection(&rwlock->fallback_.read_lock_.cs);
|
|
||||||
|
|
||||||
if (--rwlock->fallback_.num_readers_ == 0) {
|
|
||||||
if (!ReleaseSemaphore(rwlock->fallback_.write_lock_.sem, 1, NULL))
|
|
||||||
uv_fatal_error(GetLastError(), "ReleaseSemaphore");
|
|
||||||
}
|
|
||||||
|
|
||||||
LeaveCriticalSection(&rwlock->fallback_.read_lock_.cs);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_fallback_wrlock(uv_rwlock_t* rwlock) {
|
|
||||||
DWORD r = WaitForSingleObject(rwlock->fallback_.write_lock_.sem, INFINITE);
|
|
||||||
if (r != WAIT_OBJECT_0)
|
|
||||||
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static int uv__rwlock_fallback_trywrlock(uv_rwlock_t* rwlock) {
|
|
||||||
DWORD r = WaitForSingleObject(rwlock->fallback_.write_lock_.sem, 0);
|
|
||||||
if (r == WAIT_OBJECT_0)
|
|
||||||
return 0;
|
|
||||||
else if (r == WAIT_TIMEOUT)
|
|
||||||
return UV_EAGAIN;
|
|
||||||
else if (r == WAIT_FAILED)
|
|
||||||
return uv_translate_sys_error(GetLastError());
|
|
||||||
else
|
|
||||||
return UV_EIO;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static void uv__rwlock_fallback_wrunlock(uv_rwlock_t* rwlock) {
|
|
||||||
if (!ReleaseSemaphore(rwlock->fallback_.write_lock_.sem, 1, NULL))
|
|
||||||
uv_fatal_error(GetLastError(), "ReleaseSemaphore");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* This condition variable implementation is based on the SetEvent solution
|
/* This condition variable implementation is based on the SetEvent solution
|
||||||
* (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
* (section 3.2) at http://www.cs.wustl.edu/~schmidt/win32-cv-1.html
|
||||||
* We could not use the SignalObjectAndWait solution (section 3.4) because
|
* We could not use the SignalObjectAndWait solution (section 3.4) because
|
||||||
|
28
deps/uv/src/win/winapi.c
vendored
28
deps/uv/src/win/winapi.c
vendored
@ -40,13 +40,6 @@ sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
|||||||
sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
||||||
sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
||||||
sCancelIoEx pCancelIoEx;
|
sCancelIoEx pCancelIoEx;
|
||||||
sInitializeSRWLock pInitializeSRWLock;
|
|
||||||
sAcquireSRWLockShared pAcquireSRWLockShared;
|
|
||||||
sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
|
|
||||||
sTryAcquireSRWLockShared pTryAcquireSRWLockShared;
|
|
||||||
sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive;
|
|
||||||
sReleaseSRWLockShared pReleaseSRWLockShared;
|
|
||||||
sReleaseSRWLockExclusive pReleaseSRWLockExclusive;
|
|
||||||
sInitializeConditionVariable pInitializeConditionVariable;
|
sInitializeConditionVariable pInitializeConditionVariable;
|
||||||
sSleepConditionVariableCS pSleepConditionVariableCS;
|
sSleepConditionVariableCS pSleepConditionVariableCS;
|
||||||
sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
||||||
@ -129,27 +122,6 @@ void uv_winapi_init() {
|
|||||||
pCancelIoEx = (sCancelIoEx)
|
pCancelIoEx = (sCancelIoEx)
|
||||||
GetProcAddress(kernel32_module, "CancelIoEx");
|
GetProcAddress(kernel32_module, "CancelIoEx");
|
||||||
|
|
||||||
pInitializeSRWLock = (sInitializeSRWLock)
|
|
||||||
GetProcAddress(kernel32_module, "InitializeSRWLock");
|
|
||||||
|
|
||||||
pAcquireSRWLockShared = (sAcquireSRWLockShared)
|
|
||||||
GetProcAddress(kernel32_module, "AcquireSRWLockShared");
|
|
||||||
|
|
||||||
pAcquireSRWLockExclusive = (sAcquireSRWLockExclusive)
|
|
||||||
GetProcAddress(kernel32_module, "AcquireSRWLockExclusive");
|
|
||||||
|
|
||||||
pTryAcquireSRWLockShared = (sTryAcquireSRWLockShared)
|
|
||||||
GetProcAddress(kernel32_module, "TryAcquireSRWLockShared");
|
|
||||||
|
|
||||||
pTryAcquireSRWLockExclusive = (sTryAcquireSRWLockExclusive)
|
|
||||||
GetProcAddress(kernel32_module, "TryAcquireSRWLockExclusive");
|
|
||||||
|
|
||||||
pReleaseSRWLockShared = (sReleaseSRWLockShared)
|
|
||||||
GetProcAddress(kernel32_module, "ReleaseSRWLockShared");
|
|
||||||
|
|
||||||
pReleaseSRWLockExclusive = (sReleaseSRWLockExclusive)
|
|
||||||
GetProcAddress(kernel32_module, "ReleaseSRWLockExclusive");
|
|
||||||
|
|
||||||
pInitializeConditionVariable = (sInitializeConditionVariable)
|
pInitializeConditionVariable = (sInitializeConditionVariable)
|
||||||
GetProcAddress(kernel32_module, "InitializeConditionVariable");
|
GetProcAddress(kernel32_module, "InitializeConditionVariable");
|
||||||
|
|
||||||
|
28
deps/uv/src/win/winapi.h
vendored
28
deps/uv/src/win/winapi.h
vendored
@ -4655,27 +4655,6 @@ typedef BOOL (WINAPI* sCancelIoEx)
|
|||||||
(HANDLE hFile,
|
(HANDLE hFile,
|
||||||
LPOVERLAPPED lpOverlapped);
|
LPOVERLAPPED lpOverlapped);
|
||||||
|
|
||||||
typedef VOID (WINAPI* sInitializeSRWLock)
|
|
||||||
(PSRWLOCK SRWLock);
|
|
||||||
|
|
||||||
typedef VOID (WINAPI* sAcquireSRWLockShared)
|
|
||||||
(PSRWLOCK SRWLock);
|
|
||||||
|
|
||||||
typedef VOID (WINAPI* sAcquireSRWLockExclusive)
|
|
||||||
(PSRWLOCK SRWLock);
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI* sTryAcquireSRWLockShared)
|
|
||||||
(PSRWLOCK SRWLock);
|
|
||||||
|
|
||||||
typedef BOOL (WINAPI* sTryAcquireSRWLockExclusive)
|
|
||||||
(PSRWLOCK SRWLock);
|
|
||||||
|
|
||||||
typedef VOID (WINAPI* sReleaseSRWLockShared)
|
|
||||||
(PSRWLOCK SRWLock);
|
|
||||||
|
|
||||||
typedef VOID (WINAPI* sReleaseSRWLockExclusive)
|
|
||||||
(PSRWLOCK SRWLock);
|
|
||||||
|
|
||||||
typedef VOID (WINAPI* sInitializeConditionVariable)
|
typedef VOID (WINAPI* sInitializeConditionVariable)
|
||||||
(PCONDITION_VARIABLE ConditionVariable);
|
(PCONDITION_VARIABLE ConditionVariable);
|
||||||
|
|
||||||
@ -4714,13 +4693,6 @@ extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
|||||||
extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
||||||
extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
||||||
extern sCancelIoEx pCancelIoEx;
|
extern sCancelIoEx pCancelIoEx;
|
||||||
extern sInitializeSRWLock pInitializeSRWLock;
|
|
||||||
extern sAcquireSRWLockShared pAcquireSRWLockShared;
|
|
||||||
extern sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
|
|
||||||
extern sTryAcquireSRWLockShared pTryAcquireSRWLockShared;
|
|
||||||
extern sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive;
|
|
||||||
extern sReleaseSRWLockShared pReleaseSRWLockShared;
|
|
||||||
extern sReleaseSRWLockExclusive pReleaseSRWLockExclusive;
|
|
||||||
extern sInitializeConditionVariable pInitializeConditionVariable;
|
extern sInitializeConditionVariable pInitializeConditionVariable;
|
||||||
extern sSleepConditionVariableCS pSleepConditionVariableCS;
|
extern sSleepConditionVariableCS pSleepConditionVariableCS;
|
||||||
extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
extern sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
||||||
|
2
deps/uv/test/test-list.h
vendored
2
deps/uv/test/test-list.h
vendored
@ -291,6 +291,7 @@ TEST_DECLARE (threadpool_cancel_single)
|
|||||||
TEST_DECLARE (thread_local_storage)
|
TEST_DECLARE (thread_local_storage)
|
||||||
TEST_DECLARE (thread_mutex)
|
TEST_DECLARE (thread_mutex)
|
||||||
TEST_DECLARE (thread_rwlock)
|
TEST_DECLARE (thread_rwlock)
|
||||||
|
TEST_DECLARE (thread_rwlock_trylock)
|
||||||
TEST_DECLARE (thread_create)
|
TEST_DECLARE (thread_create)
|
||||||
TEST_DECLARE (thread_equal)
|
TEST_DECLARE (thread_equal)
|
||||||
TEST_DECLARE (dlerror)
|
TEST_DECLARE (dlerror)
|
||||||
@ -707,6 +708,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (thread_local_storage)
|
TEST_ENTRY (thread_local_storage)
|
||||||
TEST_ENTRY (thread_mutex)
|
TEST_ENTRY (thread_mutex)
|
||||||
TEST_ENTRY (thread_rwlock)
|
TEST_ENTRY (thread_rwlock)
|
||||||
|
TEST_ENTRY (thread_rwlock_trylock)
|
||||||
TEST_ENTRY (thread_create)
|
TEST_ENTRY (thread_create)
|
||||||
TEST_ENTRY (thread_equal)
|
TEST_ENTRY (thread_equal)
|
||||||
TEST_ENTRY (dlerror)
|
TEST_ENTRY (dlerror)
|
||||||
|
59
deps/uv/test/test-mutexes.c
vendored
59
deps/uv/test/test-mutexes.c
vendored
@ -61,3 +61,62 @@ TEST_IMPL(thread_rwlock) {
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TEST_IMPL(thread_rwlock_trylock) {
|
||||||
|
uv_rwlock_t rwlock;
|
||||||
|
int r;
|
||||||
|
|
||||||
|
r = uv_rwlock_init(&rwlock);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* No locks held. */
|
||||||
|
|
||||||
|
r = uv_rwlock_trywrlock(&rwlock);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* Write lock held. */
|
||||||
|
|
||||||
|
r = uv_rwlock_tryrdlock(&rwlock);
|
||||||
|
ASSERT(r == UV_EBUSY);
|
||||||
|
r = uv_rwlock_trywrlock(&rwlock);
|
||||||
|
ASSERT(r == UV_EBUSY);
|
||||||
|
|
||||||
|
uv_rwlock_wrunlock(&rwlock);
|
||||||
|
|
||||||
|
/* No locks held. */
|
||||||
|
|
||||||
|
r = uv_rwlock_tryrdlock(&rwlock);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* One read lock held. */
|
||||||
|
|
||||||
|
r = uv_rwlock_tryrdlock(&rwlock);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* Two read locks held. */
|
||||||
|
|
||||||
|
r = uv_rwlock_trywrlock(&rwlock);
|
||||||
|
ASSERT(r == UV_EBUSY);
|
||||||
|
|
||||||
|
uv_rwlock_rdunlock(&rwlock);
|
||||||
|
|
||||||
|
/* One read lock held. */
|
||||||
|
|
||||||
|
uv_rwlock_rdunlock(&rwlock);
|
||||||
|
|
||||||
|
/* No read locks held. */
|
||||||
|
|
||||||
|
r = uv_rwlock_trywrlock(&rwlock);
|
||||||
|
ASSERT(r == 0);
|
||||||
|
|
||||||
|
/* Write lock held. */
|
||||||
|
|
||||||
|
uv_rwlock_wrunlock(&rwlock);
|
||||||
|
|
||||||
|
/* No locks held. */
|
||||||
|
|
||||||
|
uv_rwlock_destroy(&rwlock);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user