ID:               31363
 Comment by:       maurice at gitaar dot net
 Reported By:      ian at snork dot net
 Status:           Open
 Bug Type:         Filesystem function related
 Operating System: Debian woody (i386)
 PHP Version:      5CVS-2005-03-09
 New Comment:

I had the same problem. It seems that errno is not reset to zero in the
flock implementation. Therefore the last errno will be used. In case no
other errno-modifying call is made before retrying the flock() call,
the call will conclude in an EWOULDBLOCK situation (my conclusion after
a very quick scan of the code).

Looking with truss on Solaris to the process shows that the first fcntl
call (during which I have already locked the file) returns an EAGAIN
error, meaning that the file was already locked. The second fnctl call
(on the now unlocked file) does not return an error. So the call is
successfull. But the call from the php code does set the $wouldblock
parameter to a true value.

For me a workaround for now is something like this (no error checking
on flock and a bit of pseudo-coded, but the workaround is the important
part):

for (;;)
{
    flock($fd, LOCK_EX|LOCK_NB, $wouldblock);
    if (! $wouldblock) break;
    fopen("/this/is/no/real/file", "r");
}

The fopen() call sets errno to the file not found error, which makes
the flock() call act like the first time it is called. This is not
great coding, but it does work for me till a real fix is implemented in
PHP.


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

[2005-04-01 14:42:19] maka3d at yahoo dot com dot br

I expected it to be fixed until 5.0.4.
On freeBSD it doesn't work too :(

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

[2005-03-09 17:29:56] ian at snork dot net

flock() in today's PHP CVS snapshot
(http://snaps.php.net/php5-latest.tar.bz2) behaves slightly
differently, but still doesn't quite work correctly in non-blocking
mode.

Expected result:
--------------
$ php5 flock_test.php &  
Got /tmp/test1   
$ php5 flock_test.php &  
Got /tmp/test2   
$ php5 flock_test.php &  
Got /tmp/test3   
$ php5 flock_test.php &  
$
Releasing /tmp/test1
Got /tmp/test1
Releasing /tmp/test2
Releasing /tmp/test3


Actual result:
--------------
$ php5 flock_test.php &  
Got /tmp/test1   
$ php5 flock_test.php &  
Got /tmp/test2   
$ php5 flock_test.php &  
Got /tmp/test3   
$ php5 flock_test.php &  
$
Releasing /tmp/test1
Releasing /tmp/test2
Releasing /tmp/test3

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

[2005-02-28 21:06:39] [EMAIL PROTECTED]

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



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

[2004-12-31 06:41:56] ian at snork dot net

Description:
------------
This code works in PHP 4.3.0, but does not in PHP 5.0.3.    
        
When invoked, it will try to lock /tmp/test1, /tmp/test2      
or /tmp/test3 for exclusive use, whichever is free. If      
none are, it will wait a second before cycling through      
with another attempt.   
   
When running concurrently, the first invocation correctly   
picks up /tmp/test1; the second and subsequent ones just   
cycle forever.   
      
For some reason, the non-blocking flock() only sets $block  
the first time.  

Reproduce code:
---------------
while (!sleep(1))
  foreach (array("/tmp/test1", "/tmp/test2", "/tmp/test3") as $path)
    if (flock($handle = fopen($path, "w"), LOCK_EX | LOCK_NB, $block)
and !$block)
    {
      echo "Got $path\n"; 
      sleep(10); 
      echo "Releasing $path\n"; 
      exit; 
    }


Expected result:
----------------
$ php5 flock_test.php &  
Got /tmp/test1   
$ php5 flock_test.php &  
Got /tmp/test2   
$ php5 flock_test.php &  
Got /tmp/test3   
$ php5 flock_test.php &  
Releasing /tmp/test1  
Got /tmp/test1  
$ 
    

Actual result:
--------------
$ php5 flock_test.php & 
Got /tmp/test1 
$ php5 flock_test.php & 
$ php5 flock_test.php & 
$ php5 flock_test.php & 
$ 


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


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

Reply via email to