File manager - Edit - /home/jardides/www/Jardi-design/images/administrator/Lock.tar
Back
MemcacheLockingProvider.php 0000604 00000007021 15247161423 0012002 0 ustar 00 <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Robin Appelman <robin@icewind.nl> * * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see <http://www.gnu.org/licenses/> * */ namespace OC\Lock; use OCP\IMemcacheTTL; use OCP\Lock\LockedException; use OCP\IMemcache; class MemcacheLockingProvider extends AbstractLockingProvider { /** * @var \OCP\IMemcache */ private $memcache; /** * @param \OCP\IMemcache $memcache * @param int $ttl */ public function __construct(IMemcache $memcache, $ttl = 3600) { $this->memcache = $memcache; $this->ttl = $ttl; } private function setTTL($path) { if ($this->memcache instanceof IMemcacheTTL) { $this->memcache->setTTL($path, $this->ttl); } } /** * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE * @return bool */ public function isLocked($path, $type) { $lockValue = $this->memcache->get($path); if ($type === self::LOCK_SHARED) { return $lockValue > 0; } else if ($type === self::LOCK_EXCLUSIVE) { return $lockValue === 'exclusive'; } else { return false; } } /** * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type) { if ($type === self::LOCK_SHARED) { if (!$this->memcache->inc($path)) { throw new LockedException($path); } } else { $this->memcache->add($path, 0); if (!$this->memcache->cas($path, 0, 'exclusive')) { throw new LockedException($path); } } $this->setTTL($path); $this->markAcquire($path, $type); } /** * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ public function releaseLock($path, $type) { if ($type === self::LOCK_SHARED) { if ($this->getOwnSharedLockCount($path) === 1) { $removed = $this->memcache->cad($path, 1); // if we're the only one having a shared lock we can remove it in one go if (!$removed) { //someone else also has a shared lock, decrease only $this->memcache->dec($path); } } else { // if we own more than one lock ourselves just decrease $this->memcache->dec($path); } } else if ($type === self::LOCK_EXCLUSIVE) { $this->memcache->cad($path, 'exclusive'); } $this->markRelease($path, $type); } /** * Change the type of an existing lock * * @param string $path * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE * @throws \OCP\Lock\LockedException */ public function changeLock($path, $targetType) { if ($targetType === self::LOCK_SHARED) { if (!$this->memcache->cas($path, 'exclusive', 1)) { throw new LockedException($path); } } else if ($targetType === self::LOCK_EXCLUSIVE) { // we can only change a shared lock to an exclusive if there's only a single owner of the shared lock if (!$this->memcache->cas($path, 1, 'exclusive')) { throw new LockedException($path); } } $this->setTTL($path); $this->markChange($path, $targetType); } } NoopLockingProvider.php 0000604 00000002706 15247161423 0011220 0 ustar 00 <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Robin Appelman <robin@icewind.nl> * @author Vincent Petry <pvince81@owncloud.com> * * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see <http://www.gnu.org/licenses/> * */ namespace OC\Lock; use OCP\Lock\ILockingProvider; /** * Locking provider that does nothing. * * To be used when locking is disabled. */ class NoopLockingProvider implements ILockingProvider { /** * {@inheritdoc} */ public function isLocked($path, $type) { return false; } /** * {@inheritdoc} */ public function acquireLock($path, $type) { // do nothing } /** * {@inheritdoc} */ public function releaseLock($path, $type) { // do nothing } /**1 * {@inheritdoc} */ public function releaseAll() { // do nothing } /** * {@inheritdoc} */ public function changeLock($path, $targetType) { // do nothing } } AbstractLockingProvider.php 0000604 00000007402 15247161423 0012046 0 ustar 00 <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Robin Appelman <robin@icewind.nl> * * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see <http://www.gnu.org/licenses/> * */ namespace OC\Lock; use OCP\Lock\ILockingProvider; /** * Base locking provider that keeps track of locks acquired during the current request * to release any left over locks at the end of the request */ abstract class AbstractLockingProvider implements ILockingProvider { protected $ttl; // how long until we clear stray locks in seconds protected $acquiredLocks = [ 'shared' => [], 'exclusive' => [] ]; /** * Check if we've locally acquired a lock * * @param string $path * @param int $type * @return bool */ protected function hasAcquiredLock($path, $type) { if ($type === self::LOCK_SHARED) { return isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 0; } else { return isset($this->acquiredLocks['exclusive'][$path]) && $this->acquiredLocks['exclusive'][$path] === true; } } /** * Mark a locally acquired lock * * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ protected function markAcquire($path, $type) { if ($type === self::LOCK_SHARED) { if (!isset($this->acquiredLocks['shared'][$path])) { $this->acquiredLocks['shared'][$path] = 0; } $this->acquiredLocks['shared'][$path]++; } else { $this->acquiredLocks['exclusive'][$path] = true; } } /** * Mark a release of a locally acquired lock * * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ protected function markRelease($path, $type) { if ($type === self::LOCK_SHARED) { if (isset($this->acquiredLocks['shared'][$path]) and $this->acquiredLocks['shared'][$path] > 0) { $this->acquiredLocks['shared'][$path]--; if ($this->acquiredLocks['shared'][$path] === 0) { unset($this->acquiredLocks['shared'][$path]); } } } else if ($type === self::LOCK_EXCLUSIVE) { unset($this->acquiredLocks['exclusive'][$path]); } } /** * Change the type of an existing tracked lock * * @param string $path * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ protected function markChange($path, $targetType) { if ($targetType === self::LOCK_SHARED) { unset($this->acquiredLocks['exclusive'][$path]); if (!isset($this->acquiredLocks['shared'][$path])) { $this->acquiredLocks['shared'][$path] = 0; } $this->acquiredLocks['shared'][$path]++; } else if ($targetType === self::LOCK_EXCLUSIVE) { $this->acquiredLocks['exclusive'][$path] = true; $this->acquiredLocks['shared'][$path]--; } } /** * release all lock acquired by this instance which were marked using the mark* methods */ public function releaseAll() { foreach ($this->acquiredLocks['shared'] as $path => $count) { for ($i = 0; $i < $count; $i++) { $this->releaseLock($path, self::LOCK_SHARED); } } foreach ($this->acquiredLocks['exclusive'] as $path => $hasLock) { $this->releaseLock($path, self::LOCK_EXCLUSIVE); } } protected function getOwnSharedLockCount($path) { return isset($this->acquiredLocks['shared'][$path]) ? $this->acquiredLocks['shared'][$path] : 0; } } DBLockingProvider.php 0000604 00000017417 15247161423 0010577 0 ustar 00 <?php /** * @copyright Copyright (c) 2016, ownCloud, Inc. * * @author Individual IT Services <info@individual-it.net> * @author Morris Jobke <hey@morrisjobke.de> * @author Robin Appelman <robin@icewind.nl> * @author Roeland Jago Douma <roeland@famdouma.nl> * * @license AGPL-3.0 * * This code is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License, version 3, * along with this program. If not, see <http://www.gnu.org/licenses/> * */ namespace OC\Lock; use OC\DB\QueryBuilder\Literal; use OCP\AppFramework\Utility\ITimeFactory; use OCP\DB\QueryBuilder\IQueryBuilder; use OCP\IDBConnection; use OCP\ILogger; use OCP\Lock\ILockingProvider; use OCP\Lock\LockedException; /** * Locking provider that stores the locks in the database */ class DBLockingProvider extends AbstractLockingProvider { /** * @var \OCP\IDBConnection */ private $connection; /** * @var \OCP\ILogger */ private $logger; /** * @var \OCP\AppFramework\Utility\ITimeFactory */ private $timeFactory; private $sharedLocks = []; /** * Check if we have an open shared lock for a path * * @param string $path * @return bool */ protected function isLocallyLocked($path) { return isset($this->sharedLocks[$path]) && $this->sharedLocks[$path]; } /** * Mark a locally acquired lock * * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ protected function markAcquire($path, $type) { parent::markAcquire($path, $type); if ($type === self::LOCK_SHARED) { $this->sharedLocks[$path] = true; } } /** * Change the type of an existing tracked lock * * @param string $path * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ protected function markChange($path, $targetType) { parent::markChange($path, $targetType); if ($targetType === self::LOCK_SHARED) { $this->sharedLocks[$path] = true; } else if ($targetType === self::LOCK_EXCLUSIVE) { $this->sharedLocks[$path] = false; } } /** * @param \OCP\IDBConnection $connection * @param \OCP\ILogger $logger * @param \OCP\AppFramework\Utility\ITimeFactory $timeFactory * @param int $ttl */ public function __construct(IDBConnection $connection, ILogger $logger, ITimeFactory $timeFactory, $ttl = 3600) { $this->connection = $connection; $this->logger = $logger; $this->timeFactory = $timeFactory; $this->ttl = $ttl; } /** * Insert a file locking row if it does not exists. * * @param string $path * @param int $lock * @return int number of inserted rows */ protected function initLockField($path, $lock = 0) { $expire = $this->getExpireTime(); return $this->connection->insertIfNotExist('*PREFIX*file_locks', ['key' => $path, 'lock' => $lock, 'ttl' => $expire], ['key']); } /** * @return int */ protected function getExpireTime() { return $this->timeFactory->getTime() + $this->ttl; } /** * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE * @return bool */ public function isLocked($path, $type) { if ($this->hasAcquiredLock($path, $type)) { return true; } $query = $this->connection->prepare('SELECT `lock` from `*PREFIX*file_locks` WHERE `key` = ?'); $query->execute([$path]); $lockValue = (int)$query->fetchColumn(); if ($type === self::LOCK_SHARED) { if ($this->isLocallyLocked($path)) { // if we have a shared lock we kept open locally but it's released we always have at least 1 shared lock in the db return $lockValue > 1; } else { return $lockValue > 0; } } else if ($type === self::LOCK_EXCLUSIVE) { return $lockValue === -1; } else { return false; } } /** * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE * @throws \OCP\Lock\LockedException */ public function acquireLock($path, $type) { $expire = $this->getExpireTime(); if ($type === self::LOCK_SHARED) { if (!$this->isLocallyLocked($path)) { $result = $this->initLockField($path, 1); if ($result <= 0) { $result = $this->connection->executeUpdate( 'UPDATE `*PREFIX*file_locks` SET `lock` = `lock` + 1, `ttl` = ? WHERE `key` = ? AND `lock` >= 0', [$expire, $path] ); } } else { $result = 1; } } else { $existing = 0; if ($this->hasAcquiredLock($path, ILockingProvider::LOCK_SHARED) === false && $this->isLocallyLocked($path)) { $existing = 1; } $result = $this->initLockField($path, -1); if ($result <= 0) { $result = $this->connection->executeUpdate( 'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = ?', [$expire, $path, $existing] ); } } if ($result !== 1) { throw new LockedException($path); } $this->markAcquire($path, $type); } /** * @param string $path * @param int $type self::LOCK_SHARED or self::LOCK_EXCLUSIVE */ public function releaseLock($path, $type) { $this->markRelease($path, $type); // we keep shared locks till the end of the request so we can re-use them if ($type === self::LOCK_EXCLUSIVE) { $this->connection->executeUpdate( 'UPDATE `*PREFIX*file_locks` SET `lock` = 0 WHERE `key` = ? AND `lock` = -1', [$path] ); } } /** * Change the type of an existing lock * * @param string $path * @param int $targetType self::LOCK_SHARED or self::LOCK_EXCLUSIVE * @throws \OCP\Lock\LockedException */ public function changeLock($path, $targetType) { $expire = $this->getExpireTime(); if ($targetType === self::LOCK_SHARED) { $result = $this->connection->executeUpdate( 'UPDATE `*PREFIX*file_locks` SET `lock` = 1, `ttl` = ? WHERE `key` = ? AND `lock` = -1', [$expire, $path] ); } else { // since we only keep one shared lock in the db we need to check if we have more then one shared lock locally manually if (isset($this->acquiredLocks['shared'][$path]) && $this->acquiredLocks['shared'][$path] > 1) { throw new LockedException($path); } $result = $this->connection->executeUpdate( 'UPDATE `*PREFIX*file_locks` SET `lock` = -1, `ttl` = ? WHERE `key` = ? AND `lock` = 1', [$expire, $path] ); } if ($result !== 1) { throw new LockedException($path); } $this->markChange($path, $targetType); } /** * cleanup empty locks */ public function cleanExpiredLocks() { $expire = $this->timeFactory->getTime(); try { $this->connection->executeUpdate( 'DELETE FROM `*PREFIX*file_locks` WHERE `ttl` < ?', [$expire] ); } catch (\Exception $e) { // If the table is missing, the clean up was successful if ($this->connection->tableExists('file_locks')) { throw $e; } } } /** * release all lock acquired by this instance which were marked using the mark* methods */ public function releaseAll() { parent::releaseAll(); // since we keep shared locks we need to manually clean those $lockedPaths = array_keys($this->sharedLocks); $lockedPaths = array_filter($lockedPaths, function ($path) { return $this->sharedLocks[$path]; }); $chunkedPaths = array_chunk($lockedPaths, 100); foreach ($chunkedPaths as $chunk) { $builder = $this->connection->getQueryBuilder(); $query = $builder->update('file_locks') ->set('lock', $builder->createFunction('`lock` -1')) ->where($builder->expr()->in('key', $builder->createNamedParameter($chunk, IQueryBuilder::PARAM_STR_ARRAY))) ->andWhere($builder->expr()->gt('lock', new Literal(0))); $query->execute(); } } }
| ver. 1.4 |
Github
|
.
| PHP 7.4.33 | Generation time: 0 |
proxy
|
phpinfo
|
Settings