Project

General

Profile

Bug #18279 » 0007630_v2.patch

Administrator Admin, 2008-02-25 18:28

View differences:

t3lib/class.t3lib_lock.php (Arbeitskopie)
class t3lib_lock {
private $method;
private $id; // Identifier used for this lock
private $resource; // Resource used for this lock (can be a file or a semaphore resource)
private $filepointer;
private $isAcquired = false;
......
}
// Detect locking method
if (in_array($method, array('disable', 'simple','flock','semaphore'))) {
if (in_array($method, array('disable', 'simple', 'flock', 'semaphore'))) {
$this->method = $method;
} else {
throw new Exception('No such method "'.$method.'"');
......
case 'simple':
case 'flock':
$path = PATH_site.'typo3temp/locks/';
$this->id = $path.md5($id);
if (!is_dir($path)) {
t3lib_div::mkdir($path);
}
$this->id = md5($id);
$this->resource = $path.$this->id;
$success = true;
break;
case 'semaphore':
$id = abs(crc32($id));
if (($this->id = sem_get($id, 1))==true) {
$this->id = abs(crc32($id));
if (($this->resource = sem_get($this->id, 1))==true) {
$success = true;
}
break;
......
switch ($this->method) {
case 'simple':
if (is_file($this->id)) {
if (is_file($this->resource)) {
$this->sysLog('Waiting for a different process to release the lock');
$i = 0;
while ($i<$this->loops) {
$i++;
usleep($this->step*1000);
clearstatcache();
if (!is_file($this->id)) { // Lock became free, leave the loop
if (!is_file($this->resource)) { // Lock became free, leave the loop
$this->sysLog('Different process released the lock');
$noWait = false;
break;
}
......
$noWait = true;
}
if (($this->filepointer = touch($this->id)) == false) {
if (($this->filepointer = touch($this->resource)) == false) {
throw new Exception('Lock file could not be created');
}
break;
case 'flock':
if (($this->filepointer = fopen($this->id, 'w+')) == false) {
if (($this->filepointer = fopen($this->resource, 'w+')) == false) {
throw new Exception('Lock file could not be opened');
}
......
} elseif (flock($this->filepointer, LOCK_EX) == true) { // Lock with blocking (waiting for similar locks to become released)
$noWait = false;
} else {
throw new Exception('Could not lock file "'.$this->id.'"');
throw new Exception('Could not lock file "'.$this->resource.'"');
}
break;
case 'semaphore':
if (sem_acquire($this->id)) {
if (sem_acquire($this->resource)) {
// Unfortunately it seems not possible to find out if the request was blocked, so we return false in any case to make sure the operation is tried again.
$noWait = false;
}
......
$success = true;
switch ($this->method) {
case 'simple':
if (unlink($this->id) == false) {
if (unlink($this->resource) == false) {
$success = false;
}
break;
......
$success = false;
}
fclose($this->filepointer);
unlink($this->id);
unlink($this->resource);
break;
case 'semaphore':
if (!sem_release($this->id)) {
if (sem_release($this->resource)) {
sem_remove($this->resource);
} else {
$success = false;
}
break;
......
}
/**
* Return the ID of which is currently used
* Return the ID which is currently used
*
* @return string Locking ID
*/
......
}
/**
* Return the resource which is currently used.
* Depending on the locking method this can be a filename or a semaphore resource.
*
* @return mixed Locking resource (filename as string or semaphore as resource)
*/
public function getResource() {
return $this->resource;
}
/**
* Return the status of a lock
*
* @return string Returns true if lock is acquired, false otherwise
......
public function getLockStatus() {
return $this->isAcquired;
}
/**
* Adds a common log entry for this locking API using t3lib_div::sysLog().
* Example: 25-02-08 17:58 - cms: Locking [simple::0aeafd2a67a6bb8b9543fb9ea25ecbe2]: Acquired
*
* @param string $message: The message to be logged
* @param integer $severity: Severity - 0 is info (default), 1 is notice, 2 is warning, 3 is error, 4 is fatal error
* @return void
*/
public function sysLog($message, $severity=0) {
t3lib_div::sysLog('Locking ['.$this->method.'::'.$this->id.']: '.trim($message), 'cms', $severity);
}
}
typo3/sysext/cms/tslib/class.tslib_fe.php (Arbeitskopie)
* Lock the page generation process
* The lock is used to queue page requests until this page is successfully stored in the cache.
*
* @param object Reference to a locking object
* @param t3lib_lock Reference to a locking object
* @param string String to identify the lock in the system
* @return boolean Returns true if the lock could be obtained, false otherwise (= process had to wait for existing lock to be released)
* @see releasePageGenerationLock()
*/
function acquirePageGenerationLock(&$lockObj, $key) {
if ($this->no_cache || $this->headerNoCache()) {
$lockObj->sysLog('Page is not cached, no locking required');
return true; // No locking is needed if caching is disabled
}
......
// true = Page could get locked without blocking
// false = Page could get locked but process was blocked before
$success = $lockObj->acquire();
if ($lockObj->getLockStatus()) {
$lockObj->sysLog('Acquired lock');
}
}
} catch (Exception $e) {
t3lib_div::sysLog('Locking failed: '.$e->getMessage(), 'cms', 3);
$lockObj->sysLog('Failed to acquire lock: '.$e->getMessage(), 3);
$success = false; // If locking fails, return with false and continue without locking
}
......
/**
* Release the page generation lock
*
* @param object Reference to a locking object
* @param t3lib_lock Reference to a locking object
* @return boolean Returns true on success, false otherwise
* @see acquirePageGenerationLock()
*/
function releasePageGenerationLock(&$lockObj) {
if ($this->no_cache || $this->headerNoCache()) {
return true; // No locking is needed if caching is disabled
}
$success = false;
if (is_object($lockObj)) {
// If lock object is set and was aquired (may also happen if no_cache was enabled during runtime), release it:
if (is_object($lockObj) && $lockObj instanceof t3lib_lock && $lockObj->getLockStatus()) {
$success = $lockObj->release();
$lockObj->sysLog('Released lock');
unset($lockObj);
// Otherwise, if caching is disabled, no locking is required:
} elseif ($this->no_cache || $this->headerNoCache()) {
$success = true;
}
return $success;
}
(3-3/4)