X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Futils%2Fmono-os-mutex.h;h=cd33375894c1db0f95fdf61ae054c50043a18f2d;hb=33e80a5291986e98251198c13086f91fcc2a40e2;hp=8f7f70307c7072e7fd47ecd46c9fd94430aa92dd;hpb=0fa33056a6742b2ee02604596b355d661d9bdc41;p=mono.git diff --git a/mono/utils/mono-os-mutex.h b/mono/utils/mono-os-mutex.h index 8f7f70307c7..cd33375894c 100644 --- a/mono/utils/mono-os-mutex.h +++ b/mono/utils/mono-os-mutex.h @@ -33,81 +33,119 @@ G_BEGIN_DECLS +#ifndef MONO_INFINITE_WAIT +#define MONO_INFINITE_WAIT ((guint32) 0xFFFFFFFF) +#endif + + #if !defined(HOST_WIN32) typedef pthread_mutex_t mono_mutex_t; typedef pthread_cond_t mono_cond_t; -static inline int +static inline void mono_os_mutex_init (mono_mutex_t *mutex) { - return pthread_mutex_init (mutex, NULL); + 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 int +static inline void mono_os_mutex_init_recursive (mono_mutex_t *mutex) { int res; pthread_mutexattr_t attr; - pthread_mutexattr_init (&attr); - pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE); + 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); - pthread_mutexattr_destroy (&attr); + if (G_UNLIKELY (res != 0)) + g_error ("%s: pthread_mutex_init failed with \"%s\" (%d)", __func__, g_strerror (res), res); - return 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 +static inline void mono_os_mutex_destroy (mono_mutex_t *mutex) { - return pthread_mutex_destroy (mutex); + int res; + + res = pthread_mutex_destroy (mutex); + if (G_UNLIKELY (res != 0)) + g_error ("%s: pthread_mutex_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res); } -static inline int +static inline void mono_os_mutex_lock (mono_mutex_t *mutex) { int res; res = pthread_mutex_lock (mutex); - g_assert (res != EINVAL); - - return res; + 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) { - return pthread_mutex_trylock (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 int +static inline void mono_os_mutex_unlock (mono_mutex_t *mutex) { - return pthread_mutex_unlock (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 int +static inline void mono_os_cond_init (mono_cond_t *cond) { - return pthread_cond_init (cond, NULL); + 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 +static inline void mono_os_cond_destroy (mono_cond_t *cond) { - return pthread_cond_destroy (cond); + int res; + + res = pthread_cond_destroy (cond); + if (G_UNLIKELY (res != 0)) + g_error ("%s: pthread_cond_destroy failed with \"%s\" (%d)", __func__, g_strerror (res), res); } -static inline int +static inline void mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex) { int res; res = pthread_cond_wait (cond, mutex); - g_assert (res != EINVAL); - - return res; + if (G_UNLIKELY (res != 0)) + g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res); } static inline int @@ -118,12 +156,17 @@ mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ gint64 usecs; int res; - if (timeout_ms == (guint32) 0xFFFFFFFF) - return mono_os_cond_wait (cond, mutex); + if (timeout_ms == MONO_INFINITE_WAIT) { + mono_os_cond_wait (cond, mutex); + return 0; + } /* ms = 10^-3, us = 10^-6, ns = 10^-9 */ - gettimeofday (&tv, NULL); + res = gettimeofday (&tv, NULL); + if (G_UNLIKELY (res != 0)) + g_error ("%s: gettimeofday 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) { @@ -134,21 +177,30 @@ mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ ts.tv_nsec = usecs * 1000; res = pthread_cond_timedwait (cond, mutex, &ts); - g_assert (res != EINVAL); + if (G_UNLIKELY (res != 0 && res != ETIMEDOUT)) + g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d)", __func__, g_strerror (res), res); - return res; + return res != 0 ? -1 : 0; } -static inline int +static inline void mono_os_cond_signal (mono_cond_t *cond) { - return pthread_cond_signal (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 int +static inline void mono_os_cond_broadcast (mono_cond_t *cond) { - return pthread_cond_broadcast (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 @@ -210,90 +262,104 @@ WINBASEAPI WINBOOL WINAPI InitOnceBeginInitialize(LPINIT_ONCE lpInitOnce, DWORD 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; -static inline int +static inline void mono_os_mutex_init (mono_mutex_t *mutex) { - InitializeCriticalSection (mutex); - return 0; + 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 ()); } -static inline int +static inline void mono_os_mutex_init_recursive (mono_mutex_t *mutex) { - InitializeCriticalSection (mutex); - return 0; + 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 ()); } -static inline int +static inline void mono_os_mutex_destroy (mono_mutex_t *mutex) { DeleteCriticalSection (mutex); - return 0; } -static inline int +static inline void mono_os_mutex_lock (mono_mutex_t *mutex) { EnterCriticalSection (mutex); - return 0; } static inline int mono_os_mutex_trylock (mono_mutex_t *mutex) { - return TryEnterCriticalSection (mutex) != 0 ? 0 : 1; + return TryEnterCriticalSection (mutex) == 0 ? -1 : 0; } -static inline int +static inline void mono_os_mutex_unlock (mono_mutex_t *mutex) { LeaveCriticalSection (mutex); - return 0; } -static inline int +static inline void mono_os_cond_init (mono_cond_t *cond) { InitializeConditionVariable (cond); - return 0; } -static inline int +static inline void mono_os_cond_destroy (mono_cond_t *cond) { /* Beauty of win32 API: do not destroy it */ - return 0; } -static inline int +static inline void mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex) { - return SleepConditionVariableCS (cond, mutex, INFINITE) ? 0 : 1; + BOOL res; + + res = SleepConditionVariableCS (cond, mutex, INFINITE); + if (G_UNLIKELY (res == 0)) + g_error ("%s: SleepConditionVariableCS failed with error %d", __func__, GetLastError ()); } static inline int mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms) { - return SleepConditionVariableCS (cond, mutex, timeout_ms) ? 0 : 1; + 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 int +static inline void mono_os_cond_signal (mono_cond_t *cond) { WakeConditionVariable (cond); - return 0; } -static inline int +static inline void mono_os_cond_broadcast (mono_cond_t *cond) { WakeAllConditionVariable (cond); - return 0; } #endif