7

running this code twice :

$fp = @fopen('test.test', "wb");

    if (flock($fp, LOCK_NB | LOCK_EX)){
                @fwrite($fp, $data);
                echo 'written';
                sleep(5);
    }else{
        echo 'skipped , ok';
    }

    @flock($fp, LOCK_UN);
    @fclose($fp);

always gives me the output of "written"

Means the LOCK_NB is skipped , any clues (on both winbdows and unix)

EDIT (2012-03-29 still not fixed): https://bugs.php.net/bug.php?id=54453&edit=3 PHP Bug #54453

Rami Dabain
  • 4,709
  • 12
  • 62
  • 106
  • 2
    Works for me (on Linux) if used with the original example http://www.php.net/manual/de/function.flock.php#101701 - Try to remove the `@`s to find out potential issues. Update: Your example code works too. (Again, on Linux. Windows is *supposed* to work, but I wouldn't trust in that.) – mario Apr 02 '11 at 15:43
  • Tried the code u gave me , same results , what PHP version do u use ? – Rami Dabain Apr 02 '11 at 15:46
  • PHP 5.3.2 on AMD64. But it works the same with php447 32-bit. If your code runs on any form of networked or userland filesystem, I would be wary of file locking. – mario Apr 02 '11 at 15:48
  • Am trying the code on centos (latest) window XP and ubuntu (latest) with php 5.3.1 for windows and 5.2.9 for others ... – Rami Dabain Apr 02 '11 at 15:50
  • I'm afraid you're in for a debugging adventure. Your code looks okay. On CentOS or Ubuntu you should be able to use `strace` when running the script. It should show `flock(3, LOCK_EX|LOCK_NB) = 0` for the first and `flock(3, LOCK_EX|LOCK_NB) = -1 EAGAIN (Resource temporarily unavailable)` for the parallel run. Then you would be able to tell if either the OS or your PHP setup is borked. (Which actually would be no help in either case, but.) – mario Apr 02 '11 at 15:54

2 Answers2

21

When using Apache+PHP I was tricked into believing LOCK_NB was ignored (it wasn't, it was the browser waiting for the first request to finish).

Because I was making 2 requests with the same browser, the browser was waiting for the first call to finish before making the next one (even ignoring a "Connection: close" header).

Using 2 separate browsers (in my case Chrome + Firefox, or Chrome + wget on the server) I concluded LOCK_NB worked just fine.

If a file in w+ mode was locked with LOCK_EX | LOCK_NB, attempting another LOCK_EX | LOCK_NB on the same file returned false (the intended behaviour).

oxygen
  • 5,891
  • 6
  • 37
  • 69
0

LOCK_NB works only when :

  1. File is locked with LOCK_SH and you do a LOCK_EX|LOCK_NB
  2. File is locked with LOCK_EX and you do a LOCK_SH|LOCK_NB

LOCK_NB is ignored if :

  1. File is locked with LOCK_EX and you do a LOCK_EX|LOCK_NB
  2. File is locked with LOCK_SH and you do a LOCK_SH|LOCK_NB

i guess this is a bug ? or they need to make a LOCK_NB2 ? i reported this as a bug to PHP.NET .

EDIT (2012-03-22 still not fixed): https://bugs.php.net/bug.php?id=54453&edit=3 PHP Bug #54453

oxygen
  • 5,891
  • 6
  • 37
  • 69
Rami Dabain
  • 4,709
  • 12
  • 62
  • 106