X-Git-Url: https://code.delx.au/pulseaudio/blobdiff_plain/06211b7c8fd329137ae9003818543912a87d9898..57baff51434924e73fce8043d13a29b2977dc93e:/src/pulsecore/thread.h diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h index ca1fe4da..25eace63 100644 --- a/src/pulsecore/thread.h +++ b/src/pulsecore/thread.h @@ -1,8 +1,6 @@ #ifndef foopulsethreadhfoo #define foopulsethreadhfoo -/* $Id$ */ - /*** This file is part of PulseAudio. @@ -11,7 +9,7 @@ PulseAudio is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as - published by the Free Software Foundation; either version 2 of the + published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. PulseAudio is distributed in the hope that it will be useful, but @@ -26,6 +24,12 @@ ***/ #include +#include +#include + +#ifndef PACKAGE +#error "Please include config.h before including this file!" +#endif typedef struct pa_thread pa_thread; @@ -48,4 +52,62 @@ void pa_tls_free(pa_tls *t); void * pa_tls_get(pa_tls *t); void *pa_tls_set(pa_tls *t, void *userdata); +#define PA_STATIC_TLS_DECLARE(name, free_cb) \ + static struct { \ + pa_once once; \ + pa_tls *tls; \ + } name##_tls = { \ + .once = PA_ONCE_INIT, \ + .tls = NULL \ + }; \ + static void name##_tls_init(void) { \ + name##_tls.tls = pa_tls_new(free_cb); \ + } \ + static inline pa_tls* name##_tls_obj(void) { \ + pa_run_once(&name##_tls.once, name##_tls_init); \ + return name##_tls.tls; \ + } \ + static void name##_tls_destructor(void) PA_GCC_DESTRUCTOR; \ + static void name##_tls_destructor(void) { \ + static void (*_free_cb)(void*) = free_cb; \ + if (!pa_in_valgrind()) \ + return; \ + if (!name##_tls.tls) \ + return; \ + if (_free_cb) { \ + void *p; \ + if ((p = pa_tls_get(name##_tls.tls))) \ + _free_cb(p); \ + } \ + pa_tls_free(name##_tls.tls); \ + } \ + static inline void* name##_tls_get(void) { \ + return pa_tls_get(name##_tls_obj()); \ + } \ + static inline void* name##_tls_set(void *p) { \ + return pa_tls_set(name##_tls_obj(), p); \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon + +#ifdef SUPPORT_TLS___THREAD +/* An optimized version of the above that requires no dynamic + * allocation if the compiler supports __thread */ +#define PA_STATIC_TLS_DECLARE_NO_FREE(name) \ + static __thread void *name##_tls = NULL; \ + static inline void* name##_tls_get(void) { \ + return name##_tls; \ + } \ + static inline void* name##_tls_set(void *p) { \ + void *r = name##_tls; \ + name##_tls = p; \ + return r; \ + } \ + struct __stupid_useless_struct_to_allow_trailing_semicolon +#else +#define PA_STATIC_TLS_DECLARE_NO_FREE(name) PA_STATIC_TLS_DECLARE(name, NULL) +#endif + +#define PA_STATIC_TLS_GET(name) (name##_tls_get()) +#define PA_STATIC_TLS_SET(name, p) (name##_tls_set(p)) + #endif