- waiter = malloc (sizeof (GThreadXpWaiter));
- if (waiter == NULL)
- g_thread_abort (GetLastError (), "malloc");
- waiter->event = CreateEvent (0, FALSE, FALSE, NULL);
- if (waiter->event == NULL)
- g_thread_abort (GetLastError (), "CreateEvent");
-
- TlsSetValue (g_thread_xp_waiter_tls, waiter);
- }
-
- return waiter;
-}
-
-static void __stdcall
-g_thread_xp_CallThisOnThreadExit (void)
-{
- GThreadXpWaiter *waiter;
-
- waiter = TlsGetValue (g_thread_xp_waiter_tls);
-
- if (waiter != NULL)
- {
- TlsSetValue (g_thread_xp_waiter_tls, NULL);
- CloseHandle (waiter->event);
- free (waiter);
- }
-}
-
-/* {{{2 SRWLock emulation */
-typedef struct
-{
- CRITICAL_SECTION writer_lock;
- gboolean ever_shared; /* protected by writer_lock */
- gboolean writer_locked; /* protected by writer_lock */
-
- /* below is only ever touched if ever_shared becomes true */
- CRITICAL_SECTION atomicity;
- GThreadXpWaiter *queued_writer; /* protected by atomicity lock */
- gint num_readers; /* protected by atomicity lock */
-} GThreadSRWLock;
-
-static void __stdcall
-g_thread_xp_InitializeSRWLock (gpointer mutex)
-{
- *(GThreadSRWLock * volatile *) mutex = NULL;
-}
-
-static void __stdcall
-g_thread_xp_DeleteSRWLock (gpointer mutex)
-{
- GThreadSRWLock *lock = *(GThreadSRWLock * volatile *) mutex;
-
- if (lock)
- {
- if (lock->ever_shared)
- DeleteCriticalSection (&lock->atomicity);
-
- DeleteCriticalSection (&lock->writer_lock);
- free (lock);
- }
-}
-
-static GThreadSRWLock * __stdcall
-g_thread_xp_get_srwlock (GThreadSRWLock * volatile *lock)
-{
- GThreadSRWLock *result;
-
- /* It looks like we're missing some barriers here, but this code only
- * ever runs on Windows XP, which in turn only ever runs on hardware
- * with a relatively rigid memory model. The 'volatile' will take
- * care of the compiler.
- */
- result = *lock;
-
- if G_UNLIKELY (result == NULL)
- {
- EnterCriticalSection (&g_thread_xp_lock);
-
- result = malloc (sizeof (GThreadSRWLock));
-
- if (result == NULL)
- g_thread_abort (errno, "malloc");
-
- InitializeCriticalSection (&result->writer_lock);
- result->writer_locked = FALSE;
- result->ever_shared = FALSE;
- *lock = result;
-
- LeaveCriticalSection (&g_thread_xp_lock);