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>
|
||||
Sakthipriyan Vairamani <thechargingvolcano@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
|
||||
|
||||
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
|
||||
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
|
||||
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:
|
||||
- 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.
|
||||
|
||||
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])
|
||||
m4_include([m4/libuv-extra-automake-flags.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_MINOR 7
|
||||
#define UV_VERSION_PATCH 4
|
||||
#define UV_VERSION_PATCH 5
|
||||
#define UV_VERSION_IS_RELEASE 1
|
||||
#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;
|
||||
|
||||
typedef union {
|
||||
/* srwlock_ has type SRWLOCK, but not all toolchains define this type in */
|
||||
/* windows.h. */
|
||||
SRWLOCK srwlock_;
|
||||
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_;
|
||||
} 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;
|
||||
|
||||
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)
|
||||
: "memory");
|
||||
return out;
|
||||
#elif defined(_AIX) && defined(__xlC__)
|
||||
const int out = (*(volatile int*) ptr);
|
||||
__compare_and_swap(ptr, &oldval, newval);
|
||||
return out;
|
||||
#else
|
||||
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
||||
#endif
|
||||
@ -46,6 +50,14 @@ UV_UNUSED(static long cmpxchgl(long* ptr, long oldval, long newval)) {
|
||||
: "r" (newval), "0" (oldval)
|
||||
: "memory");
|
||||
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
|
||||
return __sync_val_compare_and_swap(ptr, oldval, newval);
|
||||
#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));
|
||||
if (!(*cpu_infos))
|
||||
return -ENOMEM; /* FIXME(bnoordhuis) Deallocate info? */
|
||||
if (!(*cpu_infos)) {
|
||||
vm_deallocate(mach_task_self(), (vm_address_t)info, msg_type);
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
*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 err;
|
||||
|
||||
/* FIXME(bnoordhuis) EAGAIN means recursive lock limit reached. Arguably
|
||||
* a bug, should probably abort rather than return -EAGAIN.
|
||||
*/
|
||||
err = pthread_mutex_trylock(mutex);
|
||||
if (err && err != EBUSY && err != EAGAIN)
|
||||
abort();
|
||||
if (err) {
|
||||
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;
|
||||
|
||||
err = pthread_rwlock_tryrdlock(rwlock);
|
||||
if (err && err != EBUSY && err != EAGAIN)
|
||||
abort();
|
||||
if (err) {
|
||||
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;
|
||||
|
||||
err = pthread_rwlock_trywrlock(rwlock);
|
||||
if (err && err != EBUSY && err != EAGAIN)
|
||||
abort();
|
||||
if (err) {
|
||||
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"
|
||||
|
||||
|
||||
#define HAVE_SRWLOCK_API() (pTryAcquireSRWLockShared != 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 void uv_cond_fallback_destroy(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))
|
||||
return 0;
|
||||
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) {
|
||||
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())
|
||||
return uv__rwlock_srwlock_init(rwlock);
|
||||
else
|
||||
return uv__rwlock_fallback_init(rwlock);
|
||||
/* Initialize the critical section protecting the reader count. */
|
||||
InitializeCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||
|
||||
/* Initialize the reader count. */
|
||||
rwlock->state_.num_readers_ = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void uv_rwlock_destroy(uv_rwlock_t* rwlock) {
|
||||
if (HAVE_SRWLOCK_API())
|
||||
uv__rwlock_srwlock_destroy(rwlock);
|
||||
else
|
||||
uv__rwlock_fallback_destroy(rwlock);
|
||||
DeleteCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||
CloseHandle(rwlock->state_.write_semaphore_);
|
||||
}
|
||||
|
||||
|
||||
void uv_rwlock_rdlock(uv_rwlock_t* rwlock) {
|
||||
if (HAVE_SRWLOCK_API())
|
||||
uv__rwlock_srwlock_rdlock(rwlock);
|
||||
else
|
||||
uv__rwlock_fallback_rdlock(rwlock);
|
||||
/* Acquire the lock that protects the reader count. */
|
||||
EnterCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||
|
||||
/* 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) {
|
||||
if (HAVE_SRWLOCK_API())
|
||||
return uv__rwlock_srwlock_tryrdlock(rwlock);
|
||||
else
|
||||
return uv__rwlock_fallback_tryrdlock(rwlock);
|
||||
int err;
|
||||
|
||||
if (!TryEnterCriticalSection(&rwlock->state_.num_readers_lock_))
|
||||
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) {
|
||||
if (HAVE_SRWLOCK_API())
|
||||
uv__rwlock_srwlock_rdunlock(rwlock);
|
||||
else
|
||||
uv__rwlock_fallback_rdunlock(rwlock);
|
||||
EnterCriticalSection(&rwlock->state_.num_readers_lock_);
|
||||
|
||||
if (--rwlock->state_.num_readers_ == 0) {
|
||||
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) {
|
||||
if (HAVE_SRWLOCK_API())
|
||||
uv__rwlock_srwlock_wrlock(rwlock);
|
||||
else
|
||||
uv__rwlock_fallback_wrlock(rwlock);
|
||||
DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, INFINITE);
|
||||
if (r != WAIT_OBJECT_0)
|
||||
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
||||
}
|
||||
|
||||
|
||||
int uv_rwlock_trywrlock(uv_rwlock_t* rwlock) {
|
||||
if (HAVE_SRWLOCK_API())
|
||||
return uv__rwlock_srwlock_trywrlock(rwlock);
|
||||
DWORD r = WaitForSingleObject(rwlock->state_.write_semaphore_, 0);
|
||||
if (r == WAIT_OBJECT_0)
|
||||
return 0;
|
||||
else if (r == WAIT_TIMEOUT)
|
||||
return UV_EBUSY;
|
||||
else
|
||||
return uv__rwlock_fallback_trywrlock(rwlock);
|
||||
uv_fatal_error(GetLastError(), "WaitForSingleObject");
|
||||
}
|
||||
|
||||
|
||||
void uv_rwlock_wrunlock(uv_rwlock_t* rwlock) {
|
||||
if (HAVE_SRWLOCK_API())
|
||||
uv__rwlock_srwlock_wrunlock(rwlock);
|
||||
else
|
||||
uv__rwlock_fallback_wrunlock(rwlock);
|
||||
if (!ReleaseSemaphore(rwlock->state_.write_semaphore_, 1, NULL))
|
||||
uv_fatal_error(GetLastError(), "ReleaseSemaphore");
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
* (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
|
||||
|
28
deps/uv/src/win/winapi.c
vendored
28
deps/uv/src/win/winapi.c
vendored
@ -40,13 +40,6 @@ sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
||||
sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
||||
sCancelIoEx pCancelIoEx;
|
||||
sInitializeSRWLock pInitializeSRWLock;
|
||||
sAcquireSRWLockShared pAcquireSRWLockShared;
|
||||
sAcquireSRWLockExclusive pAcquireSRWLockExclusive;
|
||||
sTryAcquireSRWLockShared pTryAcquireSRWLockShared;
|
||||
sTryAcquireSRWLockExclusive pTryAcquireSRWLockExclusive;
|
||||
sReleaseSRWLockShared pReleaseSRWLockShared;
|
||||
sReleaseSRWLockExclusive pReleaseSRWLockExclusive;
|
||||
sInitializeConditionVariable pInitializeConditionVariable;
|
||||
sSleepConditionVariableCS pSleepConditionVariableCS;
|
||||
sSleepConditionVariableSRW pSleepConditionVariableSRW;
|
||||
@ -129,27 +122,6 @@ void uv_winapi_init() {
|
||||
pCancelIoEx = (sCancelIoEx)
|
||||
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)
|
||||
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,
|
||||
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)
|
||||
(PCONDITION_VARIABLE ConditionVariable);
|
||||
|
||||
@ -4714,13 +4693,6 @@ extern sGetQueuedCompletionStatusEx pGetQueuedCompletionStatusEx;
|
||||
extern sSetFileCompletionNotificationModes pSetFileCompletionNotificationModes;
|
||||
extern sCreateSymbolicLinkW pCreateSymbolicLinkW;
|
||||
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 sSleepConditionVariableCS pSleepConditionVariableCS;
|
||||
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_mutex)
|
||||
TEST_DECLARE (thread_rwlock)
|
||||
TEST_DECLARE (thread_rwlock_trylock)
|
||||
TEST_DECLARE (thread_create)
|
||||
TEST_DECLARE (thread_equal)
|
||||
TEST_DECLARE (dlerror)
|
||||
@ -707,6 +708,7 @@ TASK_LIST_START
|
||||
TEST_ENTRY (thread_local_storage)
|
||||
TEST_ENTRY (thread_mutex)
|
||||
TEST_ENTRY (thread_rwlock)
|
||||
TEST_ENTRY (thread_rwlock_trylock)
|
||||
TEST_ENTRY (thread_create)
|
||||
TEST_ENTRY (thread_equal)
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
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