diff --git a/src/threadwrapper/include/pthread.h b/src/threadwrapper/include/pthread.h index eeef31d5..a6a04d8e 100644 --- a/src/threadwrapper/include/pthread.h +++ b/src/threadwrapper/include/pthread.h @@ -23,12 +23,14 @@ extern "C" { typedef void* pthread_cond_t; typedef void* pthread_cond_t; typedef void* pthread_mutex_t; +typedef void* pthread_rwlock_t; typedef void* pthread_t; typedef void*(voidp_voidp_func)(void*); typedef void pthread_attr_t; typedef void pthread_condattr_t; typedef void pthread_mutexattr_t; +typedef void pthread_rwlockattr_t; // Parameter names that have been commented away do nothing, // as they are always null when the functions are used in Kvazaar. @@ -48,6 +50,12 @@ int pthread_mutex_init(pthread_mutex_t* mutex, const pthread_mutexattr_t* /*attr int pthread_mutex_lock(pthread_mutex_t* mutex); int pthread_mutex_unlock(pthread_mutex_t* mutex); +int pthread_rwlock_init(pthread_rwlock_t* lock, const pthread_rwlockattr_t * /*attr*/); +int pthread_rwlock_destroy(pthread_rwlock_t *rwlock); +int pthread_rwlock_rdlock(pthread_rwlock_t *rwlock); +int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock); +int pthread_rwlock_unlock(pthread_rwlock_t *rwlock); + #ifdef __cplusplus } #endif diff --git a/src/threadwrapper/src/pthread.cpp b/src/threadwrapper/src/pthread.cpp index 7e094b9e..56e92f3d 100644 --- a/src/threadwrapper/src/pthread.cpp +++ b/src/threadwrapper/src/pthread.cpp @@ -17,8 +17,13 @@ OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. #include "pthread.h" #include #include +#include #include +typedef struct { + std::shared_mutex *lock; + bool write_lock; +} rw_lock_internal; int pthread_cond_broadcast(pthread_cond_t* cond) { static_cast(*cond)->notify_all(); @@ -86,3 +91,43 @@ int pthread_mutex_unlock(pthread_mutex_t* mutex) { static_cast(*mutex)->unlock(); return 0; } + +int pthread_rwlock_init(pthread_rwlock_t * lock, const pthread_rwlockattr_t *) +{ + *lock = new rw_lock_internal; + static_cast(*lock)->lock = new std::shared_mutex; + static_cast(*lock)->write_lock = false; + return 0; +} + +int pthread_rwlock_destroy(pthread_rwlock_t* rwlock) +{ + delete static_cast(*rwlock)->lock; + delete static_cast(*rwlock); + return 0; +} + +int pthread_rwlock_rdlock(pthread_rwlock_t* rwlock) +{ + static_cast(*rwlock)->lock->lock_shared(); + return 0; +} + +int pthread_rwlock_wrlock(pthread_rwlock_t* rwlock) +{ + static_cast(*rwlock)->lock->lock(); + static_cast(*rwlock)->write_lock = true; + return 0; +} + +int pthread_rwlock_unlock(pthread_rwlock_t* rwlock) +{ + if (static_cast(*rwlock)->write_lock) { + static_cast(*rwlock)->write_lock = false; + static_cast(*rwlock)->lock->unlock(); + } + else { + static_cast(*rwlock)->lock->unlock_shared(); + } + return 0; +}