mirror of
https://github.com/espressif/esp-idf.git
synced 2026-05-05 04:15:21 +02:00
pthread: added pthread_rwlock_tryrd/wrlock()
Closes https://github.com/espressif/esp-idf/issues/9229
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2021-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -191,6 +191,34 @@ int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock)
|
||||
{
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
int res;
|
||||
|
||||
res = checkrw_lock(rwlock);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_rwlock = (esp_pthread_rwlock_t *)*rwlock;
|
||||
res = pthread_mutex_trylock(&esp_rwlock->resource_mutex);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (esp_rwlock->active_writers == 0) {
|
||||
esp_rwlock->active_readers++;
|
||||
res = 0;
|
||||
} else {
|
||||
res = EBUSY;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&esp_rwlock->resource_mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
|
||||
{
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
@@ -219,6 +247,35 @@ int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock) {
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
int res;
|
||||
|
||||
res = checkrw_lock(rwlock);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
esp_rwlock = (esp_pthread_rwlock_t *)*rwlock;
|
||||
res = pthread_mutex_trylock(&esp_rwlock->resource_mutex);
|
||||
if (res != 0) {
|
||||
return res;
|
||||
}
|
||||
|
||||
if (esp_rwlock->active_readers > 0 ||
|
||||
esp_rwlock->active_writers > 0 ||
|
||||
esp_rwlock->waiting_writers > 0) { // the last check for waiting_writers is to avoid skipping the queue
|
||||
res = EBUSY;
|
||||
} else {
|
||||
esp_rwlock->active_writers++;
|
||||
res = 0;
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&esp_rwlock->resource_mutex);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int pthread_rwlock_unlock (pthread_rwlock_t *rwlock)
|
||||
{
|
||||
esp_pthread_rwlock_t *esp_rwlock;
|
||||
|
||||
@@ -293,3 +293,89 @@ TEST_CASE("wrlock multiple writers wait", "[pthread][rwlock]")
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
vQueueDelete(wait_queue);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock invalid param", "[pthread][rwlock]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(NULL), EINVAL);
|
||||
|
||||
pthread_rwlock_t rwlock = 0;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), EINVAL);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock fails on write-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_wrlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), EBUSY);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock succeeds on read-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_rdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("tryrdlock lock statically initialized lock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_tryrdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock invalid param", "[pthread][rwlock]")
|
||||
{
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(NULL), EINVAL);
|
||||
|
||||
pthread_rwlock_t rwlock = 0;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), EINVAL);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock fails on write-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_wrlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), EBUSY);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock fails on read-locked rwlock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock;
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_init(&rwlock, NULL), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_rdlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), EBUSY);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
TEST_CASE("trywrlock lock statically initialized lock", "[pthread][rwlock]")
|
||||
{
|
||||
pthread_rwlock_t rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_trywrlock(&rwlock), 0);
|
||||
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_unlock(&rwlock), 0);
|
||||
TEST_ASSERT_EQUAL_INT(pthread_rwlock_destroy(&rwlock), 0);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user