io-portability.h \
macros.h \
messages.h \
- mono-mutex.h \
mutexes.h \
processes.h \
security.h \
mutexes.c \
mutexes.h \
mutex-private.h \
- mono-mutex.c \
- mono-mutex.h \
posix.c \
processes.c \
processes.h \
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/critical-section-private.h>
-#include "mono-mutex.h"
+#include <mono/utils/mono-mutex.h>
/* A critical section is really just like a lightweight mutex. It
* can't be waited for, and doesn't have a handle.
#include <glib.h>
#include <pthread.h>
-#include "mono-mutex.h"
+#include <mono/utils/mono-mutex.h>
G_BEGIN_DECLS
#include <glib.h>
#include <pthread.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
extern struct _WapiHandleOps _wapi_event_ops;
extern struct _WapiHandleOps _wapi_namedevent_ops;
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
-
#include <mono/io-layer/event-private.h>
+#include <mono/utils/mono-mutex.h>
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/shared.h>
#include <mono/io-layer/collection.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/critical-section-private.h>
+#include <mono/utils/mono-mutex.h>
#undef DEBUG_REFS
#if 0
#include <utime.h>
#include <sys/stat.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/error.h>
#include <mono/io-layer/wapi_glob.h>
#include <mono/io-layer/io-portability.h>
#include <mono/utils/mono-io-portability.h>
+
+#include <mono/utils/mono-mutex.h>
+
#undef DEBUG
int _wapi_open (const char *pathname, int flags, mode_t mode)
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * mono-mutex.h: Portability wrappers around POSIX Mutexes
- *
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- */
-
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <assert.h>
-#include <sys/time.h>
-
-#include "mono-mutex.h"
-
-
-#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
-/* 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_NEEDED struct timespec *timeout)
-{
- struct timeval timenow;
- struct timespec sleepytime;
- int retcode;
-
- /* This is just to avoid a completely busy wait */
- sleepytime.tv_sec = 0;
- sleepytime.tv_nsec = 10000000; /* 10ms */
-
- while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
- gettimeofday (&timenow, NULL);
-
- if (timenow.tv_sec >= timeout->tv_sec &&
- (timenow.tv_usec * 1000) >= timeout->tv_nsec) {
- return ETIMEDOUT;
- }
-
- nanosleep (&sleepytime, NULL);
- }
-
- return retcode;
-}
-#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_mutexattr_init (mono_mutexattr_t *attr)
-{
- memset (attr, 0, sizeof (mono_mutexattr_t));
- return 0;
-}
-
-int
-mono_mutexattr_settype (mono_mutexattr_t *attr, int type)
-{
- attr->type = type;
- return 0;
-}
-
-int
-mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type)
-{
- *type = attr->type;
- return 0;
-}
-
-int
-mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared)
-{
- attr->shared = pshared;
- return 0;
-}
-
-int
-mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared)
-{
- *pshared = attr->shared;
- return 0;
-}
-
-int
-mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol)
-{
- attr->protocol = protocol;
- return 0;
-}
-
-int
-mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol)
-{
- *protocol = attr->protocol;
- return 0;
-}
-
-int
-mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling)
-{
- attr->priority = prioceiling;
- return 0;
-}
-
-int
-mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling)
-{
- *prioceiling = attr->priority;
- return 0;
-}
-
-int
-mono_mutexattr_destroy (mono_mutexattr_t *attr)
-{
- return 0;
-}
-
-
-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;
- ret = pthread_mutex_init (&mutex->mutex, NULL);
- } else {
- mutex->type = MONO_MUTEX_RECURSIVE;
- ret = pthread_mutex_init (&mutex->mutex, NULL);
- thr_ret = pthread_cond_init (&mutex->cond, NULL);
- g_assert (thr_ret == 0);
- }
-
- return(ret);
-}
-
-int
-mono_mutex_lock (mono_mutex_t *mutex)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_lock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else if (pthread_equal (mutex->owner, id)) {
- mutex->depth++;
- break;
- } else {
- mutex->waiters++;
- if (pthread_cond_wait (&mutex->cond, &mutex->mutex) != 0)
- return EINVAL;
- mutex->waiters--;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_trylock (mono_mutex_t *mutex)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_trylock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
-
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- if (!pthread_equal (mutex->owner, MONO_THREAD_NONE) &&
- !pthread_equal (mutex->owner, id)) {
- pthread_mutex_unlock (&mutex->mutex);
- return EBUSY;
- }
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else {
- mutex->depth++;
- break;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout)
-{
- pthread_t id;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_timedlock (&mutex->mutex, timeout);
- case MONO_MUTEX_RECURSIVE:
- id = pthread_self ();
-
- if (pthread_mutex_timedlock (&mutex->mutex, timeout) != 0)
- return ETIMEDOUT;
-
- while (1) {
- if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
- mutex->owner = id;
- mutex->depth = 1;
- break;
- } else if (pthread_equal (mutex->owner, id)) {
- mutex->depth++;
- break;
- } else {
- mutex->waiters++;
- if (pthread_cond_timedwait (&mutex->cond, &mutex->mutex, timeout) != 0)
- return ETIMEDOUT;
- mutex->waiters--;
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_unlock (mono_mutex_t *mutex)
-{
- int thr_ret;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- return pthread_mutex_unlock (&mutex->mutex);
- case MONO_MUTEX_RECURSIVE:
- if (pthread_mutex_lock (&mutex->mutex) != 0)
- return EINVAL;
-
- 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) {
- thr_ret = pthread_cond_signal (&mutex->cond);
- g_assert (thr_ret == 0);
- }
- }
-
- return pthread_mutex_unlock (&mutex->mutex);
- }
-
- return EINVAL;
-}
-
-int
-mono_mutex_destroy (mono_mutex_t *mutex)
-{
- int ret = 0;
- int thr_ret;
-
- switch (mutex->type) {
- case MONO_MUTEX_NORMAL:
- ret = pthread_mutex_destroy (&mutex->mutex);
- break;
- case MONO_MUTEX_RECURSIVE:
- if ((ret = pthread_mutex_destroy (&mutex->mutex)) == 0) {
- thr_ret = pthread_cond_destroy (&mutex->cond);
- g_assert (thr_ret == 0);
- }
- }
-
- return ret;
-}
-
-
-int
-mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex)
-{
- return pthread_cond_wait (cond, &mutex->mutex);
-}
-
-int
-mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout)
-{
- return pthread_cond_timedwait (cond, &mutex->mutex, timeout);
-}
-
-#endif /* USE_MONO_MUTEX */
+++ /dev/null
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- * mono-mutex.h: Portability wrappers around POSIX Mutexes
- *
- * Authors: Jeffrey Stedfast <fejj@ximian.com>
- *
- * Copyright 2002 Ximian, Inc. (www.ximian.com)
- */
-
-
-#ifndef __MONO_MUTEX_H__
-#define __MONO_MUTEX_H__
-
-#include <glib.h>
-#ifdef HAVE_PTHREAD_H
-#include <pthread.h>
-#endif
-#include <time.h>
-
-G_BEGIN_DECLS
-
-#ifndef HOST_WIN32
-
-typedef struct {
- pthread_mutex_t mutex;
- gboolean complete;
-} mono_once_t;
-
-#define MONO_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, FALSE }
-
-int mono_once (mono_once_t *once, void (*once_init) (void));
-
-
-#ifdef USE_MONO_MUTEX
-
-#define MONO_THREAD_NONE ((pthread_t)~0)
-
-/* mutex types... */
-enum {
- MONO_MUTEX_NORMAL,
- MONO_MUTEX_RECURSIVE,
- MONO_MUTEX_ERRORCHECK = MONO_MUTEX_NORMAL,
- MONO_MUTEX_DEFAULT = MONO_MUTEX_NORMAL
-};
-
-/* mutex protocol attributes... */
-enum {
- MONO_THREAD_PRIO_NONE,
- MONO_THREAD_PRIO_INHERIT,
- MONO_THREAD_PRIO_PROTECT,
-};
-
-/* mutex process sharing attributes... */
-enum {
- MONO_THREAD_PROCESS_PRIVATE,
- MONO_THREAD_PROCESS_SHARED
-};
-
-typedef struct _mono_mutexattr_t {
- int type : 1;
- int shared : 1;
- int protocol : 2;
- int priority : 28;
-} mono_mutexattr_t;
-
-typedef struct _mono_mutex_t {
- int type;
- pthread_t owner;
- short waiters;
- short depth;
- pthread_mutex_t mutex;
- pthread_cond_t cond;
-} mono_mutex_t;
-
-/* static initializers */
-#define MONO_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, 0 }
-#define MONO_RECURSIVE_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER }
-
-int mono_mutexattr_init (mono_mutexattr_t *attr);
-int mono_mutexattr_settype (mono_mutexattr_t *attr, int type);
-int mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type);
-int mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared);
-int mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared);
-int mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol);
-int mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol);
-int mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling);
-int mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling);
-int mono_mutexattr_destroy (mono_mutexattr_t *attr);
-
-
-int mono_mutex_init (mono_mutex_t *mutex, const mono_mutexattr_t *attr);
-int mono_mutex_lock (mono_mutex_t *mutex);
-int mono_mutex_trylock (mono_mutex_t *mutex);
-int mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout);
-int mono_mutex_unlock (mono_mutex_t *mutex);
-int mono_mutex_destroy (mono_mutex_t *mutex);
-
-#define mono_cond_init(cond,attr) pthread_cond_init (cond, attr)
-int mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex);
-int mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout);
-#define mono_cond_signal(cond) pthread_cond_signal (cond)
-#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
-#define mono_cond_destroy(cond)
-
-#else /* system is equipped with a fully-functional pthread mutex library */
-
-#define MONO_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL
-#define MONO_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
-#define MONO_MUTEX_ERRORCHECK PTHREAD_MUTEX_NORMAL
-#define MONO_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
-
-#define MONO_THREAD_PRIO_NONE PTHREAD_PRIO_NONE
-#define MONO_THREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT
-#define MONO_THREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT
-
-#define MONO_THREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
-#define MONO_THREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
-
-typedef pthread_mutex_t mono_mutex_t;
-typedef pthread_mutexattr_t mono_mutexattr_t;
-typedef pthread_cond_t mono_cond_t;
-
-#define MONO_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
-#define MONO_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER
-#define MONO_COND_INITIALIZER PTHREAD_COND_INITIALIZER
-
-#define mono_mutexattr_init(attr) pthread_mutexattr_init (attr)
-#define mono_mutexattr_settype(attr,type) pthread_mutexattr_settype (attr, type)
-#define mono_mutexattr_gettype(attr,type) pthread_mutexattr_gettype (attr, type)
-#define mono_mutexattr_setpshared(attr,pshared) pthread_mutexattr_setpshared (attr, pshared)
-#define mono_mutexattr_getpshared(attr,pshared) pthread_mutexattr_getpshared (attr, pshared)
-#define mono_mutexattr_setprotocol(attr,protocol) pthread_mutexattr_setprotocol (attr, protocol)
-#define mono_mutexattr_getprotocol(attr,protocol) pthread_mutexattr_getprotocol (attr, protocol)
-#define mono_mutexattr_setprioceiling(attr,prioceiling) pthread_mutexattr_setprioceiling (attr, prioceiling)
-#define mono_mutexattr_getprioceiling(attr,prioceiling) pthread_mutexattr_getprioceiling (attr, prioceiling)
-#define mono_mutexattr_destroy(attr) pthread_mutexattr_destroy (attr)
-
-#define mono_mutex_init(mutex,attr) pthread_mutex_init (mutex, attr)
-#define mono_mutex_lock(mutex) pthread_mutex_lock (mutex)
-#define mono_mutex_trylock(mutex) pthread_mutex_trylock (mutex)
-#define mono_mutex_timedlock(mutex,timeout) pthread_mutex_timedlock (mutex, timeout)
-#define mono_mutex_unlock(mutex) pthread_mutex_unlock (mutex)
-#define mono_mutex_destroy(mutex) pthread_mutex_destroy (mutex)
-
-#define mono_cond_init(cond,attr) pthread_cond_init (cond,attr)
-#define mono_cond_wait(cond,mutex) pthread_cond_wait (cond, mutex)
-#define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
-#define mono_cond_signal(cond) pthread_cond_signal (cond)
-#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
-#define mono_cond_destroy(cond)
-
-#endif /* USE_MONO_MUTEX */
-
-/* This is a function so it can be passed to pthread_cleanup_push -
- * that is a macro and giving it a macro as a parameter breaks.
- */
-G_GNUC_UNUSED
-static inline int mono_mutex_unlock_in_cleanup (mono_mutex_t *mutex)
-{
- return(mono_mutex_unlock (mutex));
-}
-
-#else
-
-typedef CRITICAL_SECTION mono_mutex_t;
-typedef HANDLE mono_cond_t;
-
-#define mono_mutex_init(mutex,attr) InitializeCriticalSection((mutex))
-#define mono_mutex_lock(mutex) EnterCriticalSection((mutex))
-#define mono_mutex_trylock(mutex) TryEnterCriticalSection((mutex))
-#define mono_mutex_unlock(mutex) LeaveCriticalSection((mutex))
-#define mono_mutex_destroy(mutex) DeleteCriticalSection((mutex))
-
-
-#define mono_cond_init(cond,attr) do{*(cond) = CreateEvent(NULL,FALSE,FALSE,NULL); } while (0)
-#define mono_cond_wait(cond,mutex) WaitForSingleObject(*(cond),INFINITE)
-#define mono_cond_timedwait(cond,mutex,timeout) WaitForSingleObject(*(cond),timeout)
-#define mono_cond_signal(cond) SetEvent(*(cond))
-#define mono_cond_broadcast(cond) (!SetEvent(*(cond)))
-#define mono_cond_destroy(cond) CloseHandle(*(cond))
-
-#define MONO_COND_INITIALIZER NULL
-#endif
-
-G_END_DECLS
-
-#endif /* __MONO_MUTEX_H__ */
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/mutex-private.h>
+#include <mono/utils/mono-mutex.h>
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/process-private.h>
#include <mono/io-layer/threads.h>
#include <mono/utils/strenc.h>
#include <mono/io-layer/timefuncs-private.h>
#include <mono/utils/mono-time.h>
#include <mono/utils/mono-membar.h>
+#include <mono/utils/mono-mutex.h>
/* The process' environment strings */
#if defined(__APPLE__) && !defined (__arm__)
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/misc-private.h>
#include <mono/io-layer/handles-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/semaphore-private.h>
+#include <mono/utils/mono-mutex.h>
+
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#include <mono/io-layer/wapi.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/wapi-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/misc-private.h>
+#include <mono/utils/mono-mutex.h>
+
#if 0
#define DEBUG(...) g_message(__VA_ARGS__)
#else
#include <mono/io-layer/wapi-private.h>
#include <mono/io-layer/handles-private.h>
#include <mono/io-layer/misc-private.h>
-#include <mono/io-layer/mono-mutex.h>
#include <mono/io-layer/thread-private.h>
#include <mono/io-layer/mutex-private.h>
#include <mono/utils/mono-threads.h>
#include <mono/utils/gc_wrapper.h>
#include <mono/utils/atomic.h>
+#include <mono/utils/mono-mutex.h>
#ifdef HAVE_VALGRIND_MEMCHECK_H
#include <valgrind/memcheck.h>
#include <mono/utils/dtrace.h>
#include <mono/utils/mono-logger-internal.h>
#include <mono/utils/atomic.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
#include <mono/metadata/class-internals.h>
#include <mono/metadata/object-internals.h>
#include <mono/metadata/sgen-conf.h>
#ifndef DISABLE_DEBUGGER_AGENT
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
/* Definitions to make backporting to 2.6 easier */
//#define MonoInternalThread MonoThread
#include <mono/metadata/threads.h>
#include <mono/metadata/profiler.h>
#include <mono/metadata/loader.h>
-#include <mono/io-layer/mono-mutex.h>
+#include <mono/utils/mono-mutex.h>
#define LOCATION_INDENT " "
#define BACKTRACE_SIZE 64
mono-math.c \
mono-mmap.c \
mono-mmap.h \
+ mono-mutex.c \
+ mono-mutex.h \
mono-networkinterfaces.c \
mono-networkinterfaces.h \
mono-proclib.c \
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * mono-mutex.h: Portability wrappers around POSIX Mutexes
+ *
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ */
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <assert.h>
+#include <sys/time.h>
+
+#include "mono-mutex.h"
+
+
+#ifndef HAVE_PTHREAD_MUTEX_TIMEDLOCK
+/* 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_NEEDED struct timespec *timeout)
+{
+ struct timeval timenow;
+ struct timespec sleepytime;
+ int retcode;
+
+ /* This is just to avoid a completely busy wait */
+ sleepytime.tv_sec = 0;
+ sleepytime.tv_nsec = 10000000; /* 10ms */
+
+ while ((retcode = pthread_mutex_trylock (mutex)) == EBUSY) {
+ gettimeofday (&timenow, NULL);
+
+ if (timenow.tv_sec >= timeout->tv_sec &&
+ (timenow.tv_usec * 1000) >= timeout->tv_nsec) {
+ return ETIMEDOUT;
+ }
+
+ nanosleep (&sleepytime, NULL);
+ }
+
+ return retcode;
+}
+#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_mutexattr_init (mono_mutexattr_t *attr)
+{
+ memset (attr, 0, sizeof (mono_mutexattr_t));
+ return 0;
+}
+
+int
+mono_mutexattr_settype (mono_mutexattr_t *attr, int type)
+{
+ attr->type = type;
+ return 0;
+}
+
+int
+mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type)
+{
+ *type = attr->type;
+ return 0;
+}
+
+int
+mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared)
+{
+ attr->shared = pshared;
+ return 0;
+}
+
+int
+mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared)
+{
+ *pshared = attr->shared;
+ return 0;
+}
+
+int
+mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol)
+{
+ attr->protocol = protocol;
+ return 0;
+}
+
+int
+mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol)
+{
+ *protocol = attr->protocol;
+ return 0;
+}
+
+int
+mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling)
+{
+ attr->priority = prioceiling;
+ return 0;
+}
+
+int
+mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling)
+{
+ *prioceiling = attr->priority;
+ return 0;
+}
+
+int
+mono_mutexattr_destroy (mono_mutexattr_t *attr)
+{
+ return 0;
+}
+
+
+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;
+ ret = pthread_mutex_init (&mutex->mutex, NULL);
+ } else {
+ mutex->type = MONO_MUTEX_RECURSIVE;
+ ret = pthread_mutex_init (&mutex->mutex, NULL);
+ thr_ret = pthread_cond_init (&mutex->cond, NULL);
+ g_assert (thr_ret == 0);
+ }
+
+ return(ret);
+}
+
+int
+mono_mutex_lock (mono_mutex_t *mutex)
+{
+ pthread_t id;
+
+ switch (mutex->type) {
+ case MONO_MUTEX_NORMAL:
+ return pthread_mutex_lock (&mutex->mutex);
+ case MONO_MUTEX_RECURSIVE:
+ id = pthread_self ();
+ if (pthread_mutex_lock (&mutex->mutex) != 0)
+ return EINVAL;
+
+ while (1) {
+ if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
+ mutex->owner = id;
+ mutex->depth = 1;
+ break;
+ } else if (pthread_equal (mutex->owner, id)) {
+ mutex->depth++;
+ break;
+ } else {
+ mutex->waiters++;
+ if (pthread_cond_wait (&mutex->cond, &mutex->mutex) != 0)
+ return EINVAL;
+ mutex->waiters--;
+ }
+ }
+
+ return pthread_mutex_unlock (&mutex->mutex);
+ }
+
+ return EINVAL;
+}
+
+int
+mono_mutex_trylock (mono_mutex_t *mutex)
+{
+ pthread_t id;
+
+ switch (mutex->type) {
+ case MONO_MUTEX_NORMAL:
+ return pthread_mutex_trylock (&mutex->mutex);
+ case MONO_MUTEX_RECURSIVE:
+ id = pthread_self ();
+
+ if (pthread_mutex_lock (&mutex->mutex) != 0)
+ return EINVAL;
+
+ if (!pthread_equal (mutex->owner, MONO_THREAD_NONE) &&
+ !pthread_equal (mutex->owner, id)) {
+ pthread_mutex_unlock (&mutex->mutex);
+ return EBUSY;
+ }
+
+ while (1) {
+ if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
+ mutex->owner = id;
+ mutex->depth = 1;
+ break;
+ } else {
+ mutex->depth++;
+ break;
+ }
+ }
+
+ return pthread_mutex_unlock (&mutex->mutex);
+ }
+
+ return EINVAL;
+}
+
+int
+mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout)
+{
+ pthread_t id;
+
+ switch (mutex->type) {
+ case MONO_MUTEX_NORMAL:
+ return pthread_mutex_timedlock (&mutex->mutex, timeout);
+ case MONO_MUTEX_RECURSIVE:
+ id = pthread_self ();
+
+ if (pthread_mutex_timedlock (&mutex->mutex, timeout) != 0)
+ return ETIMEDOUT;
+
+ while (1) {
+ if (pthread_equal (mutex->owner, MONO_THREAD_NONE)) {
+ mutex->owner = id;
+ mutex->depth = 1;
+ break;
+ } else if (pthread_equal (mutex->owner, id)) {
+ mutex->depth++;
+ break;
+ } else {
+ mutex->waiters++;
+ if (pthread_cond_timedwait (&mutex->cond, &mutex->mutex, timeout) != 0)
+ return ETIMEDOUT;
+ mutex->waiters--;
+ }
+ }
+
+ return pthread_mutex_unlock (&mutex->mutex);
+ }
+
+ return EINVAL;
+}
+
+int
+mono_mutex_unlock (mono_mutex_t *mutex)
+{
+ int thr_ret;
+
+ switch (mutex->type) {
+ case MONO_MUTEX_NORMAL:
+ return pthread_mutex_unlock (&mutex->mutex);
+ case MONO_MUTEX_RECURSIVE:
+ if (pthread_mutex_lock (&mutex->mutex) != 0)
+ return EINVAL;
+
+ 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) {
+ thr_ret = pthread_cond_signal (&mutex->cond);
+ g_assert (thr_ret == 0);
+ }
+ }
+
+ return pthread_mutex_unlock (&mutex->mutex);
+ }
+
+ return EINVAL;
+}
+
+int
+mono_mutex_destroy (mono_mutex_t *mutex)
+{
+ int ret = 0;
+ int thr_ret;
+
+ switch (mutex->type) {
+ case MONO_MUTEX_NORMAL:
+ ret = pthread_mutex_destroy (&mutex->mutex);
+ break;
+ case MONO_MUTEX_RECURSIVE:
+ if ((ret = pthread_mutex_destroy (&mutex->mutex)) == 0) {
+ thr_ret = pthread_cond_destroy (&mutex->cond);
+ g_assert (thr_ret == 0);
+ }
+ }
+
+ return ret;
+}
+
+
+int
+mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex)
+{
+ return pthread_cond_wait (cond, &mutex->mutex);
+}
+
+int
+mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout)
+{
+ return pthread_cond_timedwait (cond, &mutex->mutex, timeout);
+}
+
+#endif /* USE_MONO_MUTEX */
--- /dev/null
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * mono-mutex.h: Portability wrappers around POSIX Mutexes
+ *
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ */
+
+
+#ifndef __MONO_MUTEX_H__
+#define __MONO_MUTEX_H__
+
+#include <glib.h>
+#ifdef HAVE_PTHREAD_H
+#include <pthread.h>
+#endif
+#include <time.h>
+
+G_BEGIN_DECLS
+
+#ifndef HOST_WIN32
+
+typedef struct {
+ pthread_mutex_t mutex;
+ gboolean complete;
+} mono_once_t;
+
+#define MONO_ONCE_INIT { PTHREAD_MUTEX_INITIALIZER, FALSE }
+
+int mono_once (mono_once_t *once, void (*once_init) (void));
+
+
+#ifdef USE_MONO_MUTEX
+
+#define MONO_THREAD_NONE ((pthread_t)~0)
+
+/* mutex types... */
+enum {
+ MONO_MUTEX_NORMAL,
+ MONO_MUTEX_RECURSIVE,
+ MONO_MUTEX_ERRORCHECK = MONO_MUTEX_NORMAL,
+ MONO_MUTEX_DEFAULT = MONO_MUTEX_NORMAL
+};
+
+/* mutex protocol attributes... */
+enum {
+ MONO_THREAD_PRIO_NONE,
+ MONO_THREAD_PRIO_INHERIT,
+ MONO_THREAD_PRIO_PROTECT,
+};
+
+/* mutex process sharing attributes... */
+enum {
+ MONO_THREAD_PROCESS_PRIVATE,
+ MONO_THREAD_PROCESS_SHARED
+};
+
+typedef struct _mono_mutexattr_t {
+ int type : 1;
+ int shared : 1;
+ int protocol : 2;
+ int priority : 28;
+} mono_mutexattr_t;
+
+typedef struct _mono_mutex_t {
+ int type;
+ pthread_t owner;
+ short waiters;
+ short depth;
+ pthread_mutex_t mutex;
+ pthread_cond_t cond;
+} mono_mutex_t;
+
+/* static initializers */
+#define MONO_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, 0 }
+#define MONO_RECURSIVE_MUTEX_INITIALIZER { 0, MONO_THREAD_NONE, 0, 0, PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER }
+
+int mono_mutexattr_init (mono_mutexattr_t *attr);
+int mono_mutexattr_settype (mono_mutexattr_t *attr, int type);
+int mono_mutexattr_gettype (mono_mutexattr_t *attr, int *type);
+int mono_mutexattr_setpshared (mono_mutexattr_t *attr, int pshared);
+int mono_mutexattr_getpshared (mono_mutexattr_t *attr, int *pshared);
+int mono_mutexattr_setprotocol (mono_mutexattr_t *attr, int protocol);
+int mono_mutexattr_getprotocol (mono_mutexattr_t *attr, int *protocol);
+int mono_mutexattr_setprioceiling (mono_mutexattr_t *attr, int prioceiling);
+int mono_mutexattr_getprioceiling (mono_mutexattr_t *attr, int *prioceiling);
+int mono_mutexattr_destroy (mono_mutexattr_t *attr);
+
+
+int mono_mutex_init (mono_mutex_t *mutex, const mono_mutexattr_t *attr);
+int mono_mutex_lock (mono_mutex_t *mutex);
+int mono_mutex_trylock (mono_mutex_t *mutex);
+int mono_mutex_timedlock (mono_mutex_t *mutex, const struct timespec *timeout);
+int mono_mutex_unlock (mono_mutex_t *mutex);
+int mono_mutex_destroy (mono_mutex_t *mutex);
+
+#define mono_cond_init(cond,attr) pthread_cond_init (cond, attr)
+int mono_cond_wait (pthread_cond_t *cond, mono_mutex_t *mutex);
+int mono_cond_timedwait (pthread_cond_t *cond, mono_mutex_t *mutex, const struct timespec *timeout);
+#define mono_cond_signal(cond) pthread_cond_signal (cond)
+#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
+#define mono_cond_destroy(cond)
+
+#else /* system is equipped with a fully-functional pthread mutex library */
+
+#define MONO_MUTEX_NORMAL PTHREAD_MUTEX_NORMAL
+#define MONO_MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
+#define MONO_MUTEX_ERRORCHECK PTHREAD_MUTEX_NORMAL
+#define MONO_MUTEX_DEFAULT PTHREAD_MUTEX_NORMAL
+
+#define MONO_THREAD_PRIO_NONE PTHREAD_PRIO_NONE
+#define MONO_THREAD_PRIO_INHERIT PTHREAD_PRIO_INHERIT
+#define MONO_THREAD_PRIO_PROTECT PTHREAD_PRIO_PROTECT
+
+#define MONO_THREAD_PROCESS_PRIVATE PTHREAD_PROCESS_PRIVATE
+#define MONO_THREAD_PROCESS_SHARED PTHREAD_PROCESS_SHARED
+
+typedef pthread_mutex_t mono_mutex_t;
+typedef pthread_mutexattr_t mono_mutexattr_t;
+typedef pthread_cond_t mono_cond_t;
+
+#define MONO_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
+#define MONO_RECURSIVE_MUTEX_INITIALIZER PTHREAD_RECURSIVE_MUTEX_INITIALIZER
+#define MONO_COND_INITIALIZER PTHREAD_COND_INITIALIZER
+
+#define mono_mutexattr_init(attr) pthread_mutexattr_init (attr)
+#define mono_mutexattr_settype(attr,type) pthread_mutexattr_settype (attr, type)
+#define mono_mutexattr_gettype(attr,type) pthread_mutexattr_gettype (attr, type)
+#define mono_mutexattr_setpshared(attr,pshared) pthread_mutexattr_setpshared (attr, pshared)
+#define mono_mutexattr_getpshared(attr,pshared) pthread_mutexattr_getpshared (attr, pshared)
+#define mono_mutexattr_setprotocol(attr,protocol) pthread_mutexattr_setprotocol (attr, protocol)
+#define mono_mutexattr_getprotocol(attr,protocol) pthread_mutexattr_getprotocol (attr, protocol)
+#define mono_mutexattr_setprioceiling(attr,prioceiling) pthread_mutexattr_setprioceiling (attr, prioceiling)
+#define mono_mutexattr_getprioceiling(attr,prioceiling) pthread_mutexattr_getprioceiling (attr, prioceiling)
+#define mono_mutexattr_destroy(attr) pthread_mutexattr_destroy (attr)
+
+#define mono_mutex_init(mutex,attr) pthread_mutex_init (mutex, attr)
+#define mono_mutex_lock(mutex) pthread_mutex_lock (mutex)
+#define mono_mutex_trylock(mutex) pthread_mutex_trylock (mutex)
+#define mono_mutex_timedlock(mutex,timeout) pthread_mutex_timedlock (mutex, timeout)
+#define mono_mutex_unlock(mutex) pthread_mutex_unlock (mutex)
+#define mono_mutex_destroy(mutex) pthread_mutex_destroy (mutex)
+
+#define mono_cond_init(cond,attr) pthread_cond_init (cond,attr)
+#define mono_cond_wait(cond,mutex) pthread_cond_wait (cond, mutex)
+#define mono_cond_timedwait(cond,mutex,timeout) pthread_cond_timedwait (cond, mutex, timeout)
+#define mono_cond_signal(cond) pthread_cond_signal (cond)
+#define mono_cond_broadcast(cond) pthread_cond_broadcast (cond)
+#define mono_cond_destroy(cond)
+
+#endif /* USE_MONO_MUTEX */
+
+/* This is a function so it can be passed to pthread_cleanup_push -
+ * that is a macro and giving it a macro as a parameter breaks.
+ */
+G_GNUC_UNUSED
+static inline int mono_mutex_unlock_in_cleanup (mono_mutex_t *mutex)
+{
+ return(mono_mutex_unlock (mutex));
+}
+
+#else
+
+typedef CRITICAL_SECTION mono_mutex_t;
+typedef HANDLE mono_cond_t;
+
+#define mono_mutex_init(mutex,attr) InitializeCriticalSection((mutex))
+#define mono_mutex_lock(mutex) EnterCriticalSection((mutex))
+#define mono_mutex_trylock(mutex) TryEnterCriticalSection((mutex))
+#define mono_mutex_unlock(mutex) LeaveCriticalSection((mutex))
+#define mono_mutex_destroy(mutex) DeleteCriticalSection((mutex))
+
+
+#define mono_cond_init(cond,attr) do{*(cond) = CreateEvent(NULL,FALSE,FALSE,NULL); } while (0)
+#define mono_cond_wait(cond,mutex) WaitForSingleObject(*(cond),INFINITE)
+#define mono_cond_timedwait(cond,mutex,timeout) WaitForSingleObject(*(cond),timeout)
+#define mono_cond_signal(cond) SetEvent(*(cond))
+#define mono_cond_broadcast(cond) (!SetEvent(*(cond)))
+#define mono_cond_destroy(cond) CloseHandle(*(cond))
+
+#define MONO_COND_INITIALIZER NULL
+#endif
+
+G_END_DECLS
+
+#endif /* __MONO_MUTEX_H__ */