blob: 6f062a7d2d11e6e0227272816a7fb43bb946fa10 [file] [log] [blame]
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include "celix_uv_cleanup.h"
#include <atomic>
#include <gtest/gtest.h>
class UvThreadsTestSuite : public ::testing::Test {
};
static void uvThreadTryLockForMutex(void* data) {
auto* mutex = static_cast<uv_mutex_t*>(data);
EXPECT_NE(0, uv_mutex_trylock(mutex));
}
TEST_F(UvThreadsTestSuite, MutexGuardTest) {
uv_mutex_t mutex;
ASSERT_EQ(0, uv_mutex_init(&mutex));
celix_autoptr(uv_mutex_t) mutexCleanup = &mutex;
{
celix_auto(celix_uv_mutex_lock_guard_t) guard = celix_uvMutexLockGuard_init(&mutex);
uv_thread_t thread;
ASSERT_EQ(0, uv_thread_create(&thread, uvThreadTryLockForMutex, &mutex));
EXPECT_EQ(0, uv_thread_join(&thread));
} //guard out of scope -> unlock
ASSERT_EQ(0, uv_mutex_trylock(&mutex));
uv_mutex_unlock(&mutex);
}
TEST_F(UvThreadsTestSuite, MutexStealTest) {
uv_mutex_t mutex;
ASSERT_EQ(0, uv_mutex_init(&mutex));
celix_autoptr(uv_mutex_t) mutexCleanup = &mutex;
celix_steal_ptr(mutexCleanup);
uv_mutex_destroy(&mutex);
}
static void uvThreadTryLocksForWriteLock(void* data) {
auto* lock = static_cast<uv_rwlock_t*>(data);
EXPECT_NE(0, uv_rwlock_tryrdlock(lock));
EXPECT_NE(0, uv_rwlock_trywrlock(lock));
}
static void uvThreadTryLocksForReadLock(void* data) {
auto* lock = static_cast<uv_rwlock_t*>(data);
EXPECT_NE(0, uv_rwlock_trywrlock(lock));
EXPECT_EQ(0, uv_rwlock_tryrdlock(lock)); //additional read lock on read lock should succeed
uv_rwlock_rdunlock(lock);
}
TEST_F(UvThreadsTestSuite, RwlockGuardTest) {
uv_rwlock_t lock;
ASSERT_EQ(0, uv_rwlock_init(&lock));
celix_autoptr(uv_rwlock_t) lockCleanup = &lock;
{
celix_auto(celix_uv_write_lock_guard_t) writeGuard = celix_uvWriteLockGuard_init(&lock);
uv_thread_t thread;
ASSERT_EQ(0, uv_thread_create(&thread, uvThreadTryLocksForWriteLock, &lock));
EXPECT_EQ(0, uv_thread_join(&thread));
} //guard out of scope -> unlock write lock
{
celix_auto(celix_uv_read_lock_guard_t) readGuard = celix_uvReadLockGuard_init(&lock);
uv_thread_t thread;
ASSERT_EQ(0, uv_thread_create(&thread, uvThreadTryLocksForReadLock, &lock));
EXPECT_EQ(0, uv_thread_join(&thread));
} //guard out of scope -> unlock read lock
ASSERT_EQ(0, uv_rwlock_trywrlock(&lock));
uv_rwlock_wrunlock(&lock);
}
TEST_F(UvThreadsTestSuite, RwlockStealdTest) {
uv_rwlock_t lock;
ASSERT_EQ(0, uv_rwlock_init(&lock));
celix_autoptr(uv_rwlock_t) lockCleanup = &lock;
celix_steal_ptr(lockCleanup);
uv_rwlock_destroy(&lock);
}
TEST_F(UvThreadsTestSuite, ConditionAutoCleanupTest) {
uv_cond_t cond;
ASSERT_EQ(0, uv_cond_init(&cond));
celix_autoptr(uv_cond_t) condCleanup = &cond;
}
TEST_F(UvThreadsTestSuite, ConditionStealTest) {
uv_cond_t cond;
ASSERT_EQ(0, uv_cond_init(&cond));
celix_autoptr(uv_cond_t) condCleanup = &cond;
celix_steal_ptr(condCleanup);
uv_cond_destroy(&cond);
}
TEST_F(UvThreadsTestSuite, LocalThreadStorageKeyAutoCleanupTest) {
uv_key_t key;
ASSERT_EQ(0, uv_key_create(&key));
celix_autoptr(uv_key_t) keyCleanup = &key;
}
TEST_F(UvThreadsTestSuite, LocalThreadStorageKeyStealTest) {
uv_key_t key;
ASSERT_EQ(0, uv_key_create(&key));
celix_autoptr(uv_key_t) keyCleanup = &key;
celix_steal_ptr(keyCleanup);
uv_key_delete(&key);
}