*/
#include "includes.h"
+#include "smb_threads.h"
/*********************************************************
Functions to vector the locking primitives used internally
void **global_lock_array;
+/*********************************************************
+ Mutex used for our internal "once" function
+*********************************************************/
+
+static void *once_mutex = NULL;
+
+
/*********************************************************
Function to set the locking primitives used by libsmbclient.
*********************************************************/
SAFE_FREE(name);
}
+ /* Create the mutex we'll use for our "once" function */
+ if (SMB_THREAD_CREATE_MUTEX("smb_once", once_mutex) != 0) {
+ smb_panic("smb_thread_set_functions: failed to create 'once' mutex");
+ }
+
return 0;
}
+/*******************************************************************
+ Call a function only once. We implement this ourselves
+ using our own mutex rather than using the thread implementation's
+ *_once() function because each implementation has its own
+ type for the variable which keeps track of whether the function
+ has been called, and there's no easy way to allocate the correct
+ size variable in code internal to Samba without knowing the
+ implementation's "once" type.
+********************************************************************/
+
+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 (SMB_THREAD_LOCK(once_mutex) != 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)(pdata);
+
+ /* Now we can indicate that the function has been run */
+ *ponce = true;
+ }
+
+ /* Unlock the mutex */
+ if (SMB_THREAD_UNLOCK(once_mutex) != 0) {
+ smb_panic("error unlocking 'once'");
+ }
+
+ /*
+ * 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;
+}
+
+
#if 0
/* Test. - pthread implementations. */
#include <pthread.h>
if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_LOCK)) != 0) {
printf("lock error: %d\n", ret);
}
- if ((SMB_THREAD_LOCK(plock, SMB_THREAD_UNLOCK)) != 0) {
+ if ((ret = SMB_THREAD_LOCK(plock, SMB_THREAD_UNLOCK)) != 0) {
printf("unlock error: %d\n", ret);
}
SMB_THREAD_DESTROY_MUTEX(plock);