#include <string.h>
#include <errno.h>
#include <assert.h>
+#include <sys/time.h>
#include "mono-mutex.h"
#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+int pthread_mutex_timedlock (pthread_mutex_t *mutex,
+ const struct timespec *timeout);
+
int
pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *timeout)
{
/* This is just to avoid a completely busy wait */
sleepytime.tv_sec = 0;
- sleepytime.tv_nsec = 10000; /* 10ms */
+ sleepytime.tv_nsec = 10000000; /* 10ms */
while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
gettimeofday (&timenow, NULL);
#endif /* HAVE_PTHREAD_MUTEX_TIMEDLOCK */
+int
+mono_once (mono_once_t *once, void (*once_init) (void))
+{
+ int thr_ret;
+
+ if (!once->complete) {
+ pthread_cleanup_push ((void(*)(void *))pthread_mutex_unlock,
+ (void *)&once->mutex);
+ thr_ret = pthread_mutex_lock (&once->mutex);
+ g_assert (thr_ret == 0);
+
+ if (!once->complete) {
+ once_init ();
+ once->complete = TRUE;
+ }
+ thr_ret = pthread_mutex_unlock (&once->mutex);
+ g_assert (thr_ret == 0);
+
+ pthread_cleanup_pop (0);
+ }
+
+ return 0;
+}
+
#ifdef USE_MONO_MUTEX
int
mono_mutex_init (mono_mutex_t *mutex, const mono_mutexattr_t *attr)
{
+ int ret;
+ int thr_ret;
+
mutex->waiters = 0;
mutex->depth = 0;
mutex->owner = MONO_THREAD_NONE;
if (!attr || attr->type == MONO_MUTEX_NORMAL) {
mutex->type = MONO_MUTEX_NORMAL;
- pthread_mutex_init (&mutex->mutex, NULL);
+ ret = pthread_mutex_init (&mutex->mutex, NULL);
} else {
mutex->type = MONO_MUTEX_RECURSIVE;
- pthread_mutex_init (&mutex->mutex, NULL);
- pthread_cond_init (&mutex->cond, NULL);
+ ret = pthread_mutex_init (&mutex->mutex, NULL);
+ thr_ret = pthread_cond_init (&mutex->cond, NULL);
+ g_assert (thr_ret == 0);
}
- return 0;
+ return(ret);
}
int
break;
} else {
mutex->waiters++;
- if (pthread_cond_wait (&mutex->cond, &mutex->mutex) == -1)
+ if (pthread_cond_wait (&mutex->cond, &mutex->mutex) != 0)
return EINVAL;
mutex->waiters--;
}
int
mono_mutex_unlock (mono_mutex_t *mutex)
{
+ int thr_ret;
+
switch (mutex->type) {
case MONO_MUTEX_NORMAL:
return pthread_mutex_unlock (&mutex->mutex);
if (pthread_mutex_lock (&mutex->mutex) != 0)
return EINVAL;
- assert (mutex->owner == pthread_self ());
+ if (mutex->owner != pthread_self()) {
+ /* Not owned by this thread */
+ pthread_mutex_unlock (&mutex->mutex);
+ return EPERM;
+ }
mutex->depth--;
if (mutex->depth == 0) {
mutex->owner = MONO_THREAD_NONE;
- if (mutex->waiters > 0)
- pthread_cond_signal (&mutex->cond);
+ if (mutex->waiters > 0) {
+ thr_ret = pthread_cond_signal (&mutex->cond);
+ g_assert (thr_ret == 0);
+ }
}
return pthread_mutex_unlock (&mutex->mutex);
mono_mutex_destroy (mono_mutex_t *mutex)
{
int ret = 0;
+ int thr_ret;
switch (mutex->type) {
case MONO_MUTEX_NORMAL:
break;
case MONO_MUTEX_RECURSIVE:
if ((ret = pthread_mutex_destroy (&mutex->mutex)) == 0) {
- pthread_cond_destroy (&mutex->cond);
+ thr_ret = pthread_cond_destroy (&mutex->cond);
+ g_assert (thr_ret == 0);
}
}