Hi everyone,<div><br></div><div>It turned out that Windows XP does&#39;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.</div>
<div><br></div><div>Thanks a lot!</div><div><br></div><div>Regards,</div><div>Gang</div><div><br></div><div>---</div><div><br></div><div><div>Index: pixman/pixman-win32-tls.c</div><div>===================================================================</div>
<div>--- pixman/pixman-win32-tls.c<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 0)</div><div>+++ pixman/pixman-win32-tls.c<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 235)</div>
<div>@@ -0,0 +1,85 @@</div><div>+#if defined(__MINGW32__) || (defined(_MSC_VER) &amp;&amp; _WIN32_WINNT &lt; 0x0600)</div><div>+</div><div>+#include &quot;pixman-win32-tls.h&quot;</div><div>+</div><div>+#include &lt;stdlib.h&gt;</div>
<div>+#include &lt;windows.h&gt;</div><div>+</div><div>+#include &quot;pixman-compiler.h&quot;</div><div>+#include &quot;pixman-win32-tls-private.h&quot;</div><div>+</div><div>+struct tls_entry {</div><div>+  DWORD *index;</div>
<div>+  volatile int *initialized;</div><div>+  struct tls_entry *next;</div><div>+};</div><div>+</div><div>+static struct tls_entry *tls_entries = NULL;</div><div>+static HANDLE win32_tls_mutex = NULL;</div><div>+</div><div>
+static void tls_register (unsigned *index, volatile int *initialized) {</div><div>+  struct tls_entry *entry = malloc (sizeof(struct tls_entry));</div><div>+  if (entry != NULL) {</div><div>+    entry-&gt;index = index;</div>
<div>+    entry-&gt;initialized = initialized;</div><div>+    entry-&gt;next = tls_entries;</div><div>+    tls_entries = entry;</div><div>+  }</div><div>+}</div><div>+</div><div>+void _pixman_win32_tls_create (unsigned *index, volatile int *initialized) {</div>
<div>+  if (win32_tls_mutex == NULL) {</div><div>+    HANDLE mutex = CreateMutex (NULL, 0, NULL);</div><div>+    if (InterlockedCompareExchangePointer (&amp;win32_tls_mutex, mutex, NULL)</div><div>+        != NULL) {</div>
<div>+      CloseHandle (mutex);</div><div>+    }</div><div>+  }</div><div>+  WaitForSingleObject (win32_tls_mutex, INFINITE);</div><div>+  if (!(*initialized)) {</div><div>+    *index = TlsAlloc ();</div><div>+    tls_register (index, initialized);</div>
<div>+    *initialized = 1;</div><div>+  }</div><div>+  ReleaseMutex (win32_tls_mutex);</div><div>+}</div><div>+</div><div>+PIXMAN_EXPORT void pixman_win32_tls_shutdown_thread (void) {</div><div>+  struct tls_entry *entry = tls_entries;</div>
<div>+  while (entry != NULL) {</div><div>+    struct tls_entry *next = entry-&gt;next;</div><div>+    DWORD index = *entry-&gt;index;</div><div>+    void *data = TlsGetValue (index);</div><div>+    if (data != NULL) {</div>
<div>+      TlsSetValue (index, NULL);</div><div>+      free (data);</div><div>+    }</div><div>+    entry = next;</div><div>+  }</div><div>+}</div><div>+</div><div>+PIXMAN_EXPORT void pixman_win32_tls_shutdown (void) {</div>
<div>+  struct tls_entry *entry = tls_entries;</div><div>+  pixman_win32_tls_shutdown_thread ();</div><div>+  while (entry != NULL) {</div><div>+    struct tls_entry *next = entry-&gt;next;</div><div>+    DWORD index = *entry-&gt;index;</div>
<div>+    TlsFree (index);</div><div>+    entry-&gt;initialized = 0;</div><div>+    free (entry);</div><div>+    entry = next;</div><div>+  }</div><div>+  tls_entries = NULL;</div><div>+  CloseHandle (win32_tls_mutex);</div>
<div>+  win32_tls_mutex = NULL;</div><div>+}</div><div>+</div><div>+#elif defined(_MSC_VER)</div><div>+</div><div>+PIXMAN_EXPORT void pixman_win32_tls_shutdown_thread (void) {</div><div>+}</div><div>+</div><div>+PIXMAN_EXPORT void pixman_win32_tls_shutdown (void) {</div>
<div>+}</div><div>+</div><div>+#endif</div><div>Index: pixman/pixman-win32-tls.h</div><div>===================================================================</div><div>--- pixman/pixman-win32-tls.h<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 0)</div>
<div>+++ pixman/pixman-win32-tls.h<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 235)</div><div>@@ -0,0 +1,19 @@</div><div>+#ifndef PIXMAN_WIN32_TLS_H</div><div>+#define PIXMAN_WIN32_TLS_H</div><div>
+</div><div>+#if defined(__MINGW32__) || defined(_MSC_VER)</div><div>+</div><div>+#ifdef  __cplusplus</div><div>+extern &quot;C&quot; {</div><div>+#endif</div><div>+</div><div>+void pixman_win32_tls_shutdown_thread (void);</div>
<div>+void pixman_win32_tls_shutdown (void);</div><div>+</div><div>+#ifdef  __cplusplus</div><div>+}</div><div>+#endif</div><div>+</div><div>+#endif</div><div>+</div><div>+#endif</div><div>Index: pixman/pixman-win32-tls-private.h</div>
<div>===================================================================</div><div>--- pixman/pixman-win32-tls-private.h<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 0)</div><div>+++ pixman/pixman-win32-tls-private.h<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 235)</div>
<div>@@ -0,0 +1,10 @@</div><div>+#ifndef PIXMAN_WIN32_TLS_PRIVATE_H</div><div>+#define PIXMAN_WIN32_TLS_PRIVATE_H</div><div>+</div><div>+#if defined(__MINGW32__) || (defined(_MSC_VER) &amp;&amp; _WIN32_WINNT &lt; 0x0600)</div>
<div>+</div><div>+void _pixman_win32_tls_create (unsigned *index, volatile int *initialized);</div><div>+</div><div>+#endif</div><div>+</div><div>+#endif</div><div>Index: pixman/pixman-compiler.h</div><div>===================================================================</div>
<div>--- pixman/pixman-compiler.h<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 234)</div><div>+++ pixman/pixman-compiler.h<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 235)</div>
<div>@@ -89,14 +89,13 @@</div><div> #   define PIXMAN_GET_THREAD_LOCAL(name)<span class="Apple-tab-span" style="white-space:pre">                                </span>\</div><div>     (&amp;name)</div><div> </div><div>-#elif defined(__MINGW32__)</div>
<div>+#elif defined(__MINGW32__) || (defined(_MSC_VER) &amp;&amp; _WIN32_WINNT &lt; 0x0600)</div><div> </div><div>-#   define _NO_W32_PSEUDO_MODIFIERS</div><div>-#   include &lt;windows.h&gt;</div><div>+    /* MinGW and Windows XP doesn&#39;t support __declspec(thread) */</div>
<div>+#   include &quot;pixman-win32-tls-private.h&quot;</div><div> </div><div> #   define PIXMAN_DEFINE_THREAD_LOCAL(type, name)<span class="Apple-tab-span" style="white-space:pre">                        </span>\</div><div>     static volatile int tls_ ## name ## _initialized = 0;<span class="Apple-tab-span" style="white-space:pre">                </span>\</div>
<div>-    static void *tls_ ## name ## _mutex = NULL;<span class="Apple-tab-span" style="white-space:pre">                                </span>\</div><div>     static unsigned tls_ ## name ## _index;<span class="Apple-tab-span" style="white-space:pre">                                </span>\</div>
<div> <span class="Apple-tab-span" style="white-space:pre">                                                                        </span>\</div><div>     static type *<span class="Apple-tab-span" style="white-space:pre">                                                        </span>\</div><div>@@ -114,22 +113,8 @@</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>type *value;<span class="Apple-tab-span" style="white-space:pre">                                                        </span>\</div>
<div> <span class="Apple-tab-span" style="white-space:pre">        </span>if (!tls_ ## name ## _initialized)<span class="Apple-tab-span" style="white-space:pre">                                </span>\</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>{<span class="Apple-tab-span" style="white-space:pre">                                                                </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    if (!tls_ ## name ## _mutex)<span class="Apple-tab-span" style="white-space:pre">                                </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    {<span class="Apple-tab-span" style="white-space:pre">                                                                </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">                </span>void *mutex = CreateMutexA (NULL, 0, NULL);<span class="Apple-tab-span" style="white-space:pre">                </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">                </span>if (InterlockedCompareExchangePointer (<span class="Apple-tab-span" style="white-space:pre">                        </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">                        </span>&amp;tls_ ## name ## _mutex, mutex, NULL) != NULL)<span class="Apple-tab-span" style="white-space:pre">        </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">                </span>{<span class="Apple-tab-span" style="white-space:pre">                                                        </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">                </span>    CloseHandle (mutex);<span class="Apple-tab-span" style="white-space:pre">                                </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">                </span>}<span class="Apple-tab-span" style="white-space:pre">                                                        </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    }<span class="Apple-tab-span" style="white-space:pre">                                                                </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    WaitForSingleObject (tls_ ## name ## _mutex, 0xFFFFFFFF);<span class="Apple-tab-span" style="white-space:pre">        </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    if (!tls_ ## name ## _initialized)<span class="Apple-tab-span" style="white-space:pre">                                </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    {<span class="Apple-tab-span" style="white-space:pre">                                                                </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">                </span>tls_ ## name ## _index = TlsAlloc ();<span class="Apple-tab-span" style="white-space:pre">                        </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">                </span>tls_ ## name ## _initialized = 1;<span class="Apple-tab-span" style="white-space:pre">                        </span>\</div>
<div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    }<span class="Apple-tab-span" style="white-space:pre">                                                                </span>\</div><div>-<span class="Apple-tab-span" style="white-space:pre">        </span>    ReleaseMutex (tls_ ## name ## _mutex);<span class="Apple-tab-span" style="white-space:pre">                        </span>\</div>
<div>+<span class="Apple-tab-span" style="white-space:pre">        </span>    _pixman_win32_tls_create (&amp;tls_ ## name ## _index,<span class="Apple-tab-span" style="white-space:pre">                </span>\</div><div>+<span class="Apple-tab-span" style="white-space:pre">                                </span>      &amp;tls_ ## name ## _initialized);<span class="Apple-tab-span" style="white-space:pre">        </span>\</div>
<div> <span class="Apple-tab-span" style="white-space:pre">        </span>}<span class="Apple-tab-span" style="white-space:pre">                                                                </span>\</div><div> <span class="Apple-tab-span" style="white-space:pre">        </span>if (tls_ ## name ## _index == 0xFFFFFFFF)<span class="Apple-tab-span" style="white-space:pre">                        </span>\</div>
<div> <span class="Apple-tab-span" style="white-space:pre">        </span>    return NULL;<span class="Apple-tab-span" style="white-space:pre">                                                </span>\</div><div>Index: pixman/pixman.c</div><div>===================================================================</div>
<div>--- pixman/pixman.c<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 234)</div><div>+++ pixman/pixman.c<span class="Apple-tab-span" style="white-space:pre">        </span>(revision 235)</div><div>@@ -26,6 +26,10 @@</div>
<div> #ifdef HAVE_CONFIG_H</div><div> #include &lt;config.h&gt;</div><div> #endif</div><div>+#if defined(__MINGW32__) || (defined(_MSC_VER) &amp;&amp; _WIN32_WINNT &lt; 0x0600)</div><div>+#include &lt;windows.h&gt;</div><div>
+#endif</div><div>+</div><div> #include &quot;pixman-private.h&quot;</div><div> </div><div> #include &lt;stdlib.h&gt;</div></div>