note 64150 added to function.flock

From: 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

« previous php.notes (#107568) next »