Bug #68509 [NEW]: Garbage collection of file pointers releases flock() locks erroneously
| From: | markamery at btinternet dot com | Date: | Wed, 26 Nov 2014 21:17:13 +0000 |
| Subject: | Bug #68509 [NEW]: Garbage collection of file pointers releases flock() locks erroneously | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-188808@lists.php.net to get a copy of this message | ||
From: markamery at btinternet dot com
Operating system: Unix
PHP version: master-Git-2014-11-26 (Git)
Package: Filesystem function related
Bug Type: Bug
Bug description:Garbage collection of file pointers releases flock() locks erroneously
Description:
------------
If you acquire a file pointer with fopen() from within a function, then
take out a lock on it with flock(), the lock gets released when the
function returns unless you keep a reference to the file pointer in
scope to prevent it from being garbage collected.
This seems wrong on two counts:
* It's unintuitive to the user that implicit garbage collection could be
affecting their locks; the user should be protected from such concerns.
In any case, this interaction between garbage collection and locks is
undocumented.
* It appears to contradict the documentation at
http://php.net/manual/en/function.flock.php
which claims that:
> The automatic unlocking when the file's resource handle is
closed was removed. Unlocking now always has to be done manually.
In fact, it is the case that both explicit fclose() calls and the file
pointer being garbage collected result in the lock being released,
contrary to the documentation.
This should probably be fixed by tracking whether a file pointer has
been locked with flock(), and suppressing the garbage collection of file
pointers for which there are active flock() locks.
Related: I have previously posted a question and answer on Stack
Overflow about this issue:
http://stackoverflow.com/questions/24351769/flock-call-within-function-always-succeeds-ignoring-previous-lock
Test script:
---------------
<?php
function acquire_lock () {
$file_handle = fopen('mylock.lock', 'w');
$got_lock_successfully = flock($file_handle, LOCK_EX);
if (!$got_lock_successfully) {
throw new Exception("Unexpected failure to acquire lock.");
}
}
acquire_lock();
echo "Acquired lock\n";
sleep(10);
echo "terminating\n";
?>
Expected result:
----------------
When starting the test script above in two terminals in rapid
succession, the second terminal should not display the "Acquired lock"
message until the first terminal has shown the "terminating" message.
Actual result:
--------------
The second terminal shows the "Acquired lock" message as soon as the
script is started, before the first script has shown the "terminating"
message.
--
Edit bug report at https://bugs.php.net/bug.php?id=68509&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=68509&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=68509&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=68509&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=68509&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=68509&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=68509&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=68509&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=68509&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=68509&r=support
Expected behavior: https://bugs.php.net/fix.php?id=68509&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=68509&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=68509&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=68509&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=68509&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=68509&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=68509&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=68509&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=68509&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=68509&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=68509&r=mysqlcfg