+ {
+ if (InterlockedDecrement (&__mutex->counter) >= 0)
+ return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
+ }
+ return 0;
+}
+
+static inline void
+__gthread_recursive_mutex_init_function (__gthread_recursive_mutex_t *__mutex)
+{
+ __mutex->counter = -1;
+ __mutex->depth = 0;
+ __mutex->owner = 0;
+ __mutex->sema = CreateSemaphore (NULL, 0, 65535, NULL);
+}
+
+static inline int
+__gthread_recursive_mutex_lock (__gthread_recursive_mutex_t *__mutex)
+{
+ if (__gthread_active_p ())
+ {
+ DWORD __me = GetCurrentThreadId();
+ if (InterlockedIncrement (&__mutex->counter) == 0)
+ {
+ __mutex->depth = 1;
+ __mutex->owner = __me;
+ }
+ else if (__mutex->owner == __me)
+ {
+ InterlockedDecrement (&__mutex->counter);
+ ++(__mutex->depth);
+ }
+ else if (WaitForSingleObject (__mutex->sema, INFINITE) == WAIT_OBJECT_0)
+ {
+ __mutex->depth = 1;
+ __mutex->owner = __me;
+ }
+ else
+ {
+ /* WaitForSingleObject returns WAIT_FAILED, and we can only do
+ some best-effort cleanup here. */
+ InterlockedDecrement (&__mutex->counter);
+ return 1;
+ }
+ }
+ return 0;
+}
+
+static inline int
+__gthread_recursive_mutex_trylock (__gthread_recursive_mutex_t *__mutex)
+{
+ if (__gthread_active_p ())
+ {
+ DWORD __me = GetCurrentThreadId();
+ if (__GTHR_W32_InterlockedCompareExchange (&__mutex->counter, 0, -1) < 0)
+ {
+ __mutex->depth = 1;
+ __mutex->owner = __me;
+ }
+ else if (__mutex->owner == __me)
+ ++(__mutex->depth);
+ else
+ return 1;
+ }
+ return 0;
+}
+
+static inline int
+__gthread_recursive_mutex_unlock (__gthread_recursive_mutex_t *__mutex)
+{
+ if (__gthread_active_p ())
+ {
+ --(__mutex->depth);
+ if (__mutex->depth == 0)
+ {
+ __mutex->owner = 0;
+
+ if (InterlockedDecrement (&__mutex->counter) >= 0)
+ return ReleaseSemaphore (__mutex->sema, 1, NULL) ? 0 : 1;
+ }
+ }
+ return 0;