summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/util/smb_threads.c23
-rw-r--r--lib/util/smb_threads.h4
-rw-r--r--lib/util/smb_threads_internal.h12
-rw-r--r--lib/util/talloc_stack.c4
4 files changed, 28 insertions, 15 deletions
diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c
index e2d01f775a..ffe2eb0114 100644
--- a/lib/util/smb_threads.c
+++ b/lib/util/smb_threads.c
@@ -105,33 +105,44 @@ int smb_thread_set_functions(const struct smb_thread_functions *tf)
implementation's "once" type.
********************************************************************/
-int smb_thread_once(smb_thread_once_t *ponce, void (*init_fn)(void))
+int smb_thread_once(smb_thread_once_t *ponce,
+ void (*init_fn)(void *pdata),
+ void *pdata)
{
int ret;
/* Lock our "once" mutex in order to test and initialize ponce */
- if ((ret = SMB_THREAD_LOCK(once_mutex, SMB_THREAD_LOCK)) != 0) {
+ if (SMB_THREAD_LOCK(once_mutex, SMB_THREAD_LOCK) != 0) {
smb_panic("error locking 'once'");
}
+ /* Keep track of whether we ran their init function */
+ ret = ! *ponce;
+
/*
* See if another thread got here after we tested it initially but
* before we got our lock.
*/
if (! *ponce) {
/* Nope, we need to run the initialization function */
- (*init_fn)();
+ (*init_fn)(pdata);
/* Now we can indicate that the function has been run */
*ponce = true;
}
/* Unlock the mutex */
- if ((ret = SMB_THREAD_LOCK(once_mutex, SMB_THREAD_UNLOCK)) != 0) {
+ if (SMB_THREAD_LOCK(once_mutex, SMB_THREAD_UNLOCK) != 0) {
smb_panic("error unlocking 'once'");
}
-
- return 0;
+
+ /*
+ * Tell 'em whether we ran their init function. If they passed a data
+ * pointer to the init function and the init function could change
+ * something in the pointed-to data, this will tell them whether that
+ * data is valid or not.
+ */
+ return ret;
}
diff --git a/lib/util/smb_threads.h b/lib/util/smb_threads.h
index 5079b17c6d..809673ab54 100644
--- a/lib/util/smb_threads.h
+++ b/lib/util/smb_threads.h
@@ -52,7 +52,9 @@ struct smb_thread_functions {
};
int smb_thread_set_functions(const struct smb_thread_functions *tf);
-int smb_thread_once(smb_thread_once_t *ponce, void (*init_fn)(void));
+int smb_thread_once(smb_thread_once_t *ponce,
+ void (*init_fn)(void *pdata),
+ void *pdata);
extern const struct smb_thread_functions *global_tfp;
diff --git a/lib/util/smb_threads_internal.h b/lib/util/smb_threads_internal.h
index 29a581b013..038c584b60 100644
--- a/lib/util/smb_threads_internal.h
+++ b/lib/util/smb_threads_internal.h
@@ -33,12 +33,12 @@
#define SMB_THREAD_LOCK(plock, type) \
(global_tfp ? global_tfp->lock_mutex((plock), (type), __location__) : 0)
-#define SMB_THREAD_ONCE(ponce, init_fn) \
- (global_tfp \
- ? (! *(ponce) \
- ? smb_thread_once((ponce), (init_fn)) \
- : 0) \
- : ((init_fn()), 0))
+#define SMB_THREAD_ONCE(ponce, init_fn, pdata) \
+ (global_tfp \
+ ? (! *(ponce) \
+ ? smb_thread_once((ponce), (init_fn), (pdata)) \
+ : 0) \
+ : ((init_fn(pdata)), 0))
#define SMB_THREAD_CREATE_TLS(keyname, key) \
(global_tfp ? global_tfp->create_tls((keyname), &(key), __location__) : 0)
diff --git a/lib/util/talloc_stack.c b/lib/util/talloc_stack.c
index 2ed18fa113..f1727ce469 100644
--- a/lib/util/talloc_stack.c
+++ b/lib/util/talloc_stack.c
@@ -58,7 +58,7 @@ static void *global_ts;
/* 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)
+static void talloc_stackframe_init(void * unused)
{
if (!global_tfp) {
/* Non-thread safe init case. */
@@ -92,7 +92,7 @@ static struct talloc_stackframe *talloc_stackframe_create(void)
ZERO_STRUCTP(ts);
- SMB_THREAD_ONCE(&ts_initialized, talloc_stackframe_init);
+ SMB_THREAD_ONCE(&ts_initialized, talloc_stackframe_init, NULL);
if (SMB_THREAD_SET_TLS(global_ts, ts)) {
smb_panic("talloc_stackframe_init set_tls failed");