pthread: support pthread_once

Issue #1296
This commit is contained in:
Alexander Boettcher 2014-10-14 17:09:54 +02:00 committed by Christian Helmuth
parent e6850359e1
commit cdcc4ee60f
1 changed files with 46 additions and 0 deletions

View File

@ -598,4 +598,50 @@ extern "C" {
return 0;
}
int pthread_once(pthread_once_t *once, void (*init_once)(void))
{
if (!once || ((once->state != PTHREAD_NEEDS_INIT) &&
(once->state != PTHREAD_DONE_INIT)))
return EINTR;
if (!once->mutex) {
pthread_mutex_t p = new (env()->heap()) pthread_mutex(0);
/* be paranoid */
if (!p)
return EINTR;
static Lock lock;
lock.lock();
if (!once->mutex) {
once->mutex = p;
p = nullptr;
}
lock.unlock();
/*
* If another thread concurrently allocated a mutex and was faster,
* free our mutex since it is not used.
*/
if (p)
destroy(env()->heap(), p);
}
once->mutex->lock();
if (once->state == PTHREAD_DONE_INIT) {
once->mutex->unlock();
return 0;
}
init_once();
once->state = PTHREAD_DONE_INIT;
once->mutex->unlock();
return 0;
}
}