]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/util: add pthread support to talloc_stack.c
authorStefan Metzmacher <metze@samba.org>
Mon, 12 May 2025 18:44:46 +0000 (20:44 +0200)
committerAndreas Schneider <asn@cryptomilk.org>
Mon, 19 May 2025 09:11:29 +0000 (09:11 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
lib/util/talloc_stack.c

index 25ed38633ff8669b045638910124d4c0e30f78de..03b2b356308fa87ad25510933730a33eca0513c1 100644 (file)
  */
 
 #include "replace.h"
+#include <pthread.h>
 #include <talloc.h>
 #include "lib/util/talloc_stack.h"
-#include "lib/util/fault.h"
 #include "lib/util/debug.h"
+#include "lib/util/fault.h"
 
 struct talloc_stackframe {
        int talloc_stacksize;
@@ -49,7 +50,13 @@ struct talloc_stackframe {
        TALLOC_CTX **talloc_stack;
 };
 
+/* Variable to ensure TLS value is only initialized once. */
+#ifdef HAVE_PTHREAD
+static pthread_once_t ts_initialized = PTHREAD_ONCE_INIT;
+static pthread_key_t ts_key;
+#else /* ! HAVE_PTHREAD */
 static struct talloc_stackframe *global_ts;
+#endif
 
 static void talloc_stackframe_destructor(void *ptr)
 {
@@ -71,6 +78,18 @@ static void talloc_stackframe_destructor(void *ptr)
        free(ts);
 }
 
+#ifdef HAVE_PTHREAD
+static void talloc_stackframe_init_once(void)
+{
+       int ret = pthread_key_create(&ts_key, talloc_stackframe_destructor);
+       SMB_ASSERT(ret == 0);
+}
+
+static void talloc_stackframe_init(void)
+{
+       pthread_once(&ts_initialized, talloc_stackframe_init_once);
+}
+#else /* ! HAVE_PTHREAD */
 static void talloc_stackframe_atexit(void)
 {
        talloc_stackframe_destructor(global_ts);
@@ -85,6 +104,7 @@ static void talloc_stackframe_init(void)
                done = true;
        }
 }
+#endif
 
 static struct talloc_stackframe *talloc_stackframe_get_existing(void)
 {
@@ -92,7 +112,11 @@ static struct talloc_stackframe *talloc_stackframe_get_existing(void)
 
        talloc_stackframe_init();
 
+#ifdef HAVE_PTHREAD
+       ts = (struct talloc_stackframe *)pthread_getspecific(ts_key);
+#else /* ! HAVE_PTHREAD */
        ts = global_ts;
+#endif
 
        return ts;
 }
@@ -100,6 +124,9 @@ static struct talloc_stackframe *talloc_stackframe_get_existing(void)
 static struct talloc_stackframe *talloc_stackframe_get(void)
 {
        struct talloc_stackframe *ts = talloc_stackframe_get_existing();
+#ifdef HAVE_PTHREAD
+       int ret;
+#endif /* ! HAVE_PTHREAD */
 
        if (ts != NULL) {
                return ts;
@@ -119,7 +146,12 @@ static struct talloc_stackframe *talloc_stackframe_get(void)
                smb_panic("talloc_stackframe_init malloc failed");
        }
 
+#ifdef HAVE_PTHREAD
+       ret = pthread_setspecific(ts_key, ts);
+       SMB_ASSERT(ret == 0);
+#else /* ! HAVE_PTHREAD */
        global_ts = ts;
+#endif
 
        return ts;
 }