note 64150 added to function.flock
| From: | wildcat at brightNOSPAMpages dot net | Date: | Sat, 08 Apr 2006 18:48:46 +0000 |
| Subject: | note 64150 added to function.flock | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-107568@lists.php.net to get a copy of this message | ||
I wrote the following function to make a script wait in a queue of instances accessing the same
shared resource and then lock it, as a part of a lock-access-release advisory mechanism based on
locking directories.
It works on my web site (also passes the loop test proposed by dranger below). Might show
unpredicted behaviors on other systems, under conditions I didn't think at or produce,
expecially when mkdir atomicity is not guaranteed.
The whole script is too long for posting, but everyone interested in looking for eventual bugs,
testing, torturing and using it, can download code and documentation from http://brightpages.net/doc > QLCK.
Hope it is useful.
<?php
function qLock($lockSuffix, $tmpDir, $maxWait, $padLength) {
if ($tmpDir == '' or !is_dir($tmpDir)) $tmpDir = '.';
$maxWait = (int) $maxWait; if ($maxWait <= 0) $maxWait = 60;
$padLength = (int) $padLength; if ($padLength <= 0) $padLength = 6;
if ($lockSuffix == '') {
return false;
} else {
$currentdir = getcwd();
chdir($tmpDir); // relative to the current directory
$n = 0;
$lockdirs = glob('*-*.'.$lockSuffix, GLOB_ONLYDIR) or array();
foreach($lockdirs as $lockdir) {
list($m, ) = explode('-', $lockdir);
$m = intval($m);
if ($m > $n) $n = $m + 1;
}
$npad = str_pad((string) $n, $padLength, '0', STR_PAD_LEFT);
while (glob($npad.'-*.'.$lockSuffix, GLOB_ONLYDIR)) {
$n++;
$npad = str_pad((string) $n, $padLength, '0', STR_PAD_LEFT);
}
$lockname = $npad.'-'.md5(uniqid(rand(), true)).'.'.$lockSuffix;
if (@mkdir($lockname)) {
$nlockdirs = glob($npad.'-*.'.$lockSuffix, GLOB_ONLYDIR) or array();
if (count($nlockdirs) != 1) {
@rmdir($lockname);
return false;
} else {
$prelockdirs = array();
$lockdirs = glob('*-*.'.$lockSuffix, GLOB_ONLYDIR) or array();
foreach($lockdirs as $lockdir) {
list($m, ) = explode('-', $lockdir);
$m = intval($m);
if ($m < $n) $prelockdirs[] = $lockdir;
}
$t0 = time(); $t = 0;
while (count($prelockdirs) != 0 and $t < $maxWait) {
$prelockdirs = array();
$lockdirs = glob('*-*.'.$lockSuffix, GLOB_ONLYDIR) or array();
foreach($lockdirs as $lockdir) {
list($m, ) = explode('-', $lockdir);
$m = intval($m);
if ($m < $n) $prelockdirs[] = $lockdir;
}
$t = time() - $t0;
}
if (count($prelockdirs) != 0) {
@rmdir($lockname);
return false;
} else {
return $lockname;
}
}
} else {
@rmdir($lockname);
return false;
}
chdir($currentdir);
}
}
?>
----
Server IP: 213.92.11.19
Probable Submitter: 82.52.153.104
----
X-Spam-Status: No, hits=3.1 required=5.0 tests=DATE_MISSING,FROM_NO_LOWER
autolearn=no version=2.64
----
Manual Page -- http://www.php.net/manual/en/function.flock.php
Edit -- http://master.php.net/note/edit/64150
Del: integrated -- http://master.php.net/note/delete/64150/integrated
Del: useless -- http://master.php.net/note/delete/64150/useless
Del: bad code -- http://master.php.net/note/delete/64150/bad+code
Del: spam -- http://master.php.net/note/delete/64150/spam
Del: non-english -- http://master.php.net/note/delete/64150/non-english
Del: in docs -- http://master.php.net/note/delete/64150/in+docs
Del: other reasons-- http://master.php.net/note/delete/64150
Reject -- http://master.php.net/note/reject/64150
Search -- http://master.php.net/manage/user-notes.php