libuv-svace-build
182 строки · 4.6 Кб
1/* Copyright Joyent, Inc. and other Node contributors. All rights reserved.
2*
3* Permission is hereby granted, free of charge, to any person obtaining a copy
4* of this software and associated documentation files (the "Software"), to
5* deal in the Software without restriction, including without limitation the
6* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7* sell copies of the Software, and to permit persons to whom the Software is
8* furnished to do so, subject to the following conditions:
9*
10* The above copyright notice and this permission notice shall be included in
11* all copies or substantial portions of the Software.
12*
13* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19* IN THE SOFTWARE.
20*/
21
22#include "uv.h"23#include "task.h"24
25#include <stdio.h>26#include <stdlib.h>27
28static uv_cond_t condvar;29static uv_mutex_t mutex;30static uv_rwlock_t rwlock;31static int step;32
33/* The mutex and rwlock tests are really poor.
34* They're very basic sanity checks and nothing more.
35* Apologies if that rhymes.
36*/
37
38TEST_IMPL(thread_mutex) {39uv_mutex_t mutex;40int r;41
42r = uv_mutex_init(&mutex);43ASSERT_OK(r);44
45uv_mutex_lock(&mutex);46uv_mutex_unlock(&mutex);47uv_mutex_destroy(&mutex);48
49return 0;50}
51
52
53TEST_IMPL(thread_mutex_recursive) {54uv_mutex_t mutex;55int r;56
57r = uv_mutex_init_recursive(&mutex);58ASSERT_OK(r);59
60uv_mutex_lock(&mutex);61uv_mutex_lock(&mutex);62ASSERT_OK(uv_mutex_trylock(&mutex));63
64uv_mutex_unlock(&mutex);65uv_mutex_unlock(&mutex);66uv_mutex_unlock(&mutex);67uv_mutex_destroy(&mutex);68
69return 0;70}
71
72
73TEST_IMPL(thread_rwlock) {74uv_rwlock_t rwlock;75int r;76
77r = uv_rwlock_init(&rwlock);78ASSERT_OK(r);79
80uv_rwlock_rdlock(&rwlock);81uv_rwlock_rdunlock(&rwlock);82uv_rwlock_wrlock(&rwlock);83uv_rwlock_wrunlock(&rwlock);84uv_rwlock_destroy(&rwlock);85
86return 0;87}
88
89
90/* Call when holding |mutex|. */
91static void synchronize_nowait(void) {92step += 1;93uv_cond_signal(&condvar);94}
95
96
97/* Call when holding |mutex|. */
98static void synchronize(void) {99int current;100
101synchronize_nowait();102/* Wait for the other thread. Guard against spurious wakeups. */103for (current = step; current == step; uv_cond_wait(&condvar, &mutex));104ASSERT_EQ(step, current + 1);105}
106
107
108static void thread_rwlock_trylock_peer(void* unused) {109(void) &unused;110
111uv_mutex_lock(&mutex);112
113/* Write lock held by other thread. */114ASSERT_EQ(UV_EBUSY, uv_rwlock_tryrdlock(&rwlock));115ASSERT_EQ(UV_EBUSY, uv_rwlock_trywrlock(&rwlock));116synchronize();117
118/* Read lock held by other thread. */119ASSERT_OK(uv_rwlock_tryrdlock(&rwlock));120uv_rwlock_rdunlock(&rwlock);121ASSERT_EQ(UV_EBUSY, uv_rwlock_trywrlock(&rwlock));122synchronize();123
124/* Acquire write lock. */125ASSERT_OK(uv_rwlock_trywrlock(&rwlock));126synchronize();127
128/* Release write lock and acquire read lock. */129uv_rwlock_wrunlock(&rwlock);130ASSERT_OK(uv_rwlock_tryrdlock(&rwlock));131synchronize();132
133uv_rwlock_rdunlock(&rwlock);134synchronize_nowait(); /* Signal main thread we're going away. */135uv_mutex_unlock(&mutex);136}
137
138
139TEST_IMPL(thread_rwlock_trylock) {140uv_thread_t thread;141
142ASSERT_OK(uv_cond_init(&condvar));143ASSERT_OK(uv_mutex_init(&mutex));144ASSERT_OK(uv_rwlock_init(&rwlock));145
146uv_mutex_lock(&mutex);147ASSERT_OK(uv_thread_create(&thread, thread_rwlock_trylock_peer, NULL));148
149/* Hold write lock. */150ASSERT_OK(uv_rwlock_trywrlock(&rwlock));151synchronize(); /* Releases the mutex to the other thread. */152
153/* Release write lock and acquire read lock. Pthreads doesn't support154* the notion of upgrading or downgrading rwlocks, so neither do we.
155*/
156uv_rwlock_wrunlock(&rwlock);157ASSERT_OK(uv_rwlock_tryrdlock(&rwlock));158synchronize();159
160/* Release read lock. */161uv_rwlock_rdunlock(&rwlock);162synchronize();163
164/* Write lock held by other thread. */165ASSERT_EQ(UV_EBUSY, uv_rwlock_tryrdlock(&rwlock));166ASSERT_EQ(UV_EBUSY, uv_rwlock_trywrlock(&rwlock));167synchronize();168
169/* Read lock held by other thread. */170ASSERT_OK(uv_rwlock_tryrdlock(&rwlock));171uv_rwlock_rdunlock(&rwlock);172ASSERT_EQ(UV_EBUSY, uv_rwlock_trywrlock(&rwlock));173synchronize();174
175ASSERT_OK(uv_thread_join(&thread));176uv_rwlock_destroy(&rwlock);177uv_mutex_unlock(&mutex);178uv_mutex_destroy(&mutex);179uv_cond_destroy(&condvar);180
181return 0;182}
183