Allow a parameter to smb_thread_once's initialization function
authorDerrell Lipman <derrell@dworkin.(none)>
Wed, 13 May 2009 13:49:59 +0000 (09:49 -0400)
committerDerrell Lipman <derrell@dworkin.(none)>
Wed, 13 May 2009 13:50:17 +0000 (09:50 -0400)
- This should make life easier for ourselves. We're no longer constrained to
  the semantics of pthread_once, so let's allow passing a parameter to the
  initialization function. Some of Samba's init functions return a
  value. Although I haven't searched, I suspect that some of the init
  functions require in input parameters. The parameter added here can be used
  for input, output, or both, as necessary... or ignored, as is now done in
  talloc_stackframe_init().

Derrell

lib/util/smb_threads.c
lib/util/smb_threads.h
lib/util/smb_threads_internal.h
lib/util/talloc_stack.c

index e2d01f775a4e0e7d09183fa704a2ff6d9001207e..ffe2eb011423c3977a9bef373b6addd691a2c085 100644 (file)
@@ -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;
 }
 
 
index 5079b17c6d2c0c879a111ee3c27cf35f2f9869c4..809673ab544b245afe6c653061862525decab4a7 100644 (file)
@@ -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;
 
index 29a581b01394ecf4496e844068d1e411b94b830d..038c584b608c151c8d78ee40a038445edcf838b2 100644 (file)
 #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)
index 2ed18fa1139ac54984b1a91078f0efc45b4b0399..f1727ce469d87594d20061c9b925234daa9abf94 100644 (file)
@@ -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");