* roottypes.cs: Rename from tree.cs.
[mono.git] / mono / io-layer / mono-mutex.c
index 604afbe7103627fd829aa41b16e6a66d57c5b9d6..a1ea18fdbdce5c14437656ff9187d9ded59dac48 100644 (file)
@@ -35,6 +35,9 @@
 
 
 #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)
 {
@@ -65,13 +68,22 @@ pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *timeout)
 int
 mono_once (mono_once_t *once, void (*once_init) (void))
 {
+       int thr_ret;
+       
        if (!once->complete) {
-               pthread_mutex_lock (&once->mutex);
+               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;
                }
-               pthread_mutex_unlock (&once->mutex);
+               thr_ret = pthread_mutex_unlock (&once->mutex);
+               g_assert (thr_ret == 0);
+               
+               pthread_cleanup_pop (0);
        }
        
        return 0;
@@ -153,20 +165,24 @@ mono_mutexattr_destroy (mono_mutexattr_t *attr)
 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
@@ -183,16 +199,16 @@ mono_mutex_lock (mono_mutex_t *mutex)
                        return EINVAL;
                
                while (1) {
-                       if (mutex->owner == MONO_THREAD_NONE) {
+                       if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
                                mutex->owner = id;
                                mutex->depth = 1;
                                break;
-                       } else if (mutex->owner == id) {
+                       } else if (pthread_equal (mutex->owner, id)) {
                                mutex->depth++;
                                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--;
                        }
@@ -218,13 +234,14 @@ mono_mutex_trylock (mono_mutex_t *mutex)
                if (pthread_mutex_lock (&mutex->mutex) != 0)
                        return EINVAL;
                
-               if (mutex->owner != MONO_THREAD_NONE && mutex->owner != id) {
+               if (!pthread_equal (mutex->owner, MONO_THREAD_NONE) &&
+                   !pthread_equal (mutex->owner, id)) {
                        pthread_mutex_unlock (&mutex->mutex);
                        return EBUSY;
                }
                
                while (1) {
-                       if (mutex->owner == MONO_THREAD_NONE) {
+                       if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
                                mutex->owner = id;
                                mutex->depth = 1;
                                break;
@@ -255,11 +272,11 @@ mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout)
                        return ETIMEDOUT;
                
                while (1) {
-                       if (mutex->owner == MONO_THREAD_NONE) {
+                       if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
                                mutex->owner = id;
                                mutex->depth = 1;
                                break;
-                       } else if (mutex->owner == id) {
+                       } else if (pthread_equal (mutex->owner, id)) {
                                mutex->depth++;
                                break;
                        } else {
@@ -279,6 +296,8 @@ mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout)
 int
 mono_mutex_unlock (mono_mutex_t *mutex)
 {
+       int thr_ret;
+       
        switch (mutex->type) {
        case MONO_MUTEX_NORMAL:
                return pthread_mutex_unlock (&mutex->mutex);
@@ -286,13 +305,19 @@ mono_mutex_unlock (mono_mutex_t *mutex)
                if (pthread_mutex_lock (&mutex->mutex) != 0)
                        return EINVAL;
                
-               assert (mutex->owner == pthread_self ());
+               if (pthread_equal (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);
@@ -305,6 +330,7 @@ int
 mono_mutex_destroy (mono_mutex_t *mutex)
 {
        int ret = 0;
+       int thr_ret;
        
        switch (mutex->type) {
        case MONO_MUTEX_NORMAL:
@@ -312,7 +338,8 @@ mono_mutex_destroy (mono_mutex_t *mutex)
                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);
                }
        }