ID:               35326
 Updated by:       [EMAIL PROTECTED]
 Reported By:      bugs dot php dot net at chsc dot dk
-Status:           Open
+Status:           Feedback
 Bug Type:         Directory function related
 Operating System: Linux
 PHP Version:      5.0.5
 New Comment:

Please try using this CVS snapshot:

  http://snaps.php.net/php5-latest.tar.gz
 
For Windows:
 
  http://snaps.php.net/win32/php5-win32-latest.zip




Previous Comments:
------------------------------------------------------------------------

[2005-11-22 11:32:49] bugs dot php dot net at chsc dot dk

Description:
------------
There appears to be a concurrency issue when mkdir is called on two
separate threads with the following parameters:

Thread 1:
mkdir('/tmp/foo/bar/1', 0777, true);

Thread 2:
mkdir('/tmp/foo/bar/2', 0777, true);

Sometimes one of the threads (e.g. thread 2) two fails with "Warning:
mkdir(): File exists" and the directory /tmp/foo/bar/2 does not exist
afterwards.

What I think is happening in thread 2 is is this:
PHP looks for /tmp/foo/bar/2 and sees that it does not exist. Neither
does /tmp/foo/bar and /tmp/foo. So it tries to create /tmp/foo, but
that directory was just created a millisecond second ago by another
thread, so mkdir gives instead of just moving on to create /tmp/foo/bar
and /tmp/foo/bar/2.

Reproduce code:
---------------
This code reproduces the problem in about every second attempt. It
consists of two files, index.php and iframe.php.


index.php:

<?php
$fire = time() + 2;
?>
<h1>Nr. 1</h1>
<iframe src="iframe.php?fire=<?= $fire ?>&amp;no=1"></iframe>
<h1>Nr. 2</h1>
<iframe src="iframe.php?fire=<?= $fire ?>&amp;no=2"></iframe>


iframe.php:

<?php
$fire = $_GET['fire'];
$no = $_GET['no'];
// synchronize the two threads
while ($fire > time());
$dir = '/tmp/' . $fire . '/foo/bar/foo/bar/' . $no;
//sleep($no);
var_dump(is_dir($dir));
echo "Making $dir ";
mkdir($dir, 0777, true);
var_dump(is_dir($dir));
?>


Expected result:
----------------
Thread 2 should output this:
bool(false) Making /tmp/1132653651/foo/bar/foo/bar/2 bool(true)


Actual result:
--------------
Thread 2 sometimes outputs this:
bool(false) Making /tmp/1132655181/foo/bar/foo/bar/2 Warning: mkdir():
File exists in /home/chsc/public_html/mkdir/iframe.php on line 10
bool(false) 

Notice that the directory does not exist afterwards.

If I uncomment the sleep() call above, there are no problems.


A workaround:
$ok = mkdir($dir, 0777, true);
if (!$ok && !is_dir($dir)) {
    sleep(1);
    mkdir($dir, 0777, true);
}


In other words, it works if I try again. I hope that mkdir() can be
changed so that it only returns false if the directory cannot be
created at all (e.g. because of lack of permissions or because it
already exists).



------------------------------------------------------------------------


-- 
Edit this bug report at http://bugs.php.net/?id=35326&edit=1

Reply via email to