Return-Path: X-Original-To: apmail-apr-commits-archive@www.apache.org Delivered-To: apmail-apr-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 8198B10AD7 for ; Tue, 21 Jan 2014 01:23:23 +0000 (UTC) Received: (qmail 85956 invoked by uid 500); 21 Jan 2014 01:23:22 -0000 Delivered-To: apmail-apr-commits-archive@apr.apache.org Received: (qmail 85870 invoked by uid 500); 21 Jan 2014 01:23:22 -0000 Mailing-List: contact commits-help@apr.apache.org; run by ezmlm Precedence: bulk List-Post: List-Help: List-Unsubscribe: Reply-To: dev@apr.apache.org List-Id: Delivered-To: mailing list commits@apr.apache.org Received: (qmail 85863 invoked by uid 99); 21 Jan 2014 01:23:21 -0000 Received: from athena.apache.org (HELO athena.apache.org) (140.211.11.136) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jan 2014 01:23:21 +0000 X-ASF-Spam-Status: No, hits=-2000.0 required=5.0 tests=ALL_TRUSTED X-Spam-Check-By: apache.org Received: from [140.211.11.4] (HELO eris.apache.org) (140.211.11.4) by apache.org (qpsmtpd/0.29) with ESMTP; Tue, 21 Jan 2014 01:23:20 +0000 Received: from eris.apache.org (localhost [127.0.0.1]) by eris.apache.org (Postfix) with ESMTP id 4059A23889CB; Tue, 21 Jan 2014 01:23:00 +0000 (UTC) Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: svn commit: r1559879 - in /apr/apr/branches/1.4.x: ./ file_io/win32/dir.c test/testdir.c Date: Tue, 21 Jan 2014 01:23:00 -0000 To: commits@apr.apache.org From: brane@apache.org X-Mailer: svnmailer-1.0.9 Message-Id: <20140121012300.4059A23889CB@eris.apache.org> X-Virus-Checked: Checked by ClamAV on apache.org Author: brane Date: Tue Jan 21 01:22:59 2014 New Revision: 1559879 URL: http://svn.apache.org/r1559879 Log: Merged rr1559873 from trunk: Fix timing bug in parallel apr_dir_make_recursive on Windows. * 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 * test/testdir.c (test_mkdir_recurs_parallel): New multithreaded test case. (test_removeall): Clean up after test_mkdir_recurs_parallel. Modified: apr/apr/branches/1.4.x/ (props changed) apr/apr/branches/1.4.x/file_io/win32/dir.c apr/apr/branches/1.4.x/test/testdir.c Propchange: apr/apr/branches/1.4.x/ ------------------------------------------------------------------------------ Merged /apr/apr/trunk:r1559873 Modified: apr/apr/branches/1.4.x/file_io/win32/dir.c URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/file_io/win32/dir.c?rev=1559879&r1=1559878&r2=1559879&view=diff ============================================================================== --- apr/apr/branches/1.4.x/file_io/win32/dir.c (original) +++ apr/apr/branches/1.4.x/file_io/win32/dir.c Tue Jan 21 01:22:59 2014 @@ -316,8 +316,8 @@ static apr_status_t dir_make_parent(char if (APR_STATUS_IS_ENOENT(rv)) { /* Missing an intermediate dir */ rv = dir_make_parent(path, perm, pool); - if (rv == APR_SUCCESS) { - rv = apr_dir_make (path, perm, pool); /* And complete the path */ + if (rv == APR_SUCCESS || APR_STATUS_IS_EEXIST(rv)) { + rv = apr_dir_make(path, perm, pool); /* And complete the path */ } } @@ -330,28 +330,35 @@ APR_DECLARE(apr_status_t) apr_dir_make_r apr_pool_t *pool) { apr_status_t rv = 0; - + rv = apr_dir_make (path, perm, pool); /* Try to make PATH right out */ - + if (APR_STATUS_IS_ENOENT(rv)) { /* Missing an intermediate dir */ char *dir; - + rv = apr_filepath_merge(&dir, "", path, APR_FILEPATH_NATIVE, pool); - if (rv == APR_SUCCESS) - rv = dir_make_parent(dir, perm, pool); /* Make intermediate dirs */ - - if (rv == APR_SUCCESS) + if (rv != APR_SUCCESS) + return rv; + + rv = dir_make_parent(dir, perm, pool); /* Make intermediate dirs */ + + if (rv == APR_SUCCESS || APR_STATUS_IS_EEXIST(rv)) { rv = apr_dir_make (dir, perm, pool); /* And complete the path */ - } - /* - * It's OK if PATH exists. Timing issues can lead to the second - * apr_dir_make being called on existing dir, therefore this check - * has to come last. - */ - if (APR_STATUS_IS_EEXIST(rv)) - return APR_SUCCESS; + if (APR_STATUS_IS_EEXIST(rv)) { + rv = APR_SUCCESS; /* Timing issue; see comment below */ + } + } + } + else if (APR_STATUS_IS_EEXIST(rv)) { + /* + * It's OK if PATH exists. Timing issues can lead to the + * second apr_dir_make being called on existing dir, therefore + * this check has to come last. + */ + rv = APR_SUCCESS; + } return rv; } Modified: apr/apr/branches/1.4.x/test/testdir.c URL: http://svn.apache.org/viewvc/apr/apr/branches/1.4.x/test/testdir.c?rev=1559879&r1=1559878&r2=1559879&view=diff ============================================================================== --- apr/apr/branches/1.4.x/test/testdir.c (original) +++ apr/apr/branches/1.4.x/test/testdir.c Tue Jan 21 01:22:59 2014 @@ -22,6 +22,7 @@ #include "apr_errno.h" #include "apr_general.h" #include "apr_lib.h" +#include "apr_thread_proc.h" #include "testutil.h" static void test_mkdir(abts_case *tc, void *data) @@ -59,6 +60,60 @@ static void test_mkdir_recurs(abts_case ABTS_INT_EQUAL(tc, APR_DIR, finfo.filetype); } +static void *APR_THREAD_FUNC thread_mkdir_func(apr_thread_t *thd, void *data) +{ + abts_case *tc = data; + apr_status_t s1, s2, s3, s4, s5; + + s1 = apr_dir_make_recursive("data/prll/one/thwo/three", + APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE, + p); + s2 = apr_dir_make_recursive("data/prll/four/five/six/seven/eight", + APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE, + p); + s3 = apr_dir_make_recursive("data/prll/nine/ten", + APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE, + p); + s4 = apr_dir_make_recursive("data/prll/11/12/13/14/15/16/17/18/19/20", + APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE, + p); + s5 = apr_dir_make_recursive("data/fortytwo", + APR_FPROT_UREAD | APR_FPROT_UWRITE | APR_FPROT_UEXECUTE, + p); + + ABTS_INT_EQUAL(tc, APR_SUCCESS, s1); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s2); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s3); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s4); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s5); + return NULL; +} + +static void test_mkdir_recurs_parallel(abts_case *tc, void *data) +{ + apr_thread_t *t1, *t2, *t3, *t4; + apr_status_t s1, s2, s3, s4; + + s1 = apr_thread_create(&t1, NULL, thread_mkdir_func, tc, p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s1); + s2 = apr_thread_create(&t2, NULL, thread_mkdir_func, tc, p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s2); + s3 = apr_thread_create(&t3, NULL, thread_mkdir_func, tc, p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s3); + s4 = apr_thread_create(&t4, NULL, thread_mkdir_func, tc, p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s4); + + apr_thread_join(&s1, t1); + apr_thread_join(&s2, t2); + apr_thread_join(&s3, t3); + apr_thread_join(&s4, t4); + + ABTS_INT_EQUAL(tc, APR_SUCCESS, s1); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s2); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s3); + ABTS_INT_EQUAL(tc, APR_SUCCESS, s4); +} + static void test_remove(abts_case *tc, void *data) { apr_status_t rv; @@ -91,6 +146,72 @@ static void test_removeall(abts_case *tc rv = apr_dir_remove("data/one", p); ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/one/thwo/three", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/one/thwo", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/one", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/four/five/six/seven/eight", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/four/five/six/seven", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/four/five/six", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/four/five", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/four", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/nine/ten", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/nine", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13/14/15/16/17/18/19/20", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13/14/15/16/17/18/19", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13/14/15/16/17/18", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13/14/15/16/17", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13/14/15/16", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13/14/15", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13/14", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12/13", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11/12", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll/11", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/prll", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); + + rv = apr_dir_remove("data/fortytwo", p); + ABTS_INT_EQUAL(tc, APR_SUCCESS, rv); } static void test_remove_notthere(abts_case *tc, void *data) @@ -245,6 +366,7 @@ abts_suite *testdir(abts_suite *suite) abts_run_test(suite, test_mkdir, NULL); abts_run_test(suite, test_mkdir_recurs, NULL); + abts_run_test(suite, test_mkdir_recurs_parallel, NULL); abts_run_test(suite, test_remove, NULL); abts_run_test(suite, test_removeall_fail, NULL); abts_run_test(suite, test_removeall, NULL);