Mutex used for our internal "once" function
*********************************************************/
-void *once_mutex = NULL;
+static void *once_mutex = NULL;
/*********************************************************
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;
- bool need_func_call;
/* 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) != 0) {
smb_panic("error locking 'once'");
}
- /* Store whether we're going to need to issue the function call */
- need_func_call = ! *ponce;
+ /* 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 (need_func_call) {
- /*
- * Nope, we still need to issue the call. Set the "once"
- * variable to true now so we can unlock the mutex. (We don't
- * want to leave it locked during the call to the
- * initialization function in case there's yet another "once"
- * function needed to be called from therein.)
- */
+ if (! *ponce) {
+ /* Nope, we need to run the initialization function */
+ (*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_UNLOCK(once_mutex) != 0) {
smb_panic("error unlocking 'once'");
}
-
- /* Finally, if we need to call the user-provided function, ... */
- if (need_func_call) {
- /* ... then do so now. */
- (*init_fn)();
- }
-
- 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;
}