On 04.03.2015 17:04, Philip Martin wrote: > Branko Čibej <br...@wandisco.com> writes: > >> And here it is: the whole atomic.c file >> >> https://paste.apache.org/2iyN >> >> and the diff against current trunk: >> >> https://paste.apache.org/cK1R >> > I prefer patches to be included in the email. Ideally inline, as far as > I am concerned, or as an attachment.
In this case, looking at the whole file is actually easier to review ... anyway, here's the latest version of the patch: Index: subversion/libsvn_subr/atomic.c =================================================================== --- subversion/libsvn_subr/atomic.c (revision 1663988) +++ subversion/libsvn_subr/atomic.c (working copy) @@ -42,44 +42,53 @@ /* We have to call init_func exactly once. Because APR doesn't have statically-initialized mutexes, we implement a poor man's spinlock using svn_atomic_cas. */ + + svn_error_t *err = SVN_NO_ERROR; svn_atomic_t status = svn_atomic_cas(global_status, SVN_ATOMIC_START_INIT, SVN_ATOMIC_UNINITIALIZED); - if (status == SVN_ATOMIC_UNINITIALIZED) + for (;;) { - svn_error_t *err = init_func(baton, pool); - if (err) + switch (status) { -#if APR_HAS_THREADS - /* Tell other threads that the initialization failed. */ - svn_atomic_cas(global_status, - SVN_ATOMIC_INIT_FAILED, - SVN_ATOMIC_START_INIT); -#endif + case SVN_ATOMIC_UNINITIALIZED: + err = init_func(baton, pool); + if (err) + { + status = svn_atomic_cas(global_status, + SVN_ATOMIC_INIT_FAILED, + SVN_ATOMIC_START_INIT); + } + else + { + status = svn_atomic_cas(global_status, + SVN_ATOMIC_INITIALIZED, + SVN_ATOMIC_START_INIT); + } + + /* Take another spin through the switch to make sure that we + have just set a valid value. */ + continue; + + case SVN_ATOMIC_START_INIT: + /* Wait for the init function to complete. */ + apr_sleep(APR_USEC_PER_SEC / 1000); + status = svn_atomic_cas(global_status, + SVN_ATOMIC_UNINITIALIZED, + SVN_ATOMIC_UNINITIALIZED); + continue; + + case SVN_ATOMIC_INIT_FAILED: return svn_error_create(SVN_ERR_ATOMIC_INIT_FAILURE, err, "Couldn't perform atomic initialization"); + + case SVN_ATOMIC_INITIALIZED: + return SVN_NO_ERROR; + + default: + /* Something went seriously wrong with the atomic operations. */ + abort(); } - svn_atomic_cas(global_status, - SVN_ATOMIC_INITIALIZED, - SVN_ATOMIC_START_INIT); } -#if APR_HAS_THREADS - /* Wait for whichever thread is performing initialization to finish. */ - /* XXX FIXME: Should we have a maximum wait here, like we have in - the Windows file IO spinner? */ - else while (status != SVN_ATOMIC_INITIALIZED) - { - if (status == SVN_ATOMIC_INIT_FAILED) - return svn_error_create(SVN_ERR_ATOMIC_INIT_FAILURE, NULL, - "Couldn't perform atomic initialization"); - - apr_sleep(APR_USEC_PER_SEC / 1000); - status = svn_atomic_cas(global_status, - SVN_ATOMIC_UNINITIALIZED, - SVN_ATOMIC_UNINITIALIZED); - } -#endif /* APR_HAS_THREADS */ - - return SVN_NO_ERROR; }