AsyncPromise — ensure that setResult/setError and blockingGet are not called inside write action

This commit is contained in:
Vladimir Krivosheev
2018-03-19 12:35:29 +01:00
parent fef5b1cf65
commit dca8627cc8
@@ -1,6 +1,7 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package org.jetbrains.concurrency
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.util.Function
import org.jetbrains.concurrency.InternalPromiseUtil.PromiseValue
@@ -96,6 +97,10 @@ open class AsyncPromise<T : Any?> : InternalPromiseUtil.BasePromise<T>(), Cancel
}
fun setResult(result: T) {
ApplicationManager.getApplication()?.let {
LOG.assertTrue(!it.isWriteAccessAllowed, "Result must be not set inside write-action")
}
if (!valueRef.compareAndSet(null, PromiseValue.createFulfilled(result))) {
return
}
@@ -115,6 +120,10 @@ open class AsyncPromise<T : Any?> : InternalPromiseUtil.BasePromise<T>(), Cancel
}
open fun setError(error: Throwable): Boolean {
ApplicationManager.getApplication()?.let {
LOG.assertTrue(!it.isWriteAccessAllowed, "Error must be not set inside write-action")
}
if (!valueRef.compareAndSet(null, PromiseValue.createRejected(error))) {
LOG.errorIfNotMessage(error)
return false
@@ -139,6 +148,10 @@ open class AsyncPromise<T : Any?> : InternalPromiseUtil.BasePromise<T>(), Cancel
}
override fun blockingGet(timeout: Int, timeUnit: TimeUnit): T? {
ApplicationManager.getApplication()?.let {
LOG.assertTrue(!it.isWriteAccessAllowed, "blockingGet() must be not called inside write-action")
}
var value = valueRef.get()
if (value == null) {
val latch = CountDownLatch(1)