[Pixman] [PATCH] Adding TLS for Windows XP
Gang Ji
gangji at google.com
Mon Mar 28 11:01:57 PDT 2011
Hi everyone,
It turned out that Windows XP does't support __declspec(thread). In order
to make a multi-thread safe app using pixman, we tried to add TLS for
Windows XP. We have added using TLS primitives and tried to avoid memory
leak during cleaning up.
Thanks a lot!
Regards,
Gang
---
Index: pixman/pixman-win32-tls.c
===================================================================
--- pixman/pixman-win32-tls.c (revision 0)
+++ pixman/pixman-win32-tls.c (revision 235)
@@ -0,0 +1,85 @@
+#if defined(__MINGW32__) || (defined(_MSC_VER) && _WIN32_WINNT < 0x0600)
+
+#include "pixman-win32-tls.h"
+
+#include <stdlib.h>
+#include <windows.h>
+
+#include "pixman-compiler.h"
+#include "pixman-win32-tls-private.h"
+
+struct tls_entry {
+ DWORD *index;
+ volatile int *initialized;
+ struct tls_entry *next;
+};
+
+static struct tls_entry *tls_entries = NULL;
+static HANDLE win32_tls_mutex = NULL;
+
+static void tls_register (unsigned *index, volatile int *initialized) {
+ struct tls_entry *entry = malloc (sizeof(struct tls_entry));
+ if (entry != NULL) {
+ entry->index = index;
+ entry->initialized = initialized;
+ entry->next = tls_entries;
+ tls_entries = entry;
+ }
+}
+
+void _pixman_win32_tls_create (unsigned *index, volatile int *initialized)
{
+ if (win32_tls_mutex == NULL) {
+ HANDLE mutex = CreateMutex (NULL, 0, NULL);
+ if (InterlockedCompareExchangePointer (&win32_tls_mutex, mutex, NULL)
+ != NULL) {
+ CloseHandle (mutex);
+ }
+ }
+ WaitForSingleObject (win32_tls_mutex, INFINITE);
+ if (!(*initialized)) {
+ *index = TlsAlloc ();
+ tls_register (index, initialized);
+ *initialized = 1;
+ }
+ ReleaseMutex (win32_tls_mutex);
+}
+
+PIXMAN_EXPORT void pixman_win32_tls_shutdown_thread (void) {
+ struct tls_entry *entry = tls_entries;
+ while (entry != NULL) {
+ struct tls_entry *next = entry->next;
+ DWORD index = *entry->index;
+ void *data = TlsGetValue (index);
+ if (data != NULL) {
+ TlsSetValue (index, NULL);
+ free (data);
+ }
+ entry = next;
+ }
+}
+
+PIXMAN_EXPORT void pixman_win32_tls_shutdown (void) {
+ struct tls_entry *entry = tls_entries;
+ pixman_win32_tls_shutdown_thread ();
+ while (entry != NULL) {
+ struct tls_entry *next = entry->next;
+ DWORD index = *entry->index;
+ TlsFree (index);
+ entry->initialized = 0;
+ free (entry);
+ entry = next;
+ }
+ tls_entries = NULL;
+ CloseHandle (win32_tls_mutex);
+ win32_tls_mutex = NULL;
+}
+
+#elif defined(_MSC_VER)
+
+PIXMAN_EXPORT void pixman_win32_tls_shutdown_thread (void) {
+}
+
+PIXMAN_EXPORT void pixman_win32_tls_shutdown (void) {
+}
+
+#endif
Index: pixman/pixman-win32-tls.h
===================================================================
--- pixman/pixman-win32-tls.h (revision 0)
+++ pixman/pixman-win32-tls.h (revision 235)
@@ -0,0 +1,19 @@
+#ifndef PIXMAN_WIN32_TLS_H
+#define PIXMAN_WIN32_TLS_H
+
+#if defined(__MINGW32__) || defined(_MSC_VER)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void pixman_win32_tls_shutdown_thread (void);
+void pixman_win32_tls_shutdown (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
+
+#endif
Index: pixman/pixman-win32-tls-private.h
===================================================================
--- pixman/pixman-win32-tls-private.h (revision 0)
+++ pixman/pixman-win32-tls-private.h (revision 235)
@@ -0,0 +1,10 @@
+#ifndef PIXMAN_WIN32_TLS_PRIVATE_H
+#define PIXMAN_WIN32_TLS_PRIVATE_H
+
+#if defined(__MINGW32__) || (defined(_MSC_VER) && _WIN32_WINNT < 0x0600)
+
+void _pixman_win32_tls_create (unsigned *index, volatile int *initialized);
+
+#endif
+
+#endif
Index: pixman/pixman-compiler.h
===================================================================
--- pixman/pixman-compiler.h (revision 234)
+++ pixman/pixman-compiler.h (revision 235)
@@ -89,14 +89,13 @@
# define PIXMAN_GET_THREAD_LOCAL(name) \
(&name)
-#elif defined(__MINGW32__)
+#elif defined(__MINGW32__) || (defined(_MSC_VER) && _WIN32_WINNT < 0x0600)
-# define _NO_W32_PSEUDO_MODIFIERS
-# include <windows.h>
+ /* MinGW and Windows XP doesn't support __declspec(thread) */
+# include "pixman-win32-tls-private.h"
# define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \
static volatile int tls_ ## name ## _initialized = 0; \
- static void *tls_ ## name ## _mutex = NULL; \
static unsigned tls_ ## name ## _index; \
\
static type * \
@@ -114,22 +113,8 @@
type *value; \
if (!tls_ ## name ## _initialized) \
{ \
- if (!tls_ ## name ## _mutex) \
- { \
- void *mutex = CreateMutexA (NULL, 0, NULL); \
- if (InterlockedCompareExchangePointer ( \
- &tls_ ## name ## _mutex, mutex, NULL) != NULL) \
- { \
- CloseHandle (mutex); \
- } \
- } \
- WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF); \
- if (!tls_ ## name ## _initialized) \
- { \
- tls_ ## name ## _index = TlsAlloc (); \
- tls_ ## name ## _initialized = 1; \
- } \
- ReleaseMutex (tls_ ## name ## _mutex); \
+ _pixman_win32_tls_create (&tls_ ## name ## _index, \
+ &tls_ ## name ## _initialized); \
} \
if (tls_ ## name ## _index == 0xFFFFFFFF) \
return NULL; \
Index: pixman/pixman.c
===================================================================
--- pixman/pixman.c (revision 234)
+++ pixman/pixman.c (revision 235)
@@ -26,6 +26,10 @@
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
+#if defined(__MINGW32__) || (defined(_MSC_VER) && _WIN32_WINNT < 0x0600)
+#include <windows.h>
+#endif
+
#include "pixman-private.h"
#include <stdlib.h>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.freedesktop.org/archives/pixman/attachments/20110328/c266a166/attachment.htm>
More information about the Pixman
mailing list