diff --git a/platform/platform-impl/src/com/intellij/openapi/application/impl/NestedLocksThreadingSupport.kt b/platform/platform-impl/src/com/intellij/openapi/application/impl/NestedLocksThreadingSupport.kt index 95351610e2b0..cbbe5e28a88f 100644 --- a/platform/platform-impl/src/com/intellij/openapi/application/impl/NestedLocksThreadingSupport.kt +++ b/platform/platform-impl/src/com/intellij/openapi/application/impl/NestedLocksThreadingSupport.kt @@ -1466,54 +1466,47 @@ private class RunSuspend(val job: Job?, val interceptor: PermitWaitingInterce val resultDeferred: CompletableDeferred = CompletableDeferred() - override fun resumeWith(result: Result) { + override fun resumeWith(result: Result) = synchronized(this) { if (result.isSuccess) { resultDeferred.complete(result.getOrThrow()) } else { resultDeferred.completeExceptionally(result.exceptionOrNull()!!) } - synchronized(this) { - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll() - } + @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll() } - private fun doAwait(): T { + fun await(): T { if (interceptor == null) { - var interrupted = false - while (true) { - if (resultDeferred.isCompleted) { - if (interrupted) { - // Restore "interrupted" flag - Thread.currentThread().interrupt() + synchronized(this) { + var interrupted = false + while (true) { + if (resultDeferred.isCompleted) { + if (interrupted) { + // Restore "interrupted" flag + Thread.currentThread().interrupt() + } + return resultDeferred.getOrThrow() } - return resultDeferred.getOrThrow() - } - else { - try { - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") - ((this as Object).wait()) - } - catch (_: InterruptedException) { - // Suppress exception or token could be lost. - interrupted = true + else { + try { + @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") + ((this as Object).wait()) + } + catch (_: InterruptedException) { + // Suppress exception or token could be lost. + interrupted = true + } } } } - } - else { + } else { if (!resultDeferred.isCompleted) { interceptor.consumer(resultDeferred) } return resultDeferred.getOrThrow() // consumer returns when `result` gets non-nullable value } } - - fun await(): T { - return synchronized(this) { - doAwait() - } - } } @OptIn(ExperimentalCoroutinesApi::class) diff --git a/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt b/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt index 99f6826a5ee6..2cfe101558f8 100644 --- a/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt +++ b/platform/platform-impl/src/com/intellij/openapi/progress/util/SuvorovProgress.kt @@ -265,6 +265,8 @@ private class EternalEventStealer(disposable: Disposable) { } fun dispatchAllEventsForTimeout(timeoutMillis: Long, deferred: Deferred<*>) { + val initialMark = System.nanoTime() + deferred.invokeOnCompletion { synchronized(this@EternalEventStealer) { (this@EternalEventStealer as Object).notifyAll() @@ -272,39 +274,32 @@ private class EternalEventStealer(disposable: Disposable) { } synchronized(this) { - doDispatchAllEventsForTimeout(timeoutMillis, deferred) - } - } - - fun doDispatchAllEventsForTimeout(timeoutMillis: Long, deferred: Deferred<*>) { - val initialMark = System.nanoTime() - - while (true) { - val currentMark = System.nanoTime() - val elapsedSinceStartNanos = currentMark - initialMark - val toSleepMillis = timeoutMillis - (elapsedSinceStartNanos / 1_000_000) - if (toSleepMillis <= 0) { - return - } - if (deferred.isCompleted) { - return - } - try { - (this as Object).wait(toSleepMillis) - } - catch (_: InterruptedException) { - // we still return locking result regardless of interruption - Thread.currentThread().interrupt() - } - var eventIndex = 0 - while (eventIndex < invocationEventList.size) { - val event = invocationEventList[eventIndex] - eventIndex++ - event.dispatch() - } - invocationEventList.clear() - if (!deferred.isActive) { - return + while (true) { + val currentMark = System.nanoTime() + val elapsedSinceStartNanos = currentMark - initialMark + val toSleep = timeoutMillis - (elapsedSinceStartNanos / 1_000_000) + if (toSleep <= 0) { + return + } + if (deferred.isCompleted) { + return + } + try { + (this as Object).wait(toSleep) + } catch (_ : InterruptedException) { + // we still return locking result regardless of interruption + Thread.currentThread().interrupt() + } + var eventIndex = 0 + while (eventIndex < invocationEventList.size) { + val event = invocationEventList[eventIndex] + eventIndex++ + event.dispatch() + } + invocationEventList.clear() + if (!deferred.isActive) { + return + } } } }