diff options
author | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-05-09 14:24:24 -0400 |
---|---|---|
committer | Søren Sandmann Pedersen <ssp@redhat.com> | 2010-05-09 14:24:24 -0400 |
commit | 164fe215f2c904cf74537caf9d76b7f9ce2667ec (patch) | |
tree | 31e4c2476e8fdda6d74767dfec51e857f9af62ba | |
parent | e1594f204d3a3c2d2083793c8830f0ebf390ed66 (diff) | |
parent | 5158d6740c8e2643611a623a0caa649f4b0bc5bd (diff) |
Merge branch 'for-master'
-rw-r--r-- | configure.ac | 3 | ||||
-rw-r--r-- | pixman/pixman-compiler.h | 65 |
2 files changed, 68 insertions, 0 deletions
diff --git a/configure.ac b/configure.ac index aabe7210..c9d0c662 100644 --- a/configure.ac +++ b/configure.ac @@ -524,6 +524,9 @@ support_for__thread=no AC_MSG_CHECKING(for __thread) AC_COMPILE_IFELSE([ +#ifdef __MINGW32__ +#error MinGW has broken __thread support +#endif __thread int x ; int main () { return 0; } ], support_for__thread=yes) diff --git a/pixman/pixman-compiler.h b/pixman/pixman-compiler.h index c4107173..f0f9d91f 100644 --- a/pixman/pixman-compiler.h +++ b/pixman/pixman-compiler.h @@ -84,6 +84,71 @@ # define PIXMAN_GET_THREAD_LOCAL(name) \ (&name) +#elif defined(__MINGW32__) && !defined(__WIN64) + +/* We can't include <windows.h> as it causes carious clashes with + * identifiers in pixman, sigh. So just declare the functions we need + * here. + */ +extern __stdcall long InterlockedCompareExchange(long volatile *, long, long); +#define InterlockedCompareExchangePointer(d,e,c) \ + (void *)InterlockedCompareExchange((long volatile *)(d),(long)(e),(long)(c)) +extern __stdcall int TlsAlloc (void); +extern __stdcall void *TlsGetValue (unsigned); +extern __stdcall int TlsSetValue (unsigned, void *); +extern __stdcall void *CreateMutexA(void *, int, char *); +extern __stdcall int CloseHandle(void *); +extern __stdcall unsigned WaitForSingleObject (void *, unsigned); +extern __stdcall int ReleaseMutex (void *); + +# 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 * \ + tls_ ## name ## _alloc (void) \ + { \ + type *value = calloc (1, sizeof (type)); \ + if (value) \ + TlsSetValue (tls_ ## name ## _index, value); \ + return value; \ + } \ + \ + static force_inline type * \ + tls_ ## name ## _get (void) \ + { \ + 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); \ + } \ + if (tls_ ## name ## _index == 0xFFFFFFFF) \ + return NULL; \ + value = TlsGetValue (tls_ ## name ## _index); \ + if (!value) \ + value = tls_ ## name ## _alloc (); \ + return value; \ + } + +# define PIXMAN_GET_THREAD_LOCAL(name) \ + tls_ ## name ## _get () + #elif defined(_MSC_VER) # define PIXMAN_DEFINE_THREAD_LOCAL(type, name) \ |