mirror of
https://gitflic.ru/project/openide/openide.git
synced 2025-12-16 22:51:17 +07:00
IJPL-162040 Store lock permits in context to allow lock inheritance between coroutines.
- Fix check for inheritance in case of Fleet or other coroutine framework. - Make tests stricter. - Mark new Application API as internal and experimental, as ot is needed only for this code and should not be used in other places. (cherry picked from commit 63798b6160ca5963499ae066db149d3b2af6017d) IJ-CR-147289 GitOrigin-RevId: 700746a8c9590945893ef389f2c86724eb8a83d5
This commit is contained in:
committed by
intellij-monorepo-bot
parent
ecb3e54b63
commit
c91c8b6702
@@ -1100,10 +1100,8 @@ com.intellij.openapi.application.Application
|
||||
- exit(Z,Z,Z,I):V
|
||||
- a:getDefaultModalityState():com.intellij.openapi.application.ModalityState
|
||||
- a:getIdleTime():J
|
||||
- getLockStateAsCoroutineContext():kotlin.coroutines.CoroutineContext
|
||||
- a:getModalityStateForComponent(java.awt.Component):com.intellij.openapi.application.ModalityState
|
||||
- a:getStartTime():J
|
||||
- hasLockStateInContext(kotlin.coroutines.CoroutineContext):Z
|
||||
- a:hasWriteAction(java.lang.Class):Z
|
||||
- a:invokeAndWait(java.lang.Runnable):V
|
||||
- a:invokeAndWait(java.lang.Runnable,com.intellij.openapi.application.ModalityState):V
|
||||
|
||||
@@ -675,10 +675,14 @@ public interface Application extends ComponentManager {
|
||||
}
|
||||
//</editor-fold>
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.Internal
|
||||
default CoroutineContext getLockStateAsCoroutineContext() {
|
||||
return EmptyCoroutineContext.INSTANCE;
|
||||
}
|
||||
|
||||
@ApiStatus.Experimental
|
||||
@ApiStatus.Internal
|
||||
default boolean hasLockStateInContext(CoroutineContext context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ internal class InternalReadAction<T>(
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (isLockStoredInContext && application.isReadAccessAllowed && !application.isWriteIntentLockAcquired) {
|
||||
if (isLockStoredInContext && application.hasLockStateInContext(currentCoroutineContext())) {
|
||||
val unsatisfiedConstraint = findUnsatisfiedConstraint()
|
||||
check(unsatisfiedConstraint == null) {
|
||||
"Cannot suspend until constraints are satisfied while holding the read lock: $unsatisfiedConstraint"
|
||||
@@ -47,7 +47,7 @@ internal class InternalReadAction<T>(
|
||||
}
|
||||
}
|
||||
withContext(Dispatchers.Default) {
|
||||
check(isLockStoredInContext || !application.isReadAccessAllowed) {
|
||||
check(!application.isReadAccessAllowed) {
|
||||
"This thread unexpectedly holds the read lock"
|
||||
}
|
||||
readLoop()
|
||||
|
||||
@@ -8,6 +8,7 @@ import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.testFramework.common.timeoutRunBlocking
|
||||
import com.intellij.util.concurrency.ImplicitBlockingContextTest
|
||||
import com.intellij.util.concurrency.Semaphore
|
||||
import com.intellij.util.concurrency.ThreadingAssertions
|
||||
import com.intellij.util.concurrency.runWithImplicitBlockingContextEnabled
|
||||
import kotlinx.coroutines.*
|
||||
import org.junit.jupiter.api.Assertions.*
|
||||
@@ -156,8 +157,10 @@ abstract class SuspendingReadActionTest : CancellableReadActionTests() {
|
||||
@RepeatedTest(REPETITIONS)
|
||||
fun `read action works if already obtained`(): Unit = timeoutRunBlocking {
|
||||
cra {
|
||||
assertTrue(ApplicationManager.getApplication().isReadAccessAllowed)
|
||||
runBlockingCancellable {
|
||||
assertEquals(42, cra {
|
||||
assertTrue(ApplicationManager.getApplication().isReadAccessAllowed)
|
||||
42
|
||||
})
|
||||
}
|
||||
@@ -387,6 +390,7 @@ class NonBlockingUndispatchedSuspendingReadActionTest : SuspendingReadActionTest
|
||||
override suspend fun awaitConstraint(): Unit = fail("must not be called")
|
||||
}
|
||||
cra {
|
||||
assertTrue(ApplicationManager.getApplication().isReadAccessAllowed)
|
||||
runBlockingCancellable {
|
||||
assertThrows<IllegalStateException> {
|
||||
cra(unsatisfiableConstraint) {
|
||||
|
||||
Reference in New Issue
Block a user