diff --git a/components/pthreads/pthread.h b/components/pthreads/pthread.h index fa562192248163a02bd305e6e76efd4ac5089eac..6a87c026f67ff50afb61914b0ad250836477c132 100644 --- a/components/pthreads/pthread.h +++ b/components/pthreads/pthread.h @@ -104,9 +104,9 @@ struct pthread_rwlock pthread_cond_t rw_condreaders; /* for reader threads waiting */ pthread_cond_t rw_condwriters; /* for writer threads waiting */ - int rw_nwaitreaders; /* the number waiting */ - int rw_nwaitwriters; /* the number waiting */ - int rw_refcount; + int rw_nwaitreaders; /* the number of reader threads waiting */ + int rw_nwaitwriters; /* the number of writer threads waiting */ + int rw_refcount; /* 0: unlocked, -1: locked by writer, > 0 locked by n readers */ }; typedef struct pthread_rwlock pthread_rwlock_t; diff --git a/components/pthreads/pthread_rwlock.c b/components/pthreads/pthread_rwlock.c index 3db0ecc662b3af21c6ea43758a6f829675ec02e6..b694cb09ff51049cb8de47b3f066d02d34a584e6 100644 --- a/components/pthreads/pthread_rwlock.c +++ b/components/pthreads/pthread_rwlock.c @@ -112,9 +112,11 @@ int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock) while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0) { rwlock->rw_nwaitreaders++; + /* rw_mutex will be released when waiting for rw_condreaders */ result = pthread_cond_wait(&rwlock->rw_condreaders, &rwlock->rw_mutex); + /* rw_mutex should have been taken again when returned from waiting */ rwlock->rw_nwaitreaders--; - if (result != 0) + if (result != 0) /* wait error */ break; } @@ -160,7 +162,9 @@ int pthread_rwlock_timedrdlock (pthread_rwlock_t * rwlock, const struct timespec while (rwlock->rw_refcount < 0 || rwlock->rw_nwaitwriters > 0) { rwlock->rw_nwaitreaders++; + /* rw_mutex will be released when waiting for rw_condreaders */ result = pthread_cond_timedwait(&rwlock->rw_condreaders, &rwlock->rw_mutex, abstime); + /* rw_mutex should have been taken again when returned from waiting */ rwlock->rw_nwaitreaders--; if (result != 0) break; @@ -187,7 +191,9 @@ int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock, const struct timespec while (rwlock->rw_refcount != 0) { rwlock->rw_nwaitwriters++; + /* rw_mutex will be released when waiting for rw_condwriters */ result = pthread_cond_timedwait(&rwlock->rw_condwriters, &rwlock->rw_mutex, abstime); + /* rw_mutex should have been taken again when returned from waiting */ rwlock->rw_nwaitwriters--; if (result != 0) break; @@ -233,7 +239,7 @@ int pthread_rwlock_unlock (pthread_rwlock_t *rwlock) if (rwlock->rw_refcount > 0) rwlock->rw_refcount--; /* releasing a reader */ else if (rwlock->rw_refcount == -1) - rwlock->rw_refcount = 0; /* releasing a reader */ + rwlock->rw_refcount = 0; /* releasing a writer */ /* give preference to waiting writers over waiting readers */ if (rwlock->rw_nwaitwriters > 0) @@ -264,7 +270,9 @@ int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock) while (rwlock->rw_refcount != 0) { rwlock->rw_nwaitwriters++; + /* rw_mutex will be released when waiting for rw_condwriters */ result = pthread_cond_wait(&rwlock->rw_condwriters, &rwlock->rw_mutex); + /* rw_mutex should have been taken again when returned from waiting */ rwlock->rw_nwaitwriters--; if (result != 0) break;