Not sure if I like to keep it. For now, aim for correctness.
#ifndef HB_NO_VISIBILITY
const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+thread_local void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
#endif
void cbdt_callback (const uint8_t* data, unsigned int length,
#ifndef HB_NO_VISIBILITY
const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+thread_local void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
#endif
template <typename Type, int Bytes> struct LEInt;
#ifndef HB_NO_VISIBILITY
const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+thread_local void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
#endif
HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1]
#endif // static_assert
+#ifdef __GNUC__
+#if (__GNUC__ < 4 || (__GNUC__ == 4 && __GNUC_MINOR__ < 8))
+#define thread_local __thread
+#endif
+#else
+#define thread_local
+#endif
+
#endif // __cplusplus < 201103L
#if (defined(__GNUC__) || defined(__clang__)) && defined(__OPTIMIZE__)
/* Global writable pool. Enlarge as necessary. */
+/* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool
+ * for correct operation. It only exist to catch and divert program logic bugs instead of
+ * causing bad memory access. So, races there are not actually introducing incorrectness
+ * in the code. So maybe disable? Has ~12kb binary size overhead to have it. */
#ifdef HB_NO_VISIBILITY
static
#else
extern HB_INTERNAL
#endif
-void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)]
+thread_local void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)]
#ifdef HB_NO_VISIBILITY
= {}
#endif
#if !defined(HB_NO_VISIBILITY) && !defined(HB_SUBSET_BUILTIN)
const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+thread_local void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
#endif
#ifndef HB_NO_VISIBILITY
const void * const _hb_NullPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
-void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
+thread_local void * _hb_CrapPool[HB_NULL_POOL_SIZE / sizeof (void *)] = {};
#endif
int