Fix broken smb_thread_once function
authorDerrell Lipman <derrell@dworkin.(none)>
Wed, 13 May 2009 01:22:23 +0000 (21:22 -0400)
committerDerrell Lipman <derrell@dworkin.(none)>
Wed, 13 May 2009 01:24:34 +0000 (21:24 -0400)
- We can't set *ponce=true before running the function because although other
  threads wouldn't re-run the initialization function, they could potentially
  proceed beyond the initialization point while the first thread was still
  running the initialization function. If a second thread gets to an
  SMB_THREAD_ONCE() call while one with the same ponce is running, we need to
  ensure that it enters smb_thread_once() to await the mutex and then recheck
  whether *ponce is set or not.  My original comment about other "once"
  functions possibly being called from within this "once" function is
  irrelevant since those other ones would have their own unique ponce.

Derrell

lib/util/smb_threads.c

index 04079767d6d2146e6db76181d8bbc4cacb5e19ea..6f84a2e7476d78dc82bff6bb5df58fbb6c90ab0c 100644 (file)
@@ -108,29 +108,19 @@ 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 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) {
                 smb_panic("error locking 'once'");
        }
 
-        /* Store whether we're going to need to issue the function call */
-        need_func_call = ! *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.)
-                 */
-                *ponce = true;
+        if (! *ponce) {
+                /* Nope, we need to run the initialization function */
+                (*init_fn)();
         }
 
         /* Unlock the mutex */
@@ -138,12 +128,6 @@ int smb_thread_once(smb_thread_once_t *ponce, void (*init_fn)(void))
                 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;
 }