/* * Copyright © 2024 Nick Bowler * * Helpers for hosts using POSIX threading (pthreads) API. * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . */ #include #if USE_POSIX_THREADS_WEAK # pragma weak pthread_key_create # pragma weak pthread_getspecific # pragma weak pthread_setspecific #endif static struct { union { pthread_key_t mt; #if USE_POSIX_THREADS_WEAK void *st; #endif } u; #if USE_POSIX_THREADS_WEAK signed char valid; #else bool valid; #endif } tls_key; #define tls_key_valid (tls_key.valid != 0) static void tls_key_init(void) { if (pthread_in_use()) tls_key.valid = !pthread_key_create(&tls_key.u.mt, free); else tls_key.valid = -1; } static void *tls_get(void) { #if USE_POSIX_THREADS_WEAK if (tls_key.valid < 0) return tls_key.u.st; #endif return pthread_getspecific(tls_key.u.mt); } static int tls_set(void *p) { #if USE_POSIX_THREADS_WEAK if (tls_key.valid < 0) return (tls_key.u.st = p, 1); #endif return !pthread_setspecific(tls_key.u.mt, p); }