+/* {{{1 GRecMutex */
+
+static CRITICAL_SECTION *
+g_rec_mutex_impl_new (void)
+{
+ CRITICAL_SECTION *cs;
+
+ cs = g_slice_new (CRITICAL_SECTION);
+ InitializeCriticalSection (cs);
+
+ return cs;
+}
+
+static void
+g_rec_mutex_impl_free (CRITICAL_SECTION *cs)
+{
+ DeleteCriticalSection (cs);
+ g_slice_free (CRITICAL_SECTION, cs);
+}
+
+static CRITICAL_SECTION *
+g_rec_mutex_get_impl (GRecMutex *mutex)
+{
+ CRITICAL_SECTION *impl = mutex->p;
+
+ if G_UNLIKELY (mutex->p == NULL)
+ {
+ impl = g_rec_mutex_impl_new ();
+ if (InterlockedCompareExchangePointer (&mutex->p, impl, NULL) != NULL)
+ g_rec_mutex_impl_free (impl);
+ impl = mutex->p;
+ }
+
+ return impl;
+}
+
+void
+g_rec_mutex_init (GRecMutex *mutex)
+{
+ mutex->p = g_rec_mutex_impl_new ();
+}
+
+void
+g_rec_mutex_clear (GRecMutex *mutex)
+{
+ g_rec_mutex_impl_free (mutex->p);
+}
+
+void
+g_rec_mutex_lock (GRecMutex *mutex)
+{
+ EnterCriticalSection (g_rec_mutex_get_impl (mutex));
+}
+
+void
+g_rec_mutex_unlock (GRecMutex *mutex)
+{
+ LeaveCriticalSection (mutex->p);
+}
+
+gboolean
+g_rec_mutex_trylock (GRecMutex *mutex)
+{
+ return TryEnterCriticalSection (g_rec_mutex_get_impl (mutex));
+}
+