pthread rwlock bugfixes

This commit is contained in:
Mark Schulte 2017-04-07 15:45:24 -06:00 committed by Gregory Nutt
parent b631dc886f
commit 2b1ca79b4b
4 changed files with 28 additions and 11 deletions

View File

@ -343,6 +343,7 @@ struct pthread_rwlock_s
pthread_cond_t cv;
unsigned int num_readers;
unsigned int num_writers;
bool write_in_progress;
};
typedef struct pthread_rwlock_s pthread_rwlock_t;

View File

@ -60,8 +60,9 @@ int pthread_rwlock_init(FAR pthread_rwlock_t *lock,
return -ENOSYS;
}
lock->num_readers = 0;
lock->num_writers = 0;
lock->num_readers = 0;
lock->num_writers = 0;
lock->write_in_progress = false;
err = pthread_cond_init(&lock->cv, NULL);
if (err != 0)
@ -111,9 +112,9 @@ int pthread_rwlock_unlock(FAR pthread_rwlock_t *rw_lock)
err = pthread_cond_broadcast(&rw_lock->cv);
}
}
else if (rw_lock->num_writers > 0)
else if (rw_lock->write_in_progress)
{
rw_lock->num_writers--;
rw_lock->write_in_progress = false;
err = pthread_cond_broadcast(&rw_lock->cv);
}

View File

@ -54,7 +54,7 @@ static int tryrdlock(FAR pthread_rwlock_t *rw_lock)
{
int err;
if (rw_lock->num_writers > 0)
if (rw_lock->num_writers > 0 || rw_lock->write_in_progress)
{
err = EBUSY;
}

View File

@ -75,13 +75,13 @@ int pthread_rwlock_trywrlock(FAR pthread_rwlock_t *rw_lock)
return err;
}
if (rw_lock->num_readers > 0 || rw_lock->num_writers > 0)
if (rw_lock->num_readers > 0 || rw_lock->write_in_progress)
{
err = EBUSY;
}
else
{
rw_lock->num_writers++;
rw_lock->write_in_progress = true;
}
pthread_mutex_unlock(&rw_lock->lock);
@ -92,20 +92,21 @@ int pthread_rwlock_timedwrlock(FAR pthread_rwlock_t *rw_lock,
FAR const struct timespec *ts)
{
int err = pthread_mutex_lock(&rw_lock->lock);
int num_writers_current;
if (err != 0)
{
return err;
}
num_writers_current = rw_lock->num_writers++;
if (num_writers_current == 0)
if (rw_lock->num_writers == UINT_MAX)
{
err = EAGAIN;
goto exit_with_mutex;
}
while (rw_lock->num_writers != num_writers_current)
rw_lock->num_writers++;
while (rw_lock->write_in_progress || rw_lock->num_readers > 0)
{
if (ts != NULL)
{
@ -122,6 +123,20 @@ int pthread_rwlock_timedwrlock(FAR pthread_rwlock_t *rw_lock,
}
}
if (err == 0)
{
rw_lock->write_in_progress = true;
}
else
{
/* In case of error, notify any blocked readers. */
(void) pthread_cond_broadcast(&rw_lock->cv);
}
rw_lock->num_writers--;
exit_with_mutex:
pthread_mutex_unlock(&rw_lock->lock);
return err;