summaryrefslogtreecommitdiffstats
path: root/lib/private/Lock
diff options
context:
space:
mode:
Diffstat (limited to 'lib/private/Lock')
-rw-r--r--lib/private/Lock/DBLockingProvider.php27
1 files changed, 20 insertions, 7 deletions
diff --git a/lib/private/Lock/DBLockingProvider.php b/lib/private/Lock/DBLockingProvider.php
index 9e97df44d3f..1865e94925f 100644
--- a/lib/private/Lock/DBLockingProvider.php
+++ b/lib/private/Lock/DBLockingProvider.php
@@ -24,6 +24,7 @@
namespace OC\Lock;
+use OC\DB\QueryBuilder\Literal;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\IDBConnection;
use OCP\ILogger;
@@ -257,13 +258,25 @@ class DBLockingProvider extends AbstractLockingProvider {
parent::releaseAll();
// since we keep shared locks we need to manually clean those
- foreach ($this->sharedLocks as $path => $lock) {
- if ($lock) {
- $this->connection->executeUpdate(
- 'UPDATE `*PREFIX*file_locks` SET `lock` = `lock` - 1 WHERE `key` = ? AND `lock` > 0',
- [$path]
- );
- }
+ $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();
+ $params = array_map(function ($path) use ($builder) {
+ return $builder->createNamedParameter($path);
+ }, $chunk);
+
+ $query = $builder->update('file_locks')
+ ->set('lock', $builder->createFunction('`lock` -1'))
+ ->where($builder->expr()->in('key', $params))
+ ->andWhere($builder->expr()->gt('lock', new Literal(0)));
+
+ $query->execute();
}
}
}