From: Derrell Lipman Date: Wed, 13 May 2009 01:22:23 +0000 (-0400) Subject: Fix broken smb_thread_once function X-Git-Url: http://git.samba.org/?p=metze%2Fsamba%2Fwip.git;a=commitdiff_plain;h=8a60c26c7cb788fe181fb8db10e454b96dda23a9 Fix broken smb_thread_once function - 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 --- diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c index 04079767d6d2..6f84a2e7476d 100644 --- a/lib/util/smb_threads.c +++ b/lib/util/smb_threads.c @@ -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; }