On 16.01.2014 15:19, Bert Huijben wrote: > Hi, > > While debugging a Subversion buildbot error I found a race condition in > apr_dir_make_recursive(). > > If two new threads perform something like > $ mkdir -p some/deep/sub/dir > $ mkdir -p some/deep/sub/other > At the same time > > And 'some' and/or 'deep' don't exist both threads will fail to create their > final directory part and then try to create the parent directories. If their > first attempt fails they try to create the parent directory, and then itself > again. But if the other thread was first, we get an EEXISTS error. This > error is ignored by the inner implementation, but the outer function > accidentally converts this to APR_SUCCESS even though the requested > directory isn't created. > > [[ > * file_io/win32/dir.c > (dir_make_parent): When parent just got created, continue creating > children. > (apr_dir_make_recursive): Only handle EEXIST of the requested directory as > success, > not any ancestor. > > Patch by: rhuijben > ]] > > At first glance it appears the same problem exists on other platforms (most > importantly the standard unix code) too.
As a matter of fact, Unix does not have this problem because it doesn't recurse through a dir_make_parent function, and the existing check already covers the EEXIST. And OS/2 doesn't have an apr_dir_make_recursive implementation at all. So the problem existed only on Windows. I've added a test case to testdir.c to exercise this code in parallel. -- Brane
