[!!!][TASK] Remove old locking API 24/45424/6
authorBenni Mack <benni@typo3.org>
Wed, 23 Dec 2015 18:53:14 +0000 (19:53 +0100)
committerWouter Wolters <typo3@wouterwolters.nl>
Thu, 24 Dec 2015 10:48:07 +0000 (11:48 +0100)
Resolves: #72417
Releases: master
Change-Id: I2f3349ca4dfeb1a3c3e1747db6ac42d492fa979a
Reviewed-on: https://review.typo3.org/45424
Reviewed-by: Markus Klein <markus.klein@typo3.org>
Tested-by: Markus Klein <markus.klein@typo3.org>
Reviewed-by: Wouter Wolters <typo3@wouterwolters.nl>
Tested-by: Wouter Wolters <typo3@wouterwolters.nl>
typo3/sysext/core/Classes/Locking/Locker.php [deleted file]
typo3/sysext/core/Configuration/DefaultConfiguration.php
typo3/sysext/core/Documentation/Changelog/master/Breaking-72417-RemovedOldLockingAPI.rst [new file with mode: 0644]
typo3/sysext/core/Tests/Unit/Locking/LockerTest.php [deleted file]
typo3/sysext/install/Classes/Service/SilentConfigurationUpgradeService.php

diff --git a/typo3/sysext/core/Classes/Locking/Locker.php b/typo3/sysext/core/Classes/Locking/Locker.php
deleted file mode 100644 (file)
index 316ac0b..0000000
+++ /dev/null
@@ -1,509 +0,0 @@
-<?php
-namespace TYPO3\CMS\Core\Locking;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Utility\GeneralUtility;
-
-/**
- * TYPO3 locking class
- * This class provides an abstract layer to various locking features for TYPO3
- *
- * It is intended to blocks requests until some data has been generated.
- * This is especially useful if two clients are requesting the same website short after each other. While the request of client 1 triggers building and caching of the website, client 2 will be waiting at this lock.
- */
-class Locker
-{
-    const LOCKING_METHOD_SIMPLE = 'simple';
-    const LOCKING_METHOD_FLOCK = 'flock';
-    const LOCKING_METHOD_SEMAPHORE = 'semaphore';
-    const LOCKING_METHOD_DISABLED = 'disable';
-
-    const FILE_LOCK_FOLDER = 'typo3temp/locks/';
-
-    /**
-     * @var string Locking method: One of the constants above
-     */
-    protected $method = '';
-
-    /**
-     * @var mixed Identifier used for this lock
-     */
-    protected $id;
-
-    /**
-     * @var mixed Resource used for this lock (can be a file or a semaphore resource)
-     */
-    protected $resource;
-
-    /**
-     * @var resource File pointer if using flock method
-     */
-    protected $filePointer;
-
-    /**
-     * @var bool True if lock is acquired
-     */
-    protected $isAcquired = false;
-
-    /**
-     * @var int Number of times a locked resource is tried to be acquired. Only used in manual locks method "simple".
-     */
-    protected $loops = 150;
-
-    /**
-     * @var int Milliseconds after lock acquire is retried. $loops * $step results in the maximum delay of a lock. Only used in manual lock method "simple".
-     */
-    protected $step = 200;
-
-    /**
-     * @var string Logging facility
-     */
-    protected $syslogFacility = 'cms';
-
-    /**
-     * @var bool True if locking should be logged
-     */
-    protected $isLoggingEnabled = true;
-
-    /**
-     * Constructor:
-     * initializes locking, check input parameters and set variables accordingly.
-     *
-     * Parameters $loops and $step only apply to the locking method LOCKING_METHOD_SIMPLE.
-     *
-     * @param string $id ID to identify this lock in the system
-     * @param string $method Define which locking method to use. Use one of the LOCKING_METHOD_* constants. Defaults to LOCKING_METHOD_SIMPLE. Use '' to use setting from Install Tool.
-     * @param int $loops Number of times a locked resource is tried to be acquired.
-     * @param int $step Milliseconds after lock acquire is retried. $loops * $step results in the maximum delay of a lock.
-     * @throws \RuntimeException
-     * @throws \InvalidArgumentException
-     * @deprecated since TYPO3 CMS 7, will be removed with TYPO3 CMS 8
-     */
-    public function __construct($id, $method = self::LOCKING_METHOD_SIMPLE, $loops = 0, $step = 0)
-    {
-        GeneralUtility::logDeprecatedFunction();
-        // Force ID to be string
-        $id = (string)$id;
-        if ((int)$loops) {
-            $this->loops = (int)$loops;
-        }
-        if ((int)$step) {
-            $this->step = (int)$step;
-        }
-        if ($method === '' && isset($GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode'])) {
-            $method = (string)$GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode'];
-        }
-
-        switch ($method) {
-            case self::LOCKING_METHOD_SIMPLE:
-                // intended fall through
-            case self::LOCKING_METHOD_FLOCK:
-                $this->id = md5($id);
-                $this->createPathIfNeeded();
-                break;
-            case self::LOCKING_METHOD_SEMAPHORE:
-                $this->id = abs(crc32($id));
-                break;
-            case self::LOCKING_METHOD_DISABLED:
-                break;
-            default:
-                throw new \InvalidArgumentException('No such locking method "' . $method . '"', 1294586097);
-        }
-        $this->method = $method;
-    }
-
-    /**
-     * Destructor:
-     * Releases lock automatically when instance is destroyed and release resources
-     */
-    public function __destruct()
-    {
-        $this->release();
-        switch ($this->method) {
-            case self::LOCKING_METHOD_FLOCK:
-                if (
-                    GeneralUtility::isAllowedAbsPath($this->resource)
-                    && GeneralUtility::isFirstPartOfStr($this->resource, PATH_site . self::FILE_LOCK_FOLDER)
-                ) {
-                    @unlink($this->resource);
-                }
-                break;
-            case self::LOCKING_METHOD_SEMAPHORE:
-                @sem_remove($this->resource);
-                break;
-            default:
-                // do nothing
-        }
-    }
-
-    /**
-     * Tries to allocate the semaphore
-     *
-     * @return void
-     * @throws \RuntimeException
-     */
-    protected function getSemaphore()
-    {
-        $this->resource = sem_get($this->id, 1);
-        if ($this->resource === false) {
-            throw new \RuntimeException('Unable to get semaphore with id ' . $this->id, 1313828196);
-        }
-    }
-
-    /**
-     * Acquire a lock and return when successful.
-     *
-     * It is important to know that the lock will be acquired in any case, even if the request was blocked first.
-     * Therefore, the lock needs to be released in every situation.
-     *
-     * @return bool Returns TRUE if lock could be acquired without waiting, FALSE otherwise.
-     * @throws \RuntimeException
-     * @deprecated since 6.2 - will be removed two versions later; use new API instead
-     */
-    public function acquire()
-    {
-        // @todo refactor locking in TSFE to use the new API, then this call can be logged
-        // GeneralUtility::logDeprecatedFunction();
-
-        // Default is TRUE, which means continue without caring for other clients.
-        // In the case of TYPO3s cache management, this has no negative effect except some resource overhead.
-        $noWait = false;
-        $isAcquired = false;
-        switch ($this->method) {
-            case self::LOCKING_METHOD_SIMPLE:
-                if (file_exists($this->resource)) {
-                    $this->sysLog('Waiting for a different process to release the lock');
-                    $maxExecutionTime = (int)ini_get('max_execution_time');
-                    $maxAge = time() - ($maxExecutionTime ?: 120);
-                    if (@filectime($this->resource) < $maxAge) {
-                        @unlink($this->resource);
-                        $this->sysLog('Unlinking stale lockfile', GeneralUtility::SYSLOG_SEVERITY_WARNING);
-                    }
-                }
-                for ($i = 0; $i < $this->loops; $i++) {
-                    $filePointer = @fopen($this->resource, 'x');
-                    if ($filePointer !== false) {
-                        fclose($filePointer);
-                        GeneralUtility::fixPermissions($this->resource);
-                        $this->sysLog('Lock acquired');
-                        $noWait = $i === 0;
-                        $isAcquired = true;
-                        break;
-                    }
-                    usleep($this->step * 1000);
-                }
-                if (!$isAcquired) {
-                    throw new \RuntimeException('Lock file could not be created', 1294586098);
-                }
-                break;
-            case self::LOCKING_METHOD_FLOCK:
-                $this->filePointer = fopen($this->resource, 'c');
-                if ($this->filePointer === false) {
-                    throw new \RuntimeException('Lock file could not be opened', 1294586099);
-                }
-                // Lock without blocking
-                if (flock($this->filePointer, LOCK_EX | LOCK_NB)) {
-                    $noWait = true;
-                } elseif (flock($this->filePointer, LOCK_EX)) {
-                    // Lock with blocking (waiting for similar locks to become released)
-                    $noWait = false;
-                } else {
-                    throw new \RuntimeException('Could not lock file "' . $this->resource . '"', 1294586100);
-                }
-                $isAcquired = true;
-                break;
-            case self::LOCKING_METHOD_SEMAPHORE:
-                $this->getSemaphore();
-                while (!$isAcquired) {
-                    if (@sem_acquire($this->resource)) {
-                        // Unfortunately it is not possible to find out if the request has blocked,
-                        // as sem_acquire will block until we get the resource.
-                        // So we do not set $noWait here at all
-                        $isAcquired = true;
-                    }
-                }
-                break;
-            case self::LOCKING_METHOD_DISABLED:
-                break;
-            default:
-                // will never be reached
-        }
-        $this->isAcquired = $isAcquired;
-        return $noWait;
-    }
-
-    /**
-     * Try to acquire an exclusive lock
-     *
-     * @throws \RuntimeException
-     * @return bool Returns TRUE if the lock was acquired successfully
-     */
-    public function acquireExclusiveLock()
-    {
-        if ($this->isAcquired) {
-            return true;
-        }
-        $this->isAcquired = false;
-        switch ($this->method) {
-            case self::LOCKING_METHOD_SIMPLE:
-                if (file_exists($this->resource)) {
-                    $this->sysLog('Waiting for a different process to release the lock');
-                    $maxExecutionTime = (int)ini_get('max_execution_time');
-                    $maxAge = time() - ($maxExecutionTime ?: 120);
-                    if (@filectime($this->resource) < $maxAge) {
-                        @unlink($this->resource);
-                        $this->sysLog('Unlinking stale lockfile', GeneralUtility::SYSLOG_SEVERITY_WARNING);
-                    }
-                }
-                for ($i = 0; $i < $this->loops; $i++) {
-                    $filePointer = @fopen($this->resource, 'x');
-                    if ($filePointer !== false) {
-                        fclose($filePointer);
-                        GeneralUtility::fixPermissions($this->resource);
-                        $this->sysLog('Lock acquired');
-                        $this->isAcquired = true;
-                        break;
-                    }
-                    usleep($this->step * 1000);
-                }
-                break;
-            case self::LOCKING_METHOD_FLOCK:
-                $this->filePointer = fopen($this->resource, 'c');
-                if ($this->filePointer === false) {
-                    throw new \RuntimeException('Lock file could not be opened', 1294586099);
-                }
-                if (flock($this->filePointer, LOCK_EX)) {
-                    $this->isAcquired = true;
-                }
-                break;
-            case self::LOCKING_METHOD_SEMAPHORE:
-                $this->getSemaphore();
-                if (@sem_acquire($this->resource)) {
-                    $this->isAcquired = true;
-                }
-                break;
-            case self::LOCKING_METHOD_DISABLED:
-                break;
-            default:
-                // will never be reached
-        }
-        return $this->isAcquired;
-    }
-
-    /**
-     * Try to acquire a shared lock
-     *
-     * (Only works for the flock() locking method currently)
-     *
-     * @return bool Returns TRUE if the lock was acquired successfully
-     * @throws \RuntimeException
-     */
-    public function acquireSharedLock()
-    {
-        if ($this->isAcquired) {
-            return true;
-        }
-        if ($this->method === self::LOCKING_METHOD_FLOCK) {
-            $this->filePointer = fopen($this->resource, 'c');
-            if ($this->filePointer === false) {
-                throw new \RuntimeException('Lock file could not be opened', 1294586099);
-            }
-            if (flock($this->filePointer, LOCK_SH)) {
-                $this->isAcquired = true;
-            }
-        }
-        return $this->isAcquired;
-    }
-
-    /**
-     * Release the lock
-     *
-     * @return bool Returns TRUE on success or FALSE on failure
-     */
-    public function release()
-    {
-        if (!$this->isAcquired) {
-            return true;
-        }
-        $success = true;
-        switch ($this->method) {
-            case self::LOCKING_METHOD_SIMPLE:
-                if (
-                    GeneralUtility::isAllowedAbsPath($this->resource)
-                    && GeneralUtility::isFirstPartOfStr($this->resource, PATH_site . self::FILE_LOCK_FOLDER)
-                ) {
-                    if (@unlink($this->resource) === false) {
-                        $success = false;
-                    }
-                }
-                break;
-            case self::LOCKING_METHOD_FLOCK:
-                if (is_resource($this->filePointer)) {
-                    if (flock($this->filePointer, LOCK_UN) === false) {
-                        $success = false;
-                    }
-                    fclose($this->filePointer);
-                }
-                break;
-            case self::LOCKING_METHOD_SEMAPHORE:
-                if (!@sem_release($this->resource)) {
-                    $success = false;
-                }
-                break;
-            case self::LOCKING_METHOD_DISABLED:
-                break;
-            default:
-                // will never be reached
-        }
-        $this->isAcquired = false;
-        return $success;
-    }
-
-    /**
-     * Return the locking method which is currently used
-     *
-     * @return string Locking method
-     */
-    public function getMethod()
-    {
-        return $this->method;
-    }
-
-    /**
-     * Return the ID which is currently used
-     *
-     * @return string Locking ID
-     */
-    public function getId()
-    {
-        return $this->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 local status of a lock
-     *
-     * @return bool Returns TRUE if lock is acquired by this process, FALSE otherwise
-     */
-    public function getLockStatus()
-    {
-        return $this->isAcquired;
-    }
-
-    /**
-     * Return the global status of the lock
-     *
-     * @return bool Returns TRUE if the lock is locked by either this or another process, FALSE otherwise
-     */
-    public function isLocked()
-    {
-        $result = false;
-        switch ($this->method) {
-            case self::LOCKING_METHOD_SIMPLE:
-                if (file_exists($this->resource)) {
-                    $maxExecutionTime = (int)ini_get('max_execution_time');
-                    $maxAge = time() - ($maxExecutionTime ?: 120);
-                    if (@filectime($this->resource) < $maxAge) {
-                        @unlink($this->resource);
-                        $this->sysLog('Unlinking stale lockfile', GeneralUtility::SYSLOG_SEVERITY_WARNING);
-                    } else {
-                        $result = true;
-                    }
-                }
-                break;
-            case self::LOCKING_METHOD_FLOCK:
-                // we can't detect this reliably here, since the third parameter of flock() does not work on windows
-                break;
-            case self::LOCKING_METHOD_SEMAPHORE:
-                // no way to detect this at all, no PHP API for that
-                break;
-            case self::LOCKING_METHOD_DISABLED:
-                break;
-            default:
-                // will never be reached
-        }
-        return $result;
-    }
-
-    /**
-     * Sets the facility (extension name) for the syslog entry.
-     *
-     * @param string $syslogFacility
-     */
-    public function setSyslogFacility($syslogFacility)
-    {
-        $this->syslogFacility = $syslogFacility;
-    }
-
-    /**
-     * Enable/ disable logging
-     *
-     * @param bool $isLoggingEnabled
-     */
-    public function setEnableLogging($isLoggingEnabled)
-    {
-        $this->isLoggingEnabled = $isLoggingEnabled;
-    }
-
-    /**
-     * Adds a common log entry for this locking API using \TYPO3\CMS\Core\Utility\GeneralUtility::sysLog().
-     * Example: 25-02-08 17:58 - cms: Locking [simple::0aeafd2a67a6bb8b9543fb9ea25ecbe2]: Acquired
-     *
-     * @param string $message The message to be logged
-     * @param int $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)
-    {
-        if ($this->isLoggingEnabled) {
-            GeneralUtility::sysLog('Locking [' . $this->method . '::' . $this->id . ']: ' . trim($message), $this->syslogFacility, $severity);
-        }
-    }
-
-    /**
-     * Tests if the directory for simple locks is available.
-     * If not, the directory will be created. The lock path is usually
-     * below typo3temp, typo3temp itself should exist already
-     *
-     * @return void
-     * @throws \RuntimeException If path couldn't be created.
-     */
-    protected function createPathIfNeeded()
-    {
-        $path = PATH_site . self::FILE_LOCK_FOLDER;
-        if (!is_dir($path)) {
-            // Not using mkdir_deep on purpose here, if typo3temp itself
-            // does not exist, this issue should be solved on a different
-            // level of the application.
-            if (!GeneralUtility::mkdir($path)) {
-                throw new \RuntimeException('Cannot create directory ' . $path, 1395140007);
-            }
-        }
-        if (!is_writable($path)) {
-            throw new \RuntimeException('Cannot write to directory ' . $path, 1396278700);
-        }
-        $this->resource = $path . $this->id;
-    }
-}
index f5ba25b..8992ae2 100644 (file)
@@ -105,7 +105,6 @@ return array(
         'maxFileNameLength' => 60,                // Integer: This is the maximum file name length. The value will be taken into account by basic file operations like renaming or creation of files and folders.
         'UTF8filesystem' => false,                // Boolean: If TRUE then TYPO3 uses utf-8 to store file names. This allows for accented Latin letters as well as any other non-latin characters like Cyrillic and Chinese.
         'systemLocale' => '',                    // String: locale used for certain system related functions, e.g. escaping shell commands. If problems with filenames containing special characters occur, the value of this option is probably wrong. See <a href="http://php.net/manual/en/function.setlocale.php" target="_blank">setlocale()</a>.
-        'lockingMode' => 'simple',                // String: *deprecated* Define which locking mode is used to control requests to pages being generated. Can be one of either "disable" (no locking), "simple" (checks for file existence), "flock" (using PHPs <a href="http://php.net/flock" target="_blank">flock()</a> function), "semaphore" (using PHPs <a href="http://php.net/sem-acquire" target="_blank">sem_acquire()</a> function). Default is "simple". (This option is deprecated since TYPO3 CMS 7 and will be removed in TYPO3 CMS 8. The option is only used by extensions using the old Locker.)
         'reverseProxyIP' => '',                    // String: list of IP addresses. If TYPO3 is behind one or more (intransparent) reverse proxies the IP addresses must be added here.
         'reverseProxyHeaderMultiValue' => 'none',    // String: "none","first","last": defines which values of a proxy header (eg HTTP_X_FORWARDED_FOR) to use, if more than one is found. "none" discards the value, "first" and "last" use the first/last of the values in the list.
         'reverseProxyPrefix' => '',                // String: optional prefix to be added to the internal URL (SCRIPT_NAME and REQUEST_URI).
diff --git a/typo3/sysext/core/Documentation/Changelog/master/Breaking-72417-RemovedOldLockingAPI.rst b/typo3/sysext/core/Documentation/Changelog/master/Breaking-72417-RemovedOldLockingAPI.rst
new file mode 100644 (file)
index 0000000..8f5e5b8
--- /dev/null
@@ -0,0 +1,16 @@
+==========================================
+Breaking: #72417 - Removed old locking API
+==========================================
+
+Description
+===========
+
+The old locking mechanism was replaced by a more sophisticated a robust LockFactory,
+and is now completely removed from the TYPO3 Core.
+
+
+Impact
+======
+
+Using the ``Locker`` class will result in a fatal error. The option ``$TYPO3_CONF_VARS[SYS][lockingMode]`` has
+no effect anymore.
\ No newline at end of file
diff --git a/typo3/sysext/core/Tests/Unit/Locking/LockerTest.php b/typo3/sysext/core/Tests/Unit/Locking/LockerTest.php
deleted file mode 100644 (file)
index 0b6081c..0000000
+++ /dev/null
@@ -1,234 +0,0 @@
-<?php
-namespace TYPO3\CMS\Core\Tests\Unit\Locking;
-
-/*
- * This file is part of the TYPO3 CMS project.
- *
- * It is free software; you can redistribute it and/or modify it under
- * the terms of the GNU General Public License, either version 2
- * of the License, or any later version.
- *
- * For the full copyright and license information, please read the
- * LICENSE.txt file that was distributed with this source code.
- *
- * The TYPO3 project - inspiring people to share!
- */
-
-use TYPO3\CMS\Core\Locking\Locker;
-
-/**
- * Testcase for \TYPO3\CMS\Core\Locking\Locker
- */
-class LockerTest extends \TYPO3\CMS\Core\Tests\UnitTestCase
-{
-    ///////////////////////////////
-    // tests concerning __construct
-    ///////////////////////////////
-    /**
-     * @test
-     */
-    public function constructorUsesDefaultLockingMethodSimple()
-    {
-        $instance = new Locker('999999999');
-        $this->assertSame(Locker::LOCKING_METHOD_SIMPLE, $instance->getMethod());
-    }
-
-    /**
-     * @test
-     */
-    public function constructorSetsMethodToGivenParameter()
-    {
-        $instance = new Locker('999999999', Locker::LOCKING_METHOD_FLOCK);
-        $this->assertSame(Locker::LOCKING_METHOD_FLOCK, $instance->getMethod());
-    }
-
-    /**
-     * @test
-     * @expectedException \InvalidArgumentException
-     */
-    public function constructorThrowsExceptionForNotExistingLockingMethod()
-    {
-        new Locker('999999999', 'foo');
-    }
-
-    /**
-     * @test
-     */
-    public function constructorFetchesInstallToolConfigurationIfEmptyMethod()
-    {
-        $GLOBALS['TYPO3_CONF_VARS']['SYS']['lockingMode'] = Locker::LOCKING_METHOD_SIMPLE;
-        $instance = new Locker('999999999', '');
-        $this->assertSame(Locker::LOCKING_METHOD_SIMPLE, $instance->getMethod());
-    }
-
-    /**
-     * @test
-     */
-    public function constructorUsesDefaultValueForLoops()
-    {
-        $instance = $this->getAccessibleMock(\TYPO3\CMS\Core\Locking\Locker::class, array('dummy'), array('999999999', Locker::LOCKING_METHOD_DISABLED));
-        $this->assertSame(150, $instance->_get('loops'));
-    }
-
-    /**
-     * @test
-     */
-    public function constructorSetsLoopsToGivenNumberOfLoops()
-    {
-        $instance = $this->getAccessibleMock(\TYPO3\CMS\Core\Locking\Locker::class, array('dummy'), array('999999999', Locker::LOCKING_METHOD_DISABLED, 10));
-        $this->assertSame(10, $instance->_get('loops'));
-    }
-
-    /**
-     * @test
-     */
-    public function constructorUsesDefaultValueForSteps()
-    {
-        $instance = $this->getAccessibleMock(\TYPO3\CMS\Core\Locking\Locker::class, array('dummy'), array('999999999', Locker::LOCKING_METHOD_DISABLED));
-        $this->assertSame(200, $instance->_get('step'));
-    }
-
-    /**
-     * @test
-     */
-    public function constructorSetsStepToGivenNumberOfStep()
-    {
-        $instance = $this->getAccessibleMock(\TYPO3\CMS\Core\Locking\Locker::class, array('dummy'), array('999999999', Locker::LOCKING_METHOD_DISABLED, 0, 10));
-        $this->assertSame(10, $instance->_get('step'));
-    }
-
-    /**
-     * @test
-     */
-    public function constructorCreatesLockDirectoryIfNotExisting()
-    {
-        \TYPO3\CMS\Core\Utility\GeneralUtility::rmdir(PATH_site . Locker::FILE_LOCK_FOLDER, true);
-        new Locker('999999999', Locker::LOCKING_METHOD_SIMPLE);
-        $this->assertTrue(is_dir(PATH_site . Locker::FILE_LOCK_FOLDER));
-    }
-
-    /**
-     * @test
-     */
-    public function constructorSetsIdToMd5OfStringIfUsingSimpleLocking()
-    {
-        $instance = new Locker('999999999', Locker::LOCKING_METHOD_SIMPLE);
-        $this->assertSame(md5('999999999'), $instance->getId());
-    }
-
-    /**
-     * @test
-     */
-    public function constructorSetsResourceToPathWithIdIfUsingSimpleLocking()
-    {
-        $instance = new Locker('999999999', Locker::LOCKING_METHOD_SIMPLE);
-        $this->assertSame(PATH_site . Locker::FILE_LOCK_FOLDER . md5('999999999'), $instance->getResource());
-    }
-
-    /**
-     * @test
-     */
-    public function constructorSetsIdToAbsCrc32OfIdStringIfUsingSemaphoreLocking()
-    {
-        if (!function_exists('sem_get')) {
-            $this->markTestSkipped('The system does not support semaphore base locking.');
-        }
-        $instance = new Locker('999999999', Locker::LOCKING_METHOD_SEMAPHORE);
-        $this->assertSame(abs(crc32('999999999')), $instance->getId());
-    }
-
-    ///////////////////////////////
-    // tests concerning acquire
-    ///////////////////////////////
-    /**
-     * @test
-     */
-    public function acquireFixesPermissionsOnLockFileIfUsingSimpleLogging()
-    {
-        if (TYPO3_OS == 'WIN') {
-            $this->markTestSkipped('acquireFixesPermissionsOnLockFileIfUsingSimpleLogging() test not available on Windows.');
-        }
-        // Use a very high id to be unique
-        $instance = new Locker(999999999, Locker::LOCKING_METHOD_SIMPLE);
-        $instance->setEnableLogging(false);
-        $pathOfLockFile = $instance->getResource();
-        $GLOBALS['TYPO3_CONF_VARS']['SYS']['fileCreateMask'] = '0777';
-        // Acquire lock, get actual file permissions and clean up
-        $instance->acquireExclusiveLock();
-        clearstatcache();
-        $resultFilePermissions = substr(decoct(fileperms($pathOfLockFile)), 2);
-        $instance->release();
-        $this->assertEquals($resultFilePermissions, '0777');
-    }
-
-    ///////////////////////////////
-    // tests concerning release
-    ///////////////////////////////
-
-    /**
-     * @test
-     */
-    public function releaseRemovesLockfileInTypo3TempLocks()
-    {
-        // Use a very high id to be unique
-        $instance = new Locker(999999999, Locker::LOCKING_METHOD_SIMPLE);
-        // Disable logging
-        $instance->setEnableLogging(false);
-        // File pointer to current lock file
-        $lockFile = $instance->getResource();
-        $instance->acquireExclusiveLock();
-        $instance->release();
-        $this->assertFalse(is_file($lockFile));
-    }
-
-    /**
-     * Dataprovider for releaseDoesNotRemoveFilesNotWithinTypo3TempLocksDirectory
-     */
-    public function invalidFileReferences()
-    {
-        return array(
-            'simple not within PATH_site' => array('simple', '/tmp/TYPO3-Lock-Test'),
-            'flock not withing PATH_site' => array('flock', '/tmp/TYPO3-Lock-Test'),
-            'simple directory traversal' => array('simple', PATH_site . 'typo3temp/../typo3temp/locks/foo'),
-            'flock directory traversal' => array('flock', PATH_site . 'typo3temp/../typo3temp/locks/foo'),
-            'simple directory traversal 2' => array('simple', PATH_site . 'typo3temp/locks/../locks/foo'),
-            'flock directory traversal 2' => array('flock', PATH_site . 'typo3temp/locks/../locks/foo'),
-            'simple within uploads' => array('simple', PATH_site . 'uploads/TYPO3-Lock-Test'),
-            'flock within uploads' => array('flock', PATH_site . 'uploads/TYPO3-Lock-Test')
-        );
-    }
-
-    /**
-     * @test
-     * @dataProvider invalidFileReferences
-     */
-    public function releaseDoesNotRemoveFilesNotWithinTypo3TempLocksDirectory($lockMethod, $file)
-    {
-        if (TYPO3_OS === 'WIN') {
-            $this->markTestSkipped('releaseDoesNotRemoveFilesNotWithinTypo3TempLocksDirectory() test not available on Windows.');
-        }
-        // Create test file
-        touch($file);
-        if (!is_file($file)) {
-            $this->markTestSkipped('releaseDoesNotRemoveFilesNotWithinTypo3TempLocksDirectory() skipped: Test file could not be created');
-        }
-        // Create instance, set lockfile to invalid path
-        $instance = new Locker(999999999, $lockMethod);
-        $instance->setEnableLogging(false);
-        $t3libLockReflection = new \ReflectionClass(\TYPO3\CMS\Core\Locking\Locker::class);
-        $t3libLockReflectionResourceProperty = $t3libLockReflection->getProperty('resource');
-        $t3libLockReflectionResourceProperty->setAccessible(true);
-        $t3libLockReflectionResourceProperty->setValue($instance, $file);
-        $t3libLockReflectionAcquiredProperty = $t3libLockReflection->getProperty('isAcquired');
-        $t3libLockReflectionAcquiredProperty->setAccessible(true);
-        $t3libLockReflectionAcquiredProperty->setValue($instance, true);
-        // Call release method
-        $instance->release();
-        // Check if file is still there and clean up
-        $fileExists = is_file($file);
-        if (is_file($file)) {
-            unlink($file);
-        }
-        $this->assertTrue($fileExists);
-    }
-}
index e214893..09deb6a 100755 (executable)
@@ -70,6 +70,8 @@ class SilentConfigurationUpgradeService
         'INSTALL/wizardDone/TYPO3\\CMS\\Rtehtmlarea\\Hook\\Install\\RteAcronymButtonRenamedToAbbreviation',
         // #72400
         'BE/spriteIconGenerator_handler',
+        // #72417
+        'SYS/lockingMode',
     );
 
     /**