diff options
-rw-r--r-- | lib/util/smb_threads.c | 23 | ||||
-rw-r--r-- | lib/util/smb_threads.h | 4 | ||||
-rw-r--r-- | lib/util/smb_threads_internal.h | 12 | ||||
-rw-r--r-- | lib/util/talloc_stack.c | 4 |
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"); |