[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha7-1100-g3d2e95c

Jeremy Allison jra at samba.org
Mon Apr 20 10:05:19 GMT 2009


The branch, master has been updated
       via  3d2e95c296a1858986b9c806dff67c9cc3d8f70d (commit)
      from  03abc846ee14a08e585c0997a6235ea01db8352f (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit 3d2e95c296a1858986b9c806dff67c9cc3d8f70d
Author: Jeremy Allison <jra at samba.org>
Date:   Mon Apr 20 03:04:42 2009 -0700

    Fix the pthread_once initialization issue. Make talloc_stackframe use
    this.
    Jeremy.

-----------------------------------------------------------------------

Summary of changes:
 lib/util/smb_threads.c          |   25 +++++++++++++--
 lib/util/smb_threads.h          |   61 +++++++++++++++++++++++----------------
 lib/util/smb_threads_internal.h |   11 ++++--
 lib/util/talloc_stack.c         |   26 +++++++++++++---
 4 files changed, 85 insertions(+), 38 deletions(-)


Changeset truncated at 500 lines:

diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c
index fa2d8da..783e660 100644
--- a/lib/util/smb_threads.c
+++ b/lib/util/smb_threads.c
@@ -92,8 +92,26 @@ int smb_thread_set_functions(const struct smb_thread_functions *tf)
 
 SMB_THREADS_DEF_PTHREAD_IMPLEMENTATION(tf);
 
+static smb_thread_once_t ot = SMB_THREAD_ONCE_INIT;
 void *pkey = NULL;
 
+static void init_fn(void)
+{
+	int ret;
+
+	if (!global_tfp) {
+		/* Non-thread safe init case. */
+		if (ot) {
+			return;
+		}
+		ot = true;
+	}
+
+	if ((ret = SMB_THREAD_CREATE_TLS("test_tls", pkey)) != 0) {
+		printf("Create tls once error: %d\n", ret);
+	}
+}
+
 /* Test function. */
 int test_threads(void)
 {
@@ -101,9 +119,8 @@ int test_threads(void)
 	void *plock = NULL;
 	smb_thread_set_functions(&tf);
 
-	if ((ret = SMB_THREAD_CREATE_TLS_ONCE("test_tls", pkey)) != 0) {
-		printf("Create tls once error: %d\n", ret);
-	}
+	SMB_THREAD_ONCE(&ot, init_fn);
+
 	if ((ret = SMB_THREAD_CREATE_MUTEX("test", plock)) != 0) {
 		printf("Create lock error: %d\n", ret);
 	}
@@ -114,7 +131,7 @@ int test_threads(void)
 		printf("unlock error: %d\n", ret);
 	}
 	SMB_THREAD_DESTROY_MUTEX(plock);
-	SMB_THREAD_DESTROY_TLS_ONCE(pkey);
+	SMB_THREAD_DESTROY_TLS(pkey);
 
 	return 0;
 }
diff --git a/lib/util/smb_threads.h b/lib/util/smb_threads.h
index c2ba533..f4ed1fc 100644
--- a/lib/util/smb_threads.h
+++ b/lib/util/smb_threads.h
@@ -20,6 +20,23 @@
 #ifndef _smb_threads_h_
 #define _smb_threads_h_
 
+#if defined(HAVE_PTHREAD_H)
+#include <pthread.h>
+#endif
+
+/* Data types needed for smb_thread_once call. */
+#if defined(HAVE_PTHREAD_H)
+#define smb_thread_once_t pthread_once_t
+#else
+#define smb_thread_once_t bool
+#endif
+
+#if defined(HAVE_PTHREAD_H)
+#define SMB_THREAD_ONCE_INIT PTHREAD_ONCE_INIT
+#else
+#define SMB_THREAD_ONCE_INIT false
+#endif
+
 enum smb_thread_lock_type {
 	SMB_THREAD_LOCK = 1,
 	SMB_THREAD_UNLOCK
@@ -35,11 +52,14 @@ struct smb_thread_functions {
 	int (*lock_mutex)(void *plock, enum smb_thread_lock_type lock_type,
 			const char *location);
 
+	/* Once initialization. */
+	int (*smb_thread_once)(smb_thread_once_t *p_once, void (*init_fn)(void));
+
 	/* Thread local storage. */
-	int (*create_tls_once)(const char *keyname,
+	int (*create_tls)(const char *keyname,
 			void **ppkey,
 			const char *location);
-	void (*destroy_tls_once)(void **pkey,
+	void (*destroy_tls)(void **pkey,
 			const char *location);
 	int (*set_tls)(void *pkey, const void *pval, const char *location);
 	void *(*get_tls)(void *pkey, const char *location);
@@ -77,45 +97,35 @@ static int smb_lock_pthread(void *plock, enum smb_thread_lock_type lock_type, co
 	} \
 } \
  \
-static pthread_mutex_t smb_create_tls_mutex = PTHREAD_MUTEX_INITIALIZER; \
+static int smb_thread_once_pthread(smb_thread_once_t *p_once, void (*init_fn)(void)) \
+{ \
+	return pthread_once(p_once, init_fn); \
+} \
  \
-static int smb_create_tls_once_pthread(const char *keyname, void **ppkey, const char *location) \
+static int smb_create_tls_pthread(const char *keyname, void **ppkey, const char *location) \
 { \
 	int ret; \
 	pthread_key_t *pkey; \
-	ret = pthread_mutex_lock(&create_tls_mutex); \
-	if (ret) { \
-		return ret; \
-	} \
-	if (*ppkey) { \
-		pthread_mutex_unlock(&create_tls_mutex); \
-		return 0; \
-	} \
 	pkey = (pthread_key_t *)malloc(sizeof(pthread_key_t)); \
 	if (!pkey) { \
-		pthread_mutex_unlock(&create_tls_mutex); \
 		return ENOMEM; \
 	} \
 	ret = pthread_key_create(pkey, NULL); \
 	if (ret) { \
 		free(pkey); \
-		pthread_mutex_unlock(&create_tls_mutex); \
 		return ret; \
 	} \
 	*ppkey = (void *)pkey; \
-	pthread_mutex_unlock(&create_tls_mutex); \
 	return 0; \
 } \
  \
-static void smb_destroy_tls_once_pthread(void **ppkey, const char *location) \
+static void smb_destroy_tls_pthread(void **ppkey, const char *location) \
 { \
-	pthread_mutex_lock(&create_tls_mutex); \
 	if (*ppkey) { \
 		pthread_key_delete(*(pthread_key_t *)ppkey); \
 		free(*ppkey); \
 		*ppkey = NULL; \
 	} \
-	pthread_mutex_unlock(&create_tls_mutex); \
 } \
  \
 static int smb_set_tls_pthread(void *pkey, const void *pval, const char *location) \
@@ -129,12 +139,13 @@ static void *smb_get_tls_pthread(void *pkey, const char *location) \
 } \
  \
 static const struct smb_thread_functions (tf) = { \
-                        smb_create_mutex_pthread, \
-                        smb_destroy_mutex_pthread, \
-                        smb_lock_pthread, \
-                        smb_create_tls_once_pthread, \
-                        smb_destroy_tls_once_pthread, \
-                        smb_set_tls_pthread, \
-                        smb_get_tls_pthread }
+			smb_create_mutex_pthread, \
+			smb_destroy_mutex_pthread, \
+			smb_lock_pthread, \
+			smb_thread_once_pthread, \
+			smb_create_tls_pthread, \
+			smb_destroy_tls_pthread, \
+			smb_set_tls_pthread, \
+			smb_get_tls_pthread }
 
 #endif
diff --git a/lib/util/smb_threads_internal.h b/lib/util/smb_threads_internal.h
index 58c6fe3..b7e862a 100644
--- a/lib/util/smb_threads_internal.h
+++ b/lib/util/smb_threads_internal.h
@@ -33,13 +33,16 @@
 #define SMB_THREAD_LOCK(plock, type) \
 	(global_tfp ? global_tfp->lock_mutex((plock), (type), __location__) : 0)
 
-#define SMB_THREAD_CREATE_TLS_ONCE(keyname, key) \
-	(global_tfp ? global_tfp->create_tls_once((keyname), &(key), __location__) : 0)
+#define SMB_THREAD_ONCE(ponce, init_fn) \
+	(global_tfp ? global_tfp->smb_thread_once((ponce), (init_fn)) : ((init_fn()), 0))
 
-#define SMB_THREAD_DESTROY_TLS_ONCE(key) \
+#define SMB_THREAD_CREATE_TLS(keyname, key) \
+	(global_tfp ? global_tfp->create_tls((keyname), &(key), __location__) : 0)
+
+#define SMB_THREAD_DESTROY_TLS(key) \
 	do { \
 		if (global_tfp) { \
-			global_tfp->destroy_tls_once(&(key), __location__); \
+			global_tfp->destroy_tls(&(key), __location__); \
 		}; \
 	} while (0)
 
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
index f572dd6..f5ca9d2 100644
--- a/lib/util/talloc_stack.c
+++ b/lib/util/talloc_stack.c
@@ -55,7 +55,25 @@ struct talloc_stackframe {
 
 static void *global_ts;
 
-static struct talloc_stackframe *talloc_stackframe_init(void)
+/* Variable to ensure TLS value is only initialized once. */
+static smb_thread_once_t ts_initialized = SMB_THREAD_ONCE_INIT;
+
+static void talloc_stackframe_init(void)
+{
+	if (!global_tfp) {
+		/* Non-thread safe init case. */
+		if (ts_initialized) {
+			return;
+		}
+		ts_initialized = true;
+	}
+
+	if (SMB_THREAD_CREATE_TLS("talloc_stackframe", global_ts)) {
+		smb_panic("talloc_stackframe_init create_tls failed");
+	}
+}
+
+static struct talloc_stackframe *talloc_stackframe_create(void)
 {
 #if defined(PARANOID_MALLOC_CHECKER)
 #ifdef malloc
@@ -74,9 +92,7 @@ static struct talloc_stackframe *talloc_stackframe_init(void)
 
 	ZERO_STRUCTP(ts);
 
-	if (SMB_THREAD_CREATE_TLS_ONCE("talloc_stackframe", global_ts)) {
-		smb_panic("talloc_stackframe_init create_tls failed");
-	}
+	SMB_THREAD_ONCE(&ts_initialized, talloc_stackframe_init);
 
 	if (SMB_THREAD_SET_TLS(global_ts, ts)) {
 		smb_panic("talloc_stackframe_init set_tls failed");
@@ -115,7 +131,7 @@ static TALLOC_CTX *talloc_stackframe_internal(size_t poolsize)
 		(struct talloc_stackframe *)SMB_THREAD_GET_TLS(global_ts);
 
 	if (ts == NULL) {
-		ts = talloc_stackframe_init();
+		ts = talloc_stackframe_create();
 	}
 
 	if (ts->talloc_stack_arraysize < ts->talloc_stacksize + 1) {


-- 
Samba Shared Repository


More information about the samba-cvs mailing list