mono-mmap.h \
mono-mmap-internals.h \
mono-os-mutex.h \
- mono-os-mutex.c \
mono-coop-mutex.h \
mono-once.h \
mono-lazy-init.h \
mono-poll.c \
mono-path.c \
mono-os-semaphore.h \
- mono-os-semaphore.c \
mono-coop-semaphore.h \
mono-sigcontext.h \
mono-stdlib.c \
+++ /dev/null
-
-#include <config.h>
-#include <glib.h>
-
-#include <stdlib.h>
-#include <string.h>
-#include <time.h>
-
-#if !defined(HOST_WIN32)
-#include <pthread.h>
-#include <errno.h>
-#else
-#include <winsock2.h>
-#include <windows.h>
-#endif
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#include "mono-os-mutex.h"
-
-#if !defined(HOST_WIN32)
-
-void
-mono_os_mutex_init (mono_mutex_t *mutex)
-{
- gint res;
-
- res = pthread_mutex_init (mutex, NULL);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-void
-mono_os_mutex_init_recursive (mono_mutex_t *mutex)
-{
- gint res;
- pthread_mutexattr_t attr;
-
- res = pthread_mutexattr_init (&attr);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutexattr_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
- res = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
- res = pthread_mutex_init (mutex, &attr);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
- res = pthread_mutexattr_destroy (&attr);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutexattr_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-gint
-mono_os_mutex_destroy (mono_mutex_t *mutex)
-{
- gint res;
-
- res = pthread_mutex_destroy (mutex);
- if (G_UNLIKELY (res != 0 && res != EBUSY))
- g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
- return res != 0 ? -1 : 0;
-}
-
-void
-mono_os_mutex_lock (mono_mutex_t *mutex)
-{
- gint res;
-
- res = pthread_mutex_lock (mutex);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutex_lock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-gint
-mono_os_mutex_trylock (mono_mutex_t *mutex)
-{
- gint res;
-
- res = pthread_mutex_trylock (mutex);
- if (G_UNLIKELY (res != 0 && res != EBUSY))
- g_error ("%s: pthread_mutex_trylock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
- return res != 0 ? -1 : 0;
-}
-
-void
-mono_os_mutex_unlock (mono_mutex_t *mutex)
-{
- gint res;
-
- res = pthread_mutex_unlock (mutex);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_mutex_unlock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-void
-mono_os_cond_init (mono_cond_t *cond)
-{
- gint res;
-
- res = pthread_cond_init (cond, NULL);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_cond_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-gint
-mono_os_cond_destroy (mono_cond_t *cond)
-{
- gint res;
-
- res = pthread_cond_destroy (cond);
- if (G_UNLIKELY (res != 0 && res != EBUSY))
- g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
- return res != 0 ? -1 : 0;
-}
-
-void
-mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
-{
- gint res;
-
- res = pthread_cond_wait (cond, mutex);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-gint
-mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
-{
- struct timeval tv;
- struct timespec ts;
- gint64 usecs;
- gint res;
-
- if (timeout_ms == MONO_INFINITE_WAIT) {
- mono_os_cond_wait (cond, mutex);
- return 0;
- }
-
- /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
-
- res = gettimeofday (&tv, NULL);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
- tv.tv_sec += timeout_ms / 1000;
- usecs = tv.tv_usec + ((timeout_ms % 1000) * 1000);
- if (usecs >= 1000000) {
- usecs -= 1000000;
- tv.tv_sec ++;
- }
- ts.tv_sec = tv.tv_sec;
- ts.tv_nsec = usecs * 1000;
-
- res = pthread_cond_timedwait (cond, mutex, &ts);
- if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
- g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-
- return res != 0 ? -1 : 0;
-}
-
-void
-mono_os_cond_signal (mono_cond_t *cond)
-{
- gint res;
-
- res = pthread_cond_signal (cond);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_cond_signal failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-void
-mono_os_cond_broadcast (mono_cond_t *cond)
-{
- gint res;
-
- res = pthread_cond_broadcast (cond);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: pthread_cond_broadcast failed with \"%s\" (%d)", __func__, g_strerror (res), res);
-}
-
-#else
-
-/* Vanilla MinGW is missing some defs, load them from MinGW-w64. */
-#if defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600)
-
-/* Fixme: Opaque structs */
-typedef PVOID RTL_CONDITION_VARIABLE;
-
-#define RTL_SRWLOCK_INIT 0
-#define RTL_CONDITION_VARIABLE_INIT 0
-#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 1
-
-/*Condition Variables http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx*/
-typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
-
-WINBASEAPI VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
-WINBASEAPI WINBOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD dwMilliseconds);
-WINBASEAPI VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable);
-WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
-
-/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms683477(v=vs.85).aspx */
-WINBASEAPI BOOL WINAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
-
-#define CRITICAL_SECTION_NO_DEBUG_INFO 0x01000000
-
-#endif /* defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600) */
-
-void
-mono_os_mutex_init (mono_mutex_t *mutex)
-{
- BOOL res;
-
- res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
- if (G_UNLIKELY (res == 0))
- g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
-}
-
-void
-mono_os_mutex_init_recursive (mono_mutex_t *mutex)
-{
- BOOL res;
-
- res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
- if (G_UNLIKELY (res == 0))
- g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
-}
-
-gint
-mono_os_mutex_destroy (mono_mutex_t *mutex)
-{
- DeleteCriticalSection (mutex);
- return 0;
-}
-
-void
-mono_os_mutex_lock (mono_mutex_t *mutex)
-{
- EnterCriticalSection (mutex);
-}
-
-gint
-mono_os_mutex_trylock (mono_mutex_t *mutex)
-{
- return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
-}
-
-void
-mono_os_mutex_unlock (mono_mutex_t *mutex)
-{
- LeaveCriticalSection (mutex);
-}
-
-void
-mono_os_cond_init (mono_cond_t *cond)
-{
- InitializeConditionVariable (cond);
-}
-
-gint
-mono_os_cond_destroy (mono_cond_t *cond)
-{
- /* Beauty of win32 API: do not destroy it */
- return 0;
-}
-
-void
-mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
-{
- BOOL res;
-
- res = SleepConditionVariableCS (cond, mutex, INFINITE);
- if (G_UNLIKELY (res == 0))
- g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
-}
-
-gint
-mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
-{
- BOOL res;
-
- res = SleepConditionVariableCS (cond, mutex, timeout_ms);
- if (G_UNLIKELY (res == 0 && GetLastError () != ERROR_TIMEOUT))
- g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
-
- return res == 0 ? -1 : 0;
-}
-
-void
-mono_os_cond_signal (mono_cond_t *cond)
-{
- WakeConditionVariable (cond);
-}
-
-void
-mono_os_cond_broadcast (mono_cond_t *cond)
-{
- WakeAllConditionVariable (cond);
-}
-
-#endif
#include <config.h>
#include <glib.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+
#if !defined(HOST_WIN32)
#include <pthread.h>
+#include <errno.h>
#else
#include <winsock2.h>
#include <windows.h>
#endif
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+G_BEGIN_DECLS
+
#ifndef MONO_INFINITE_WAIT
#define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF)
#endif
-G_BEGIN_DECLS
#if !defined(HOST_WIN32)
typedef pthread_mutex_t mono_mutex_t;
typedef pthread_cond_t mono_cond_t;
+static inline void
+mono_os_mutex_init (mono_mutex_t *mutex)
+{
+ int res;
+
+ res = pthread_mutex_init (mutex, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+static inline void
+mono_os_mutex_init_recursive (mono_mutex_t *mutex)
+{
+ int res;
+ pthread_mutexattr_t attr;
+
+ res = pthread_mutexattr_init (&attr);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutexattr_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ res = pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutexattr_settype failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ res = pthread_mutex_init (mutex, &attr);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ res = pthread_mutexattr_destroy (&attr);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutexattr_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+static inline int
+mono_os_mutex_destroy (mono_mutex_t *mutex)
+{
+ int res;
+
+ res = pthread_mutex_destroy (mutex);
+ if (G_UNLIKELY (res != 0 && res != EBUSY))
+ g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ return res != 0 ? -1 : 0;
+}
+
+static inline void
+mono_os_mutex_lock (mono_mutex_t *mutex)
+{
+ int res;
+
+ res = pthread_mutex_lock (mutex);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_lock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+static inline int
+mono_os_mutex_trylock (mono_mutex_t *mutex)
+{
+ int res;
+
+ res = pthread_mutex_trylock (mutex);
+ if (G_UNLIKELY (res != 0 && res != EBUSY))
+ g_error ("%s: pthread_mutex_trylock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ return res != 0 ? -1 : 0;
+}
+
+static inline void
+mono_os_mutex_unlock (mono_mutex_t *mutex)
+{
+ int res;
+
+ res = pthread_mutex_unlock (mutex);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_mutex_unlock failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+static inline void
+mono_os_cond_init (mono_cond_t *cond)
+{
+ int res;
+
+ res = pthread_cond_init (cond, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_init failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+static inline int
+mono_os_cond_destroy (mono_cond_t *cond)
+{
+ int res;
+
+ res = pthread_cond_destroy (cond);
+ if (G_UNLIKELY (res != 0 && res != EBUSY))
+ g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ return res != 0 ? -1 : 0;
+}
+
+static inline void
+mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
+{
+ int res;
+
+ res = pthread_cond_wait (cond, mutex);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+static inline int
+mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
+{
+ struct timeval tv;
+ struct timespec ts;
+ gint64 usecs;
+ int res;
+
+ if (timeout_ms == MONO_INFINITE_WAIT) {
+ mono_os_cond_wait (cond, mutex);
+ return 0;
+ }
+
+ /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
+
+ res = gettimeofday (&tv, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+ tv.tv_sec += timeout_ms / 1000;
+ usecs = tv.tv_usec + ((timeout_ms % 1000) * 1000);
+ if (usecs >= 1000000) {
+ usecs -= 1000000;
+ tv.tv_sec ++;
+ }
+ ts.tv_sec = tv.tv_sec;
+ ts.tv_nsec = usecs * 1000;
+
+ res = pthread_cond_timedwait (cond, mutex, &ts);
+ if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
+ g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+
+ return res != 0 ? -1 : 0;
+}
+
+static inline void
+mono_os_cond_signal (mono_cond_t *cond)
+{
+ int res;
+
+ res = pthread_cond_signal (cond);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_signal failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
+static inline void
+mono_os_cond_broadcast (mono_cond_t *cond)
+{
+ int res;
+
+ res = pthread_cond_broadcast (cond);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: pthread_cond_broadcast failed with \"%s\" (%d)", __func__, g_strerror (res), res);
+}
+
#else
+/* Vanilla MinGW is missing some defs, load them from MinGW-w64. */
+#if defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600)
+
+/* Fixme: Opaque structs */
+typedef PVOID RTL_CONDITION_VARIABLE;
+typedef PVOID RTL_SRWLOCK;
+
+#ifndef _RTL_RUN_ONCE_DEF
+#define _RTL_RUN_ONCE_DEF 1
+typedef PVOID RTL_RUN_ONCE, *PRTL_RUN_ONCE;
+typedef DWORD (WINAPI *PRTL_RUN_ONCE_INIT_FN)(PRTL_RUN_ONCE, PVOID, PVOID *);
+#define RTL_RUN_ONCE_INIT 0
+#define RTL_RUN_ONCE_CHECK_ONLY 1UL
+#define RTL_RUN_ONCE_ASYNC 2UL
+#define RTL_RUN_ONCE_INIT_FAILED 4UL
+#define RTL_RUN_ONCE_CTX_RESERVED_BITS 2
+#endif /* _RTL_RUN_ONCE_DEF */
+#define RTL_SRWLOCK_INIT 0
+#define RTL_CONDITION_VARIABLE_INIT 0
+#define RTL_CONDITION_VARIABLE_LOCKMODE_SHARED 1
+
+#define CONDITION_VARIABLE_INIT RTL_CONDITION_VARIABLE_INIT
+#define CONDITION_VARIABLE_LOCKMODE_SHARED RTL_CONDITION_VARIABLE_LOCKMODE_SHARED
+#define SRWLOCK_INIT RTL_SRWLOCK_INIT
+
+/*Condition Variables http://msdn.microsoft.com/en-us/library/ms682052%28VS.85%29.aspx*/
+typedef RTL_CONDITION_VARIABLE CONDITION_VARIABLE, *PCONDITION_VARIABLE;
+typedef RTL_SRWLOCK SRWLOCK, *PSRWLOCK;
+
+WINBASEAPI VOID WINAPI InitializeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
+WINBASEAPI WINBOOL WINAPI SleepConditionVariableCS(PCONDITION_VARIABLE ConditionVariable, PCRITICAL_SECTION CriticalSection, DWORD dwMilliseconds);
+WINBASEAPI WINBOOL WINAPI SleepConditionVariableSRW(PCONDITION_VARIABLE ConditionVariable, PSRWLOCK SRWLock, DWORD dwMilliseconds, ULONG Flags);
+WINBASEAPI VOID WINAPI WakeAllConditionVariable(PCONDITION_VARIABLE ConditionVariable);
+WINBASEAPI VOID WINAPI WakeConditionVariable(PCONDITION_VARIABLE ConditionVariable);
+
+/*Slim Reader/Writer (SRW) Locks http://msdn.microsoft.com/en-us/library/aa904937%28VS.85%29.aspx*/
+WINBASEAPI VOID WINAPI AcquireSRWLockExclusive(PSRWLOCK SRWLock);
+WINBASEAPI VOID WINAPI AcquireSRWLockShared(PSRWLOCK SRWLock);
+WINBASEAPI VOID WINAPI InitializeSRWLock(PSRWLOCK SRWLock);
+WINBASEAPI VOID WINAPI ReleaseSRWLockExclusive(PSRWLOCK SRWLock);
+WINBASEAPI VOID WINAPI ReleaseSRWLockShared(PSRWLOCK SRWLock);
+
+WINBASEAPI BOOLEAN TryAcquireSRWLockExclusive(PSRWLOCK SRWLock);
+WINBASEAPI BOOLEAN TryAcquireSRWLockShared(PSRWLOCK SRWLock);
+
+/*One-Time Initialization http://msdn.microsoft.com/en-us/library/aa363808(VS.85).aspx*/
+#define INIT_ONCE_ASYNC 0x00000002UL
+#define INIT_ONCE_INIT_FAILED 0x00000004UL
+
+typedef PRTL_RUN_ONCE PINIT_ONCE;
+typedef PRTL_RUN_ONCE LPINIT_ONCE;
+typedef WINBOOL CALLBACK (*PINIT_ONCE_FN) (PINIT_ONCE InitOnce, PVOID Parameter, PVOID *Context);
+
+WINBASEAPI WINBOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD dwFlags, PBOOL fPending, LPVOID *lpContext);
+WINBASEAPI WINBOOL WINAPI InitOnceComplete(LPINIT_ONCE lpInitOnce, DWORD dwFlags, LPVOID lpContext);
+WINBASEAPI WINBOOL WINAPI InitOnceExecuteOnce(PINIT_ONCE InitOnce, PINIT_ONCE_FN InitFn, PVOID Parameter, LPVOID *Context);
+
+/* https://msdn.microsoft.com/en-us/library/windows/desktop/ms683477(v=vs.85).aspx */
+WINBASEAPI BOOL WINAPI InitializeCriticalSectionEx(LPCRITICAL_SECTION lpCriticalSection, DWORD dwSpinCount, DWORD Flags);
+
+#define CRITICAL_SECTION_NO_DEBUG_INFO 0x01000000
+
+#endif /* defined __MINGW32__ && !defined __MINGW64_VERSION_MAJOR && (_WIN32_WINNT >= 0x0600) */
+
typedef CRITICAL_SECTION mono_mutex_t;
typedef CONDITION_VARIABLE mono_cond_t;
-#endif
+static inline void
+mono_os_mutex_init (mono_mutex_t *mutex)
+{
+ BOOL res;
-/**
- * mono_os_mutex_init:
- */
-void
-mono_os_mutex_init (mono_mutex_t *mutex);
+ res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
+}
-/**
- * mono_os_mutex_init_recursive:
- */
-void
-mono_os_mutex_init_recursive (mono_mutex_t *mutex);
+static inline void
+mono_os_mutex_init_recursive (mono_mutex_t *mutex)
+{
+ BOOL res;
-/**
- * mono_os_mutex_destroy:
- *
- * @returns:
- * - 0: success
- * - -1: the mutex is busy (used by the io-layer)
- */
-gint
-mono_os_mutex_destroy (mono_mutex_t *mutex);
+ res = InitializeCriticalSectionEx (mutex, 0, CRITICAL_SECTION_NO_DEBUG_INFO);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: InitializeCriticalSectionEx failed with error %d", __func__, GetLastError ());
+}
-/**
- * mono_os_mutex_lock:
- */
-void
-mono_os_mutex_lock (mono_mutex_t *mutex);
+static inline int
+mono_os_mutex_destroy (mono_mutex_t *mutex)
+{
+ DeleteCriticalSection (mutex);
+ return 0;
+}
-/**
- * mono_os_mutex_trylock:
- *
- * @returns:
- * - 0: success
- * - -1: the mutex is busy
- */
-gint
-mono_os_mutex_trylock (mono_mutex_t *mutex);
+static inline void
+mono_os_mutex_lock (mono_mutex_t *mutex)
+{
+ EnterCriticalSection (mutex);
+}
-/**
- * mono_os_mutex_unlock:
- */
-void
-mono_os_mutex_unlock (mono_mutex_t *mutex);
+static inline int
+mono_os_mutex_trylock (mono_mutex_t *mutex)
+{
+ return TryEnterCriticalSection (mutex) == 0 ? -1 : 0;
+}
-/**
- * mono_os_cond_init:
- */
-void
-mono_os_cond_init (mono_cond_t *cond);
+static inline void
+mono_os_mutex_unlock (mono_mutex_t *mutex)
+{
+ LeaveCriticalSection (mutex);
+}
-/**
- * mono_os_cond_destroy:
- *
- * @returns:
- * - 0: success
- * - -1: the cond is busy (used by the io-layer)
- */
-gint
-mono_os_cond_destroy (mono_cond_t *cond);
+static inline void
+mono_os_cond_init (mono_cond_t *cond)
+{
+ InitializeConditionVariable (cond);
+}
-/**
- * mono_os_cond_wait:
- */
-void
-mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex);
+static inline int
+mono_os_cond_destroy (mono_cond_t *cond)
+{
+ /* Beauty of win32 API: do not destroy it */
+ return 0;
+}
-/**
- * mono_os_cond_timedwait:
- *
- * @returns:
- * - 0: success
- * - -1: wait timed out
- */
-gint
-mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms);
+static inline void
+mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
+{
+ BOOL res;
-/**
- * mono_os_cond_signal:
- */
-void
-mono_os_cond_signal (mono_cond_t *cond);
+ res = SleepConditionVariableCS (cond, mutex, INFINITE);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+}
-/**
- * mono_os_cond_broadcast:
- */
-void
-mono_os_cond_broadcast (mono_cond_t *cond);
+static inline int
+mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
+{
+ BOOL res;
+
+ res = SleepConditionVariableCS (cond, mutex, timeout_ms);
+ if (G_UNLIKELY (res == 0 && GetLastError () != ERROR_TIMEOUT))
+ g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ());
+
+ return res == 0 ? -1 : 0;
+}
+
+static inline void
+mono_os_cond_signal (mono_cond_t *cond)
+{
+ WakeConditionVariable (cond);
+}
+
+static inline void
+mono_os_cond_broadcast (mono_cond_t *cond)
+{
+ WakeAllConditionVariable (cond);
+}
+
+#endif
G_END_DECLS
+++ /dev/null
-
-#include <config.h>
-#include <glib.h>
-
-#include <errno.h>
-
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
-
-#ifdef HAVE_UNISTD_H
-#include <unistd.h>
-#endif
-
-#include "mono-os-semaphore.h"
-
-#ifndef NSEC_PER_SEC
-#define NSEC_PER_SEC (1000 * 1000 * 1000)
-#endif
-
-#if defined(USE_MACH_SEMA)
-
-void
-mono_os_sem_init (MonoSemType *sem, gint value)
-{
- kern_return_t res;
-
- res = semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value);
- if (G_UNLIKELY (res != KERN_SUCCESS))
- g_error ("%s: semaphore_create failed with error %d", __func__, res);
-}
-
-void
-mono_os_sem_destroy (MonoSemType *sem)
-{
- kern_return_t res;
-
- res = semaphore_destroy (current_task (), *sem);
- if (G_UNLIKELY (res != KERN_SUCCESS))
- g_error ("%s: semaphore_destroy failed with error %d", __func__, res);
-}
-
-gint
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
-{
- kern_return_t res;
-
-retry:
- res = semaphore_wait (*sem);
- if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
- g_error ("%s: semaphore_wait failed with error %d", __func__, res);
-
- if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE))
- goto retry;
-
- return res != KERN_SUCCESS ? -1 : 0;
-}
-
-MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
-{
- kern_return_t res;
- gint resint;
- mach_timespec_t ts, copy;
- struct timeval start, current;
-
- if (timeout_ms == MONO_INFINITE_WAIT)
- return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
-
- ts.tv_sec = timeout_ms / 1000;
- ts.tv_nsec = (timeout_ms % 1000) * 1000000;
- while (ts.tv_nsec >= NSEC_PER_SEC) {
- ts.tv_nsec -= NSEC_PER_SEC;
- ts.tv_sec++;
- }
-
- copy = ts;
- resint = gettimeofday (&start, NULL);
- if (G_UNLIKELY (resint != 0))
- g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-retry:
- res = semaphore_timedwait (*sem, ts);
- if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED && res != KERN_OPERATION_TIMED_OUT))
- g_error ("%s: semaphore_timedwait failed with error %d", __func__, res);
-
- if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
- ts = copy;
-
- resint = gettimeofday (¤t, NULL);
- if (G_UNLIKELY (resint != 0))
- g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
- ts.tv_sec -= (current.tv_sec - start.tv_sec);
- ts.tv_nsec -= (current.tv_usec - start.tv_usec) * 1000;
- if (ts.tv_nsec < 0) {
- if (ts.tv_sec <= 0) {
- ts.tv_nsec = 0;
- } else {
- ts.tv_sec--;
- ts.tv_nsec += NSEC_PER_SEC;
- }
- }
- if (ts.tv_sec < 0) {
- ts.tv_sec = 0;
- ts.tv_nsec = 0;
- }
-
- goto retry;
- }
-
- switch (res) {
- case KERN_SUCCESS:
- return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
- case KERN_ABORTED:
- return MONO_SEM_TIMEDWAIT_RET_ALERTED;
- case KERN_OPERATION_TIMED_OUT:
- return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
- default:
- g_assert_not_reached ();
- }
-}
-
-void
-mono_os_sem_post (MonoSemType *sem)
-{
- kern_return_t res;
-
-retry:
- res = semaphore_signal (*sem);
- if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
- g_error ("%s: semaphore_signal failed with error %d", __func__, res);
-
- if (res == KERN_ABORTED)
- goto retry;
-}
-
-#elif !defined(HOST_WIN32) && defined(HAVE_SEMAPHORE_H)
-
-void
-mono_os_sem_init (MonoSemType *sem, gint value)
-{
- gint res;
-
- res = sem_init (sem, 0, value);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: sem_init failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-}
-
-void
-mono_os_sem_destroy (MonoSemType *sem)
-{
- gint res;
-
- res = sem_destroy (sem);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: sem_destroy failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-}
-
-gint
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
-{
- gint res;
-
-retry:
- res = sem_wait (sem);
- if (G_UNLIKELY (res != 0 && errno != EINTR))
- g_error ("%s: sem_wait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
- if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
- goto retry;
-
- return res != 0 ? -1 : 0;
-}
-
-MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
-{
- struct timespec ts, copy;
- struct timeval t;
- gint res;
-
- if (timeout_ms == 0) {
- res = sem_trywait (sem);
- if (G_UNLIKELY (res != 0 && errno != EINTR && errno != EAGAIN))
- g_error ("%s: sem_trywait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
- if (res == 0)
- return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
- else if (errno == EINTR)
- return MONO_SEM_TIMEDWAIT_RET_ALERTED;
- else if (errno == EAGAIN)
- return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
- else
- g_assert_not_reached ();
- }
-
- if (timeout_ms == MONO_INFINITE_WAIT)
- return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
-
- res = gettimeofday (&t, NULL);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
- ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
- ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
- while (ts.tv_nsec >= NSEC_PER_SEC) {
- ts.tv_nsec -= NSEC_PER_SEC;
- ts.tv_sec++;
- }
-
- copy = ts;
-
-retry:
- res = sem_timedwait (sem, &ts);
- if (G_UNLIKELY (res != 0 && errno != EINTR && errno != ETIMEDOUT))
- g_error ("%s: sem_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
- if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
- ts = copy;
- goto retry;
- }
-
- if (res == 0)
- return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
- else if (errno == EINTR)
- return MONO_SEM_TIMEDWAIT_RET_ALERTED;
- else if (errno == ETIMEDOUT)
- return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
- else
- g_assert_not_reached ();
-}
-
-void
-mono_os_sem_post (MonoSemType *sem)
-{
- gint res;
-
- res = sem_post (sem);
- if (G_UNLIKELY (res != 0))
- g_error ("%s: sem_post failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-}
-
-#else
-
-void
-mono_os_sem_init (MonoSemType *sem, gint value)
-{
- *sem = CreateSemaphore (NULL, value, 0x7FFFFFFF, NULL);
- if (G_UNLIKELY (*sem == NULL))
- g_error ("%s: CreateSemaphore failed with error %d", __func__, GetLastError ());
-}
-
-void
-mono_os_sem_destroy (MonoSemType *sem)
-{
- BOOL res;
-
- res = CloseHandle (*sem);
- if (G_UNLIKELY (res == 0))
- g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
-}
-
-MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
-{
- BOOL res;
-
-retry:
- res = WaitForSingleObjectEx (*sem, timeout_ms, flags & MONO_SEM_FLAGS_ALERTABLE);
- if (G_UNLIKELY (res != WAIT_OBJECT_0 && res != WAIT_IO_COMPLETION && res != WAIT_TIMEOUT))
- g_error ("%s: WaitForSingleObjectEx failed with error %d", __func__, GetLastError ());
-
- if (res == WAIT_IO_COMPLETION && !(flags & MONO_SEM_FLAGS_ALERTABLE))
- goto retry;
-
- switch (res) {
- case WAIT_OBJECT_0:
- return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
- case WAIT_IO_COMPLETION:
- return MONO_SEM_TIMEDWAIT_RET_ALERTED;
- case WAIT_TIMEOUT:
- return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
- default:
- g_assert_not_reached ();
- }
-}
-
-gint
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
-{
- return mono_os_sem_timedwait (sem, INFINITE, flags) != 0 ? -1 : 0;
-}
-
-void
-mono_os_sem_post (MonoSemType *sem)
-{
- BOOL res;
-
- res = ReleaseSemaphore (*sem, 1, NULL);
- if (G_UNLIKELY (res == 0))
- g_error ("%s: ReleaseSemaphore failed with error %d", __func__, GetLastError ());
-}
-
-#endif
#include <config.h>
#include <glib.h>
+#include <errno.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
#if defined(USE_MACH_SEMA)
#include <mach/mach_init.h>
#include <mach/task.h>
#include <windows.h>
#endif
+#define MONO_HAS_SEMAPHORES 1
+
+#ifndef NSEC_PER_SEC
+#define NSEC_PER_SEC (1000 * 1000 * 1000)
+#endif
+
#ifndef MONO_INFINITE_WAIT
#define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF)
#endif
G_BEGIN_DECLS
+typedef enum {
+ MONO_SEM_FLAGS_NONE = 0,
+ MONO_SEM_FLAGS_ALERTABLE = 1 << 0,
+} MonoSemFlags;
+
+typedef enum {
+ MONO_SEM_TIMEDWAIT_RET_SUCCESS = 0,
+ MONO_SEM_TIMEDWAIT_RET_ALERTED = -1,
+ MONO_SEM_TIMEDWAIT_RET_TIMEDOUT = -2,
+} MonoSemTimedwaitRet;
+
#if defined(USE_MACH_SEMA)
typedef semaphore_t MonoSemType;
+static inline void
+mono_os_sem_init (MonoSemType *sem, int value)
+{
+ kern_return_t res;
+
+ res = semaphore_create (current_task (), sem, SYNC_POLICY_FIFO, value);
+ if (G_UNLIKELY (res != KERN_SUCCESS))
+ g_error ("%s: semaphore_create failed with error %d", __func__, res);
+}
+
+static inline void
+mono_os_sem_destroy (MonoSemType *sem)
+{
+ kern_return_t res;
+
+ res = semaphore_destroy (current_task (), *sem);
+ if (G_UNLIKELY (res != KERN_SUCCESS))
+ g_error ("%s: semaphore_destroy failed with error %d", __func__, res);
+}
+
+static inline int
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
+{
+ kern_return_t res;
+
+retry:
+ res = semaphore_wait (*sem);
+ if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+ g_error ("%s: semaphore_wait failed with error %d", __func__, res);
+
+ if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+ goto retry;
+
+ return res != KERN_SUCCESS ? -1 : 0;
+}
+
+static inline MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
+{
+ kern_return_t res;
+ int resint;
+ mach_timespec_t ts, copy;
+ struct timeval start, current;
+
+ if (timeout_ms == MONO_INFINITE_WAIT)
+ return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
+
+ ts.tv_sec = timeout_ms / 1000;
+ ts.tv_nsec = (timeout_ms % 1000) * 1000000;
+ while (ts.tv_nsec >= NSEC_PER_SEC) {
+ ts.tv_nsec -= NSEC_PER_SEC;
+ ts.tv_sec++;
+ }
+
+ copy = ts;
+ resint = gettimeofday (&start, NULL);
+ if (G_UNLIKELY (resint != 0))
+ g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+retry:
+ res = semaphore_timedwait (*sem, ts);
+ if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED && res != KERN_OPERATION_TIMED_OUT))
+ g_error ("%s: semaphore_timedwait failed with error %d", __func__, res);
+
+ if (res == KERN_ABORTED && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
+ ts = copy;
+
+ resint = gettimeofday (¤t, NULL);
+ if (G_UNLIKELY (resint != 0))
+ g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+ ts.tv_sec -= (current.tv_sec - start.tv_sec);
+ ts.tv_nsec -= (current.tv_usec - start.tv_usec) * 1000;
+ if (ts.tv_nsec < 0) {
+ if (ts.tv_sec <= 0) {
+ ts.tv_nsec = 0;
+ } else {
+ ts.tv_sec--;
+ ts.tv_nsec += NSEC_PER_SEC;
+ }
+ }
+ if (ts.tv_sec < 0) {
+ ts.tv_sec = 0;
+ ts.tv_nsec = 0;
+ }
+
+ goto retry;
+ }
+
+ switch (res) {
+ case KERN_SUCCESS:
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ case KERN_ABORTED:
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ case KERN_OPERATION_TIMED_OUT:
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ default:
+ g_assert_not_reached ();
+ }
+}
+
+static inline void
+mono_os_sem_post (MonoSemType *sem)
+{
+ kern_return_t res;
+
+retry:
+ res = semaphore_signal (*sem);
+ if (G_UNLIKELY (res != KERN_SUCCESS && res != KERN_ABORTED))
+ g_error ("%s: semaphore_signal failed with error %d", __func__, res);
+
+ if (res == KERN_ABORTED)
+ goto retry;
+}
+
#elif !defined(HOST_WIN32) && defined(HAVE_SEMAPHORE_H)
typedef sem_t MonoSemType;
+static inline void
+mono_os_sem_init (MonoSemType *sem, int value)
+{
+ int res;
+
+ res = sem_init (sem, 0, value);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: sem_init failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+}
+
+static inline void
+mono_os_sem_destroy (MonoSemType *sem)
+{
+ int res;
+
+ res = sem_destroy (sem);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: sem_destroy failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+}
+
+static inline int
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
+{
+ int res;
+
+retry:
+ res = sem_wait (sem);
+ if (G_UNLIKELY (res != 0 && errno != EINTR))
+ g_error ("%s: sem_wait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+ if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+ goto retry;
+
+ return res != 0 ? -1 : 0;
+}
+
+static inline MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
+{
+ struct timespec ts, copy;
+ struct timeval t;
+ int res;
+
+ if (timeout_ms == 0) {
+ res = sem_trywait (sem);
+ if (G_UNLIKELY (res != 0 && errno != EINTR && errno != EAGAIN))
+ g_error ("%s: sem_trywait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+ if (res == 0)
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ else if (errno == EINTR)
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ else if (errno == EAGAIN)
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ else
+ g_assert_not_reached ();
+ }
+
+ if (timeout_ms == MONO_INFINITE_WAIT)
+ return (MonoSemTimedwaitRet) mono_os_sem_wait (sem, flags);
+
+ res = gettimeofday (&t, NULL);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+ ts.tv_sec = timeout_ms / 1000 + t.tv_sec;
+ ts.tv_nsec = (timeout_ms % 1000) * 1000000 + t.tv_usec * 1000;
+ while (ts.tv_nsec >= NSEC_PER_SEC) {
+ ts.tv_nsec -= NSEC_PER_SEC;
+ ts.tv_sec++;
+ }
+
+ copy = ts;
+
+retry:
+ res = sem_timedwait (sem, &ts);
+ if (G_UNLIKELY (res != 0 && errno != EINTR && errno != ETIMEDOUT))
+ g_error ("%s: sem_timedwait failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+ if (res != 0 && errno == EINTR && !(flags & MONO_SEM_FLAGS_ALERTABLE)) {
+ ts = copy;
+ goto retry;
+ }
+
+ if (res == 0)
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ else if (errno == EINTR)
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ else if (errno == ETIMEDOUT)
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ else
+ g_assert_not_reached ();
+}
+
+static inline void
+mono_os_sem_post (MonoSemType *sem)
+{
+ int res;
+
+ res = sem_post (sem);
+ if (G_UNLIKELY (res != 0))
+ g_error ("%s: sem_post failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+}
+
#else
typedef HANDLE MonoSemType;
-#endif
+static inline void
+mono_os_sem_init (MonoSemType *sem, int value)
+{
+ *sem = CreateSemaphore (NULL, value, 0x7FFFFFFF, NULL);
+ if (G_UNLIKELY (*sem == NULL))
+ g_error ("%s: CreateSemaphore failed with error %d", __func__, GetLastError ());
+}
-typedef enum {
- MONO_SEM_FLAGS_NONE = 0,
- MONO_SEM_FLAGS_ALERTABLE = 1 << 0,
-} MonoSemFlags;
+static inline void
+mono_os_sem_destroy (MonoSemType *sem)
+{
+ BOOL res;
-typedef enum {
- MONO_SEM_TIMEDWAIT_RET_SUCCESS = 0,
- MONO_SEM_TIMEDWAIT_RET_ALERTED = -1,
- MONO_SEM_TIMEDWAIT_RET_TIMEDOUT = -2,
-} MonoSemTimedwaitRet;
+ res = CloseHandle (*sem);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: CloseHandle failed with error %d", __func__, GetLastError ());
+}
-/**
- * mono_os_sem_init:
- */
-void
-mono_os_sem_init (MonoSemType *sem, gint value);
+static inline MonoSemTimedwaitRet
+mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags)
+{
+ BOOL res;
-/**
- * mono_os_sem_destroy:
- */
-void
-mono_os_sem_destroy (MonoSemType *sem);
+retry:
+ res = WaitForSingleObjectEx (*sem, timeout_ms, flags & MONO_SEM_FLAGS_ALERTABLE);
+ if (G_UNLIKELY (res != WAIT_OBJECT_0 && res != WAIT_IO_COMPLETION && res != WAIT_TIMEOUT))
+ g_error ("%s: WaitForSingleObjectEx failed with error %d", __func__, GetLastError ());
-/**
- * mono_os_sem_wait:
- *
- * @returns:
- * - 0: success
- * - -1: the wait was interrupted
- */
-gint
-mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags);
+ if (res == WAIT_IO_COMPLETION && !(flags & MONO_SEM_FLAGS_ALERTABLE))
+ goto retry;
-/**
- * mono_os_sem_timedwait:
- *
- * @returns: see MonoSemTimedwaitRet
- */
-MonoSemTimedwaitRet
-mono_os_sem_timedwait (MonoSemType *sem, guint32 timeout_ms, MonoSemFlags flags);
+ switch (res) {
+ case WAIT_OBJECT_0:
+ return MONO_SEM_TIMEDWAIT_RET_SUCCESS;
+ case WAIT_IO_COMPLETION:
+ return MONO_SEM_TIMEDWAIT_RET_ALERTED;
+ case WAIT_TIMEOUT:
+ return MONO_SEM_TIMEDWAIT_RET_TIMEDOUT;
+ default:
+ g_assert_not_reached ();
+ }
+}
-/**
- * mono_os_sem_post:
- */
-void
-mono_os_sem_post (MonoSemType *sem);
+static inline int
+mono_os_sem_wait (MonoSemType *sem, MonoSemFlags flags)
+{
+ return mono_os_sem_timedwait (sem, INFINITE, flags) != 0 ? -1 : 0;
+}
+
+static inline void
+mono_os_sem_post (MonoSemType *sem)
+{
+ BOOL res;
+
+ res = ReleaseSemaphore (*sem, 1, NULL);
+ if (G_UNLIKELY (res == 0))
+ g_error ("%s: ReleaseSemaphore failed with error %d", __func__, GetLastError ());
+}
+
+#endif
G_END_DECLS