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;
}
};
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;
#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)
/* 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. */
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");