mirror of
https://github.com/genodelabs/genode.git
synced 2024-12-18 13:26:27 +00:00
libc: pthread cond/rwlock improvements
- add a check to detect if a different thread has initialized the internal object in the meantime - remove ENOMEM error since the 'Libc::Allocator' is not supposed to throw exceptions - remove init mutex from 'pthread_condattr_init()' since there is no implicit initialization which could happen in parallel like with mutex/cond/rwlock Issue #5386
This commit is contained in:
parent
37842757ac
commit
35a679d861
@ -1086,6 +1086,15 @@ extern "C" {
|
|||||||
sem_t signal_sem;
|
sem_t signal_sem;
|
||||||
sem_t handshake_sem;
|
sem_t handshake_sem;
|
||||||
|
|
||||||
|
struct Invalid_timedwait_clock { };
|
||||||
|
|
||||||
|
void _cleanup()
|
||||||
|
{
|
||||||
|
sem_destroy(&handshake_sem);
|
||||||
|
sem_destroy(&signal_sem);
|
||||||
|
pthread_mutex_destroy(&counter_mutex);
|
||||||
|
}
|
||||||
|
|
||||||
pthread_cond(clockid_t clock_id) : num_waiters(0), num_signallers(0)
|
pthread_cond(clockid_t clock_id) : num_waiters(0), num_signallers(0)
|
||||||
{
|
{
|
||||||
pthread_mutex_init(&counter_mutex, nullptr);
|
pthread_mutex_init(&counter_mutex, nullptr);
|
||||||
@ -1093,17 +1102,12 @@ extern "C" {
|
|||||||
sem_init(&handshake_sem, 0, 0);
|
sem_init(&handshake_sem, 0, 0);
|
||||||
|
|
||||||
if (sem_set_clock(&signal_sem, clock_id)) {
|
if (sem_set_clock(&signal_sem, clock_id)) {
|
||||||
struct Invalid_timedwait_clock { };
|
_cleanup();
|
||||||
throw Invalid_timedwait_clock();
|
throw Invalid_timedwait_clock();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
~pthread_cond()
|
~pthread_cond() { _cleanup(); }
|
||||||
{
|
|
||||||
sem_destroy(&handshake_sem);
|
|
||||||
sem_destroy(&signal_sem);
|
|
||||||
pthread_mutex_destroy(&counter_mutex);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -1115,17 +1119,11 @@ extern "C" {
|
|||||||
|
|
||||||
int pthread_condattr_init(pthread_condattr_t *attr)
|
int pthread_condattr_init(pthread_condattr_t *attr)
|
||||||
{
|
{
|
||||||
static Mutex condattr_init_mutex { };
|
|
||||||
|
|
||||||
if (!attr)
|
if (!attr)
|
||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
try {
|
Libc::Allocator alloc { };
|
||||||
Mutex::Guard guard(condattr_init_mutex);
|
*attr = new (alloc) pthread_cond_attr;
|
||||||
Libc::Allocator alloc { };
|
|
||||||
*attr = new (alloc) pthread_cond_attr;
|
|
||||||
return 0;
|
|
||||||
} catch (...) { return ENOMEM; }
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -1161,22 +1159,35 @@ extern "C" {
|
|||||||
{
|
{
|
||||||
static Mutex cond_init_mutex { };
|
static Mutex cond_init_mutex { };
|
||||||
|
|
||||||
if (!cond)
|
Mutex::Guard guard(cond_init_mutex);
|
||||||
return EINVAL;
|
|
||||||
|
/*
|
||||||
|
* '*cond' could have been initialized by a different
|
||||||
|
* thread which got the init mutex earlier.
|
||||||
|
*/
|
||||||
|
if (*cond != PTHREAD_COND_INITIALIZER)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Libc::Allocator alloc { };
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Mutex::Guard guard(cond_init_mutex);
|
|
||||||
Libc::Allocator alloc { };
|
|
||||||
*cond = attr && *attr ? new (alloc) pthread_cond((*attr)->clock_id)
|
*cond = attr && *attr ? new (alloc) pthread_cond((*attr)->clock_id)
|
||||||
: new (alloc) pthread_cond(CLOCK_REALTIME);
|
: new (alloc) pthread_cond(CLOCK_REALTIME);
|
||||||
return 0;
|
} catch (pthread_cond::Invalid_timedwait_clock) { return EINVAL; }
|
||||||
} catch (...) { return ENOMEM; }
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pthread_cond_init(pthread_cond_t *__restrict cond,
|
int pthread_cond_init(pthread_cond_t *__restrict cond,
|
||||||
const pthread_condattr_t *__restrict attr)
|
const pthread_condattr_t *__restrict attr)
|
||||||
{
|
{
|
||||||
|
if (!cond)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
/* mark as uninitialized for 'cond_init()' */
|
||||||
|
*cond = PTHREAD_COND_INITIALIZER;
|
||||||
|
|
||||||
return cond_init(cond, attr);
|
return cond_init(cond, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,20 +104,30 @@ extern "C" {
|
|||||||
{
|
{
|
||||||
static Mutex rwlock_init_mutex { };
|
static Mutex rwlock_init_mutex { };
|
||||||
|
|
||||||
if (!rwlock)
|
Mutex::Guard g(rwlock_init_mutex);
|
||||||
return EINVAL;
|
|
||||||
|
|
||||||
try {
|
/*
|
||||||
Mutex::Guard g(rwlock_init_mutex);
|
* '*rwlock' could have been initialized by a different
|
||||||
Libc::Allocator alloc { };
|
* thread which got the init mutex earlier.
|
||||||
*rwlock = new (alloc) struct pthread_rwlock();
|
*/
|
||||||
|
if (*rwlock != PTHREAD_RWLOCK_INITIALIZER)
|
||||||
return 0;
|
return 0;
|
||||||
} catch (...) { return ENOMEM; }
|
|
||||||
|
Libc::Allocator alloc { };
|
||||||
|
*rwlock = new (alloc) struct pthread_rwlock();
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
|
int pthread_rwlock_init(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr)
|
||||||
{
|
{
|
||||||
|
if (!rwlock)
|
||||||
|
return EINVAL;
|
||||||
|
|
||||||
|
/* mark as uninitialized for 'rwlock_init()' */
|
||||||
|
*rwlock = PTHREAD_RWLOCK_INITIALIZER;
|
||||||
|
|
||||||
return rwlock_init(rwlock, attr);
|
return rwlock_init(rwlock, attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,8 +152,7 @@ extern "C" {
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
|
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
|
||||||
if (rwlock_init(rwlock, NULL))
|
rwlock_init(rwlock, NULL);
|
||||||
return ENOMEM;
|
|
||||||
|
|
||||||
(*rwlock)->rdlock();
|
(*rwlock)->rdlock();
|
||||||
return 0;
|
return 0;
|
||||||
@ -159,8 +168,7 @@ extern "C" {
|
|||||||
return EINVAL;
|
return EINVAL;
|
||||||
|
|
||||||
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
|
if (*rwlock == PTHREAD_RWLOCK_INITIALIZER)
|
||||||
if (rwlock_init(rwlock, NULL))
|
rwlock_init(rwlock, NULL);
|
||||||
return ENOMEM;
|
|
||||||
|
|
||||||
(*rwlock)->wrlock();
|
(*rwlock)->wrlock();
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user