Browse Source

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>
v4.x
Saúl Ibarra Corretgé 9 years ago
committed by Rod Vagg
parent
commit
4c5940776c
  1. 1
      deps/uv/AUTHORS
  2. 21
      deps/uv/ChangeLog
  3. 1
      deps/uv/Makefile.am
  4. 2
      deps/uv/appveyor.yml
  5. 2
      deps/uv/configure.ac
  6. 2
      deps/uv/include/uv-version.h
  7. 26
      deps/uv/include/uv-win.h
  8. 12
      deps/uv/src/unix/atomic-ops.h
  9. 6
      deps/uv/src/unix/darwin.c
  10. 30
      deps/uv/src/unix/thread.c
  11. 280
      deps/uv/src/win/thread.c
  12. 28
      deps/uv/src/win/winapi.c
  13. 28
      deps/uv/src/win/winapi.h
  14. 2
      deps/uv/test/test-list.h
  15. 59
      deps/uv/test/test-mutexes.c

1
deps/uv/AUTHORS

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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

@ -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…
Cancel
Save