diff options
author | Derrell Lipman <derrell@dworkin.(none)> | 2009-05-12 21:22:23 -0400 |
---|---|---|
committer | Derrell Lipman <derrell@dworkin.(none)> | 2009-05-12 21:24:34 -0400 |
commit | 8a60c26c7cb788fe181fb8db10e454b96dda23a9 (patch) | |
tree | 984f91070e1703d652762ff56a83e0b7133357ea | |
parent | 3627ceb5e25cdecd1a8113a5028cc898a1424349 (diff) | |
download | samba-8a60c26c7cb788fe181fb8db10e454b96dda23a9.tar.gz samba-8a60c26c7cb788fe181fb8db10e454b96dda23a9.tar.bz2 samba-8a60c26c7cb788fe181fb8db10e454b96dda23a9.zip |
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
-rw-r--r-- | lib/util/smb_threads.c | 22 |
1 files changed, 3 insertions, 19 deletions
diff --git a/lib/util/smb_threads.c b/lib/util/smb_threads.c index 04079767d6..6f84a2e747 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; } |