-/* Storage class specifier for thread-local storage. */
-#undef thread_local
-#if defined _MSC_VER
-/* <https://learn.microsoft.com/en-us/cpp/parallel/thread-local-storage-tls> */
-# define thread_local __declspec(thread)
+/* Thread-local storage.
+ We don't use 'thread_local' here, since on mingw it (or '__thread') pulls in
+ libwinpthread, which we want to avoid. See gl_AVOID_WINPTHREAD. */
+
+struct per_thread
+{
+ /* Set of currently blocked signals. */
+ sigset_t blocked_set /* = 0 */;
+ /* Set of currently blocked and pending signals. */
+ volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;
+};
+
+#if !GNULIB_SIGPROCMASK_SINGLE_THREAD
+
+static glwthread_tls_key_t tls_key; /* TLS key for a 'struct per_thread *' */
+
+static void
+keys_init (void)
+{
+ if (glwthread_tls_key_create (&tls_key, free) != 0)
+ /* Should not happen. */
+ abort ();
+ /* The per-thread initial value is NULL. */
+}
+
+/* Ensure that keys_init is called once only. */
+static glwthread_once_t keys_init_once = GLWTHREAD_ONCE_INIT;
+
+/* Returns the per-thread data belonging to the current thread. */
+static struct per_thread *
+get_per_thread (void)
+{
+ glwthread_once (&keys_init_once, keys_init);
+ struct per_thread *data = glwthread_tls_get (tls_key);
+ if (data == NULL)
+ {
+ data = (struct per_thread *) calloc (1, sizeof (struct per_thread));
+ if (data == NULL)
+ /* Should not happen. */
+ abort ();
+ glwthread_tls_set (tls_key, data);
+ }
+ return data;
+}
+