Perform tryLock-and-checkCanceled on waiting lock in LockBasedStorageManager
Relates to #KT-38012
This commit is contained in:
@@ -29,8 +29,6 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.ConcurrentMap;
|
||||
import java.util.concurrent.locks.Lock;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
public class LockBasedStorageManager implements StorageManager {
|
||||
private static final String PACKAGE_NAME = StringsKt.substringBeforeLast(LockBasedStorageManager.class.getCanonicalName(), ".", "");
|
||||
@@ -55,7 +53,7 @@ public class LockBasedStorageManager implements StorageManager {
|
||||
RuntimeException handleException(@NotNull Throwable throwable);
|
||||
}
|
||||
|
||||
public static final StorageManager NO_LOCKS = new LockBasedStorageManager("NO_LOCKS", ExceptionHandlingStrategy.THROW, NoLock.INSTANCE) {
|
||||
public static final StorageManager NO_LOCKS = new LockBasedStorageManager("NO_LOCKS", ExceptionHandlingStrategy.THROW, EmptySimpleLock.INSTANCE) {
|
||||
@NotNull
|
||||
@Override
|
||||
protected <T> RecursionDetectedResult<T> recursionDetectedDefault() {
|
||||
@@ -64,18 +62,31 @@ public class LockBasedStorageManager implements StorageManager {
|
||||
};
|
||||
|
||||
@NotNull
|
||||
public static LockBasedStorageManager createWithExceptionHandling(@NotNull String debugText, @NotNull ExceptionHandlingStrategy exceptionHandlingStrategy) {
|
||||
return new LockBasedStorageManager(debugText, exceptionHandlingStrategy, new ReentrantLock());
|
||||
public static LockBasedStorageManager createWithExceptionHandling(
|
||||
@NotNull String debugText,
|
||||
@NotNull ExceptionHandlingStrategy exceptionHandlingStrategy
|
||||
) {
|
||||
return createWithExceptionHandling(debugText, exceptionHandlingStrategy, null);
|
||||
}
|
||||
|
||||
protected final Lock lock;
|
||||
@NotNull
|
||||
public static LockBasedStorageManager createWithExceptionHandling(
|
||||
@NotNull String debugText,
|
||||
@NotNull ExceptionHandlingStrategy exceptionHandlingStrategy,
|
||||
@Nullable Runnable checkCancelled
|
||||
) {
|
||||
return new LockBasedStorageManager(debugText, exceptionHandlingStrategy,
|
||||
SimpleLock.Companion.simpleLock(checkCancelled));
|
||||
}
|
||||
|
||||
protected final SimpleLock lock;
|
||||
private final ExceptionHandlingStrategy exceptionHandlingStrategy;
|
||||
private final String debugText;
|
||||
|
||||
private LockBasedStorageManager(
|
||||
@NotNull String debugText,
|
||||
@NotNull ExceptionHandlingStrategy exceptionHandlingStrategy,
|
||||
@NotNull Lock lock
|
||||
@NotNull SimpleLock lock
|
||||
) {
|
||||
this.lock = lock;
|
||||
this.exceptionHandlingStrategy = exceptionHandlingStrategy;
|
||||
@@ -83,7 +94,11 @@ public class LockBasedStorageManager implements StorageManager {
|
||||
}
|
||||
|
||||
public LockBasedStorageManager(String debugText) {
|
||||
this(debugText, ExceptionHandlingStrategy.THROW, new ReentrantLock());
|
||||
this(debugText, null);
|
||||
}
|
||||
|
||||
public LockBasedStorageManager(String debugText, @Nullable Runnable checkCancelled) {
|
||||
this(debugText, ExceptionHandlingStrategy.THROW, SimpleLock.Companion.simpleLock(checkCancelled));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.storage
|
||||
|
||||
import java.util.concurrent.TimeUnit
|
||||
import java.util.concurrent.locks.Lock
|
||||
import java.util.concurrent.locks.ReentrantLock
|
||||
|
||||
private const val CHECK_CANCELLATION_PERIOD_MS: Long = 50
|
||||
|
||||
interface SimpleLock {
|
||||
fun lock()
|
||||
|
||||
fun unlock()
|
||||
|
||||
companion object {
|
||||
fun simpleLock(checkCancelled: Runnable? = null) =
|
||||
checkCancelled?.let { CancellableSimpleLock(it) } ?: DefaultSimpleLock()
|
||||
}
|
||||
}
|
||||
|
||||
inline fun <T> SimpleLock.guarded(crossinline computable: () -> T): T {
|
||||
lock()
|
||||
return try {
|
||||
computable()
|
||||
} finally {
|
||||
unlock()
|
||||
}
|
||||
}
|
||||
|
||||
object EmptySimpleLock : SimpleLock {
|
||||
override fun lock() {
|
||||
}
|
||||
|
||||
override fun unlock() {
|
||||
}
|
||||
}
|
||||
|
||||
open class DefaultSimpleLock(protected val lock: Lock = ReentrantLock()) : SimpleLock {
|
||||
|
||||
override fun lock() = lock.lock()
|
||||
|
||||
override fun unlock() = lock.unlock()
|
||||
|
||||
}
|
||||
|
||||
class CancellableSimpleLock(lock: Lock, private val checkCancelled: Runnable) : DefaultSimpleLock(lock) {
|
||||
constructor(checkCancelled: Runnable) : this(checkCancelled = checkCancelled, lock = ReentrantLock())
|
||||
|
||||
override fun lock() {
|
||||
while (!lock.tryLock(CHECK_CANCELLATION_PERIOD_MS, TimeUnit.MILLISECONDS)) {
|
||||
//ProgressIndicatorAndCompilationCanceledStatus.checkCanceled()
|
||||
checkCancelled.run()
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user