pthread: initialize static rwlocks/conds

Make sure that the rwlock is allocated before a lock operation is
performed. This case occurs if a static rwlock was create by using
PTHREAD_RWLOCK_INITIALIZER. Same goes for PTHREAD_CONDS_INITIALIZER.

Fixes #3262.
This commit is contained in:
Josef Söntgen 2018-11-13 13:33:45 +01:00 committed by Christian Helmuth
parent 3c8714ed5a
commit 38a10c92d3
2 changed files with 48 additions and 7 deletions

View File

@ -91,10 +91,23 @@ extern "C" {
{
};
static int rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
static Genode::Lock rwlock_init_lock { };
if (!rwlock)
return EINVAL;
try {
Genode::Lock::Guard g(rwlock_init_lock);
*rwlock = new struct pthread_rwlock();
return 0;
} catch (...) { return ENOMEM; }
}
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
{
*rwlock = new struct pthread_rwlock();
return 0;
return rwlock_init(rwlock, attr);
}
int pthread_rwlock_destroy(pthread_rwlock_t *rwlock)
@ -105,12 +118,26 @@ extern "C" {
int pthread_rwlock_rdlock(pthread_rwlock_t * rwlock)
{
if (!rwlock)
return EINVAL;
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
if (rwlock_init(rwlock, NULL))
return ENOMEM;
(*rwlock)->rdlock();
return 0;
}
int pthread_rwlock_wrlock(pthread_rwlock_t *rwlock)
{
if (!rwlock)
return EINVAL;
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
if (rwlock_init(rwlock, NULL))
return ENOMEM;
(*rwlock)->wrlock();
return 0;
}

View File

@ -639,15 +639,26 @@ extern "C" {
}
int pthread_cond_init(pthread_cond_t *__restrict cond,
const pthread_condattr_t *__restrict attr)
static int cond_init(pthread_cond_t *__restrict cond,
const pthread_condattr_t *__restrict attr)
{
static Genode::Lock cond_init_lock { };
if (!cond)
return EINVAL;
*cond = new pthread_cond;
try {
Genode::Lock::Guard g(cond_init_lock);
*cond = new pthread_cond;
return 0;
} catch (...) { return ENOMEM; }
}
return 0;
int pthread_cond_init(pthread_cond_t *__restrict cond,
const pthread_condattr_t *__restrict attr)
{
return cond_init(cond, attr);
}
@ -710,9 +721,12 @@ extern "C" {
{
int result = 0;
if (!cond || !*cond)
if (!cond)
return EINVAL;
if (*cond == PTHREAD_COND_INITIALIZER)
cond_init(cond, NULL);
pthread_cond *c = *cond;
c->counter_lock.lock();