From f589bf01ca9f0409b3ac40c1ec8a17ef71c0a498 Mon Sep 17 00:00:00 2001 From: Christian Schneider Date: Fri, 14 Aug 2009 13:13:17 +0000 Subject: Close a lock race when lock expires, check existance of file in _waitforlock --- it_url.class | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/it_url.class b/it_url.class index 692f825..5393de9 100644 --- a/it_url.class +++ b/it_url.class @@ -407,7 +407,7 @@ function get_cache($p = array()) { # Wait for file currently being transferred EDC('getcache', "wait", $p['url'], $path); - $result = it_url::_waitforlock($path, $p); + $result = it_url::_waitforlockedfile($path, $p); } } else @@ -455,7 +455,7 @@ function get_cache($p = array()) { # Wait for file currently being processed EDC('getcache', "processwait", $p['url'], $path); - $result = it_url::_waitforlock($path, $p); + $result = it_url::_waitforlockedfile($path, $p); } } } @@ -500,11 +500,8 @@ function _expired($path, $maxage) */ function _lock($path) { - # expire forgotten locks - if (($mtime = @filemtime("$path.lock")) && (time() - $mtime > 30)) - @unlink("$path.lock"); - - return @fopen("$path.lock", EDC('nocache') ? "w" : "x"); + $force = EDC('nocache') || (($mtime = @filemtime("$path.lock")) && (time() - $mtime > 30)); # expire forgotten locks + return @fopen("$path.lock", $force ? "w" : "x"); } /** @@ -519,26 +516,26 @@ function _unlock($path, $lock) } /** - * Wait for lock on a file to be released - * @param $path File to wait for lock + * Wait for file which is currently locked + * @param $path File to wait for * @param $p Wait parameters, see @get_cache - * @return Whether lock was released within timeout + * @return Whether lock was released within timeout and file is still there */ -function _waitforlock($path, $p) +function _waitforlockedfile($path, $p) { $sleeptime = 0.1; # seconds to wait per pass # wait until cache is ready, then read from cache - for ($maxpasses = $p['timeout'] / $sleeptime, $passes = 0; ($result = file_exists("$path.lock")) && ($passes < $maxpasses); ++$passes) + for ($maxpasses = $p['timeout'] / $sleeptime, $passes = 0; ($lockedbyother = file_exists("$path.lock")) && ($passes < $maxpasses); ++$passes) { usleep($sleeptime * 1000000); clearstatcache(); } - if ($result && $p['safety'] == 1) + if ($lockedbyother && $p['safety'] == 1) it::error(($passes < $maxpasses ? "error getting url" : "timeout") . " in it_url::get_cache(): url={$p['url']}, passes=$passes, maxpasses=$maxpasses, path={$p['path']}"); - return !$result; + return !$lockedbyother && file_exists($path); } /** -- cgit v1.2.3