Add mono_register_symfile_for_assembly() for bundles.
[mono.git] / mono / io-layer / mono-mutex.c
index 17a958cbe1b2ef0fe4b646c1bfacf2668323fb0c..f5152c2f29d5159cb294208ef16ed114f3da6608 100644 (file)
@@ -1,23 +1,10 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
 /*
- *  Authors: Jeffrey Stedfast <fejj@ximian.com>
+ * mono-mutex.h: Portability wrappers around POSIX Mutexes
  *
- *  Copyright 2002 Ximain, Inc. (www.ximian.com)
- *
- *  This program is free software; you can redistribute it and/or modify
- *  it under the terms of the GNU General Public License as published by
- *  the Free Software Foundation; either version 2 of the License, or
- *  (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU General Public License for more details.
- *
- *  You should have received a copy of the GNU General Public License
- *  along with this program; if not, write to the Free Software
- *  Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
  *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
  */
 
 
 
 
 #ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
-int pthread_mutex_timedlock (pthread_mutex_t *mutex,
-                           const struct timespec *timeout);
+/* Android does not implement pthread_mutex_timedlock(), but does provide an
+ * unusual declaration: http://code.google.com/p/android/issues/detail?id=7807
+ */
+#ifdef PLATFORM_ANDROID
+#define CONST_NEEDED
+#else
+#define CONST_NEEDED const
+#endif
 
+int pthread_mutex_timedlock (pthread_mutex_t *mutex,
+                           CONST_NEEDED struct timespec *timeout);
 int
-pthread_mutex_timedlock (pthread_mutex_t *mutex, const struct timespec *timeout)
+pthread_mutex_timedlock (pthread_mutex_t *mutex, CONST_NEEDED struct timespec *timeout)
 {
        struct timeval timenow;
        struct timespec sleepytime;
@@ -68,13 +63,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;
@@ -156,20 +160,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
@@ -186,16 +194,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--;
                        }
@@ -221,13 +229,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;
@@ -258,11 +267,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 {
@@ -282,6 +291,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);
@@ -289,13 +300,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);
@@ -308,6 +325,7 @@ int
 mono_mutex_destroy (mono_mutex_t *mutex)
 {
        int ret = 0;
+       int thr_ret;
        
        switch (mutex->type) {
        case MONO_MUTEX_NORMAL:
@@ -315,7 +333,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);
                }
        }