Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TapGestureDetector mutex is not locked error on Touchscreen #3655

Closed
Selemba1000 opened this issue Sep 11, 2023 · 11 comments · Fixed by JetBrains/compose-multiplatform-core#824
Assignees
Labels

Comments

@Selemba1000
Copy link

Describe the bug
If a element has the onClick modifier on it and is touched via the Touchscreen and it is the first interaction with any of the buttons of the application, it crashes with exception: mutex is not locked.

Affected platforms
Select one of the platforms below:

  • Desktop

Versions

  • Kotlin version*: 1.9.10
  • Compose Multiplatform version*: 1.5.1
  • OS version(s)* (required for Desktop and iOS issues): Windows 11 22h2
  • OS architecture (x86 or arm64): x86
  • JDK (for desktop issues): 11

To Reproduce
Steps and/or the code snippet to reproduce the behavior:
Box(modifier = Modifier.onClick({}).fillMaxSize()){}

  1. Run Desktop application
  2. Click on the Box, without touching anything with the mouse first

Expected behavior
Nothing should happen, as the onClick Funktion is empty.

Screenshots
image

Log

Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Mutex is not locked
	at kotlinx.coroutines.sync.MutexImpl.unlock(Mutex.kt:326)
	at kotlinx.coroutines.sync.Mutex$DefaultImpls.unlock$default(Mutex.kt:85)
	at androidx.compose.foundation.gestures.PressGestureScopeImpl.release(TapGestureDetector.kt:358)
	at androidx.compose.foundation.gestures.TapGesturesDetector_skikoKt$detectTapGestures$4$1.invokeSuspend(TapGesturesDetector.skiko.kt:125)
	at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
	at kotlinx.coroutines.DispatchedTaskKt.resume(DispatchedTask.kt:178)
	at kotlinx.coroutines.DispatchedTaskKt.dispatch(DispatchedTask.kt:166)
	at kotlinx.coroutines.CancellableContinuationImpl.dispatchResume(CancellableContinuationImpl.kt:397)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl(CancellableContinuationImpl.kt:431)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeImpl$default(CancellableContinuationImpl.kt:420)
	at kotlinx.coroutines.CancellableContinuationImpl.resumeWith(CancellableContinuationImpl.kt:328)
	at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl$PointerEventHandlerCoroutine.offerPointerEvent(SuspendingPointerInputFilter.kt:672)
	at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.dispatchPointerEvent(SuspendingPointerInputFilter.kt:549)
	at androidx.compose.ui.input.pointer.SuspendingPointerInputModifierNodeImpl.onPointerEvent-H0pRuoY(SuspendingPointerInputFilter.kt:571)
	at androidx.compose.ui.input.pointer.Node.dispatchFinalEventPass(HitPathTracker.kt:310)
	at androidx.compose.ui.input.pointer.Node.dispatchFinalEventPass(HitPathTracker.kt:315)
	at androidx.compose.ui.input.pointer.NodeParent.dispatchFinalEventPass(HitPathTracker.kt:175)
	at androidx.compose.ui.input.pointer.HitPathTracker.dispatchChanges(HitPathTracker.kt:99)
	at androidx.compose.ui.input.pointer.PointerInputEventProcessor.process-BIzXfog(PointerInputEventProcessor.kt:97)
	at androidx.compose.ui.platform.SkiaBasedOwner.processPointerInput-gBdvCQM$ui(SkiaBasedOwner.skiko.kt:362)
	at androidx.compose.ui.platform.SkiaBasedOwner.processPointerInput-gBdvCQM$ui$default(SkiaBasedOwner.skiko.kt:355)
	at androidx.compose.ui.ComposeScene.processRelease(ComposeScene.skiko.kt:652)
	at androidx.compose.ui.ComposeScene.processPointerInput(ComposeScene.skiko.kt:611)
	at androidx.compose.ui.ComposeScene.access$processPointerInput(ComposeScene.skiko.kt:68)
	at androidx.compose.ui.ComposeScene$syntheticEventSender$1.invoke(ComposeScene.skiko.kt:245)
	at androidx.compose.ui.ComposeScene$syntheticEventSender$1.invoke(ComposeScene.skiko.kt:245)
	at androidx.compose.ui.SyntheticEventSender.sendInternal(SyntheticEventSender.kt:157)
	at androidx.compose.ui.SyntheticEventSender.send(SyntheticEventSender.kt:64)
	at androidx.compose.ui.ComposeScene.sendPointerEvent-WlEVilQ(ComposeScene.skiko.kt:581)
	at androidx.compose.ui.ComposeScene.sendPointerEvent-BGSDPeU(ComposeScene.skiko.kt:523)
	at androidx.compose.ui.ComposeScene.sendPointerEvent-BGSDPeU$default(ComposeScene.skiko.kt:506)
	at androidx.compose.ui.awt.ComposeBridge_desktopKt.onMouseEvent(ComposeBridge.desktop.kt:405)
	at androidx.compose.ui.awt.ComposeBridge_desktopKt.access$onMouseEvent(ComposeBridge.desktop.kt:1)
	at androidx.compose.ui.awt.ComposeBridge$onMouseEvent$1.invoke(ComposeBridge.desktop.kt:245)
	at androidx.compose.ui.awt.ComposeBridge$onMouseEvent$1.invoke(ComposeBridge.desktop.kt:238)
	at androidx.compose.ui.awt.ComposeBridge.catchExceptions(ComposeBridge.desktop.kt:126)
	at androidx.compose.ui.awt.ComposeBridge.onMouseEvent(ComposeBridge.desktop.kt:238)
	at androidx.compose.ui.awt.ComposeBridge.access$onMouseEvent(ComposeBridge.desktop.kt:59)
	at androidx.compose.ui.awt.ComposeBridge$attachComposeToComponent$3.mouseReleased(ComposeBridge.desktop.kt:219)
	at java.desktop/java.awt.Component.processMouseEvent(Component.java:6616)
	at java.desktop/java.awt.Component.processEvent(Component.java:6381)
	at java.desktop/java.awt.Component.dispatchEventImpl(Component.java:4991)
	at java.desktop/java.awt.Component.dispatchEvent(Component.java:4823)
	at java.desktop/java.awt.EventQueue.dispatchEventImpl(EventQueue.java:775)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:720)
	at java.desktop/java.awt.EventQueue$4.run(EventQueue.java:714)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:97)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:747)
	at java.desktop/java.awt.EventQueue$5.run(EventQueue.java:745)
	at java.base/java.security.AccessController.doPrivileged(AccessController.java:399)
	at java.base/java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
	at java.desktop/java.awt.EventQueue.dispatchEvent(EventQueue.java:744)
	at java.desktop/java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
	at java.desktop/java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
	at java.desktop/java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
	at java.desktop/java.awt.EventDispatchThread.run(EventDispatchThread.java:90)
	Suppressed: kotlinx.coroutines.DiagnosticCoroutineContextException: [androidx.compose.ui.awt.ComposeBridge$coroutineExceptionHandler$1@7413ff66, androidx.compose.runtime.BroadcastFrameClock@3508f860, StandaloneCoroutine{Cancelling}@7539ccd7, FlushCoroutineDispatcher@67a6c6af]

Additional context
Seems related to: #Kotlin/kotlinx.coroutines#1937
Im guessing the initial state of the mutex can't be correctly assumed by the Touch part specificly, since one Mouseclick on some other Button fixes all future interactions.

@Selemba1000 Selemba1000 added bug Something isn't working submitted labels Sep 11, 2023
@ScottPierce
Copy link
Contributor

we are seeing this as well.

@igordmn igordmn self-assigned this Sep 18, 2023
igordmn added a commit to JetBrains/compose-multiplatform-core that referenced this issue Sep 18, 2023
Fixes JetBrains/compose-multiplatform#3655

The issue is introduced after migration to `awaitPointerEventScope`, this code is indeed has a race condition, as it was assumed in the TODO. When we send Press/Release without any moves - we go via this path:
```
// awaitPointerEventScope isn't called until it receives the first event
awaitPointerEventScope {
  // in the beginning of the method we have 2 events already in the queue

  launch { pressScope.reset() } // launch async, reset isn't called
  val down = awaitPress // don't suspend here, because we already have Press
  awaitReleaseOrCancelled() // don't suspend here, because we already have Release
  pressScope.release() // crash, because `pressScope.reset()` isn't yet called
}
```

To avoid races, we should always access `pressScope` in `launch` (this way calls maintain order).

The same approach is used in the original `TapGestureDetector.kt` (the change in commit 32de9dd)

Also, the rest of the code doesn't have races with `pressScope` calls.

## Testing
- haven't reproduced with mouse
- reproduced with a simple test (added to OnClickTest)
igordmn added a commit to JetBrains/compose-multiplatform-core that referenced this issue Sep 19, 2023
Fixes JetBrains/compose-multiplatform#3655

The issue is introduced after migration to `awaitPointerEventScope`,
this code is indeed has a race condition, as it was assumed in the TODO.
When we send Press/Release without any moves - we go via this path:
```
// awaitPointerEventScope isn't called until it receives the first event
awaitPointerEventScope {
  // in the beginning of the method we have 2 events already in the queue

  launch { pressScope.reset() } // launch async, reset isn't called
  val down = awaitPress // don't suspend here, because we already have Press
  awaitReleaseOrCancelled() // don't suspend here, because we already have Release
  pressScope.release() // crash, because `pressScope.reset()` isn't called yet
}
```

To avoid races, we should always access `pressScope` in `launch` (this
way the calls maintain order).

The same approach is used in the original `TapGestureDetector.kt` (the
change in commit 32de9dd)

Also, the rest of the code doesn't have races with `pressScope` calls.

## Testing
- haven't reproduced with mouse
- reproduced with a simple test (added to OnClickTest)
elijah-semyonov pushed a commit to JetBrains/compose-multiplatform-core that referenced this issue Sep 21, 2023
Fixes JetBrains/compose-multiplatform#3655

The issue is introduced after migration to `awaitPointerEventScope`,
this code is indeed has a race condition, as it was assumed in the TODO.
When we send Press/Release without any moves - we go via this path:
```
// awaitPointerEventScope isn't called until it receives the first event
awaitPointerEventScope {
  // in the beginning of the method we have 2 events already in the queue

  launch { pressScope.reset() } // launch async, reset isn't called
  val down = awaitPress // don't suspend here, because we already have Press
  awaitReleaseOrCancelled() // don't suspend here, because we already have Release
  pressScope.release() // crash, because `pressScope.reset()` isn't called yet
}
```

To avoid races, we should always access `pressScope` in `launch` (this
way the calls maintain order).

The same approach is used in the original `TapGestureDetector.kt` (the
change in commit 32de9dd)

Also, the rest of the code doesn't have races with `pressScope` calls.

## Testing
- haven't reproduced with mouse
- reproduced with a simple test (added to OnClickTest)
@ScottPierce
Copy link
Contributor

@igordmn when are we going to get a release with this? We have customers complaining about this bug.

@igordmn
Copy link
Collaborator

igordmn commented Sep 22, 2023

1.5.10 (bugfixes + features for multiplatform) will be approximately in a month. Will it work for you?

@ScottPierce
Copy link
Contributor

@igordmn That's an awfully long time away. If the release is a month away, it will have been almost 8 weeks between releases. Is it unreasonable to expect faster bug fix releases for regressions?

@igordmn igordmn added regression p:high High priority labels Sep 25, 2023
@igordmn
Copy link
Collaborator

igordmn commented Sep 25, 2023

We'll build 1.5.2 soon then

@ScottPierce
Copy link
Contributor

Oh wow, I wasn't expecting that. That would be amazing!

Walingar pushed a commit to JetBrains/compose-multiplatform-core that referenced this issue Sep 25, 2023
Fixes JetBrains/compose-multiplatform#3655

The issue is introduced after migration to `awaitPointerEventScope`,
this code is indeed has a race condition, as it was assumed in the TODO.
When we send Press/Release without any moves - we go via this path:
```
// awaitPointerEventScope isn't called until it receives the first event
awaitPointerEventScope {
  // in the beginning of the method we have 2 events already in the queue

  launch { pressScope.reset() } // launch async, reset isn't called
  val down = awaitPress // don't suspend here, because we already have Press
  awaitReleaseOrCancelled() // don't suspend here, because we already have Release
  pressScope.release() // crash, because `pressScope.reset()` isn't called yet
}
```

To avoid races, we should always access `pressScope` in `launch` (this
way the calls maintain order).

The same approach is used in the original `TapGestureDetector.kt` (the
change in commit 32de9dd)

Also, the rest of the code doesn't have races with `pressScope` calls.

## Testing
- haven't reproduced with mouse
- reproduced with a simple test (added to OnClickTest)
@Syer10
Copy link
Contributor

Syer10 commented Oct 11, 2023

@igordmn
We received a crash report with the same issue in the latest release(1.5.3), is it possible that it regressed?

java.lang.IllegalStateException: Mutex is not locked
    at kotlinx.coroutines.sync.MutexImpl.unlock(Mutex.kt:326)
    at kotlinx.coroutines.sync.MutexImpl$LockCont$tryResumeLockWaiter$1.invoke(Mutex.kt:388)
    at kotlinx.coroutines.sync.MutexImpl$LockCont$tryResumeLockWaiter$1.invoke(Mutex.kt:386)
    at kotlinx.coroutines.CancellableContinuationImpl.callOnCancellation(CancellableContinuationImpl.kt:219)
    at kotlinx.coroutines.CompletedContinuation.invokeHandlers(CancellableContinuationImpl.kt:590)
    at kotlinx.coroutines.CancellableContinuationImpl.cancelCompletedResult$kotlinx_coroutines_core(CancellableContinuationImpl.kt:149)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2$1.invoke(FlushCoroutineDispatcher.skiko.kt:62)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2$1.invoke(FlushCoroutineDispatcher.skiko.kt:57)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.performRun(FlushCoroutineDispatcher.skiko.kt:91)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.access$performRun(FlushCoroutineDispatcher.skiko.kt:37)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2.invokeSuspend(FlushCoroutineDispatcher.skiko.kt:57)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

kotlinx.coroutines.CompletionHandlerException: Exception in resume onCancellation handler for CancellableContinuation(DispatchedContinuation[FlushCoroutineDispatcher@47967eed, Continuation at androidx.compose.foundation.gestures.PressGestureScopeImpl.reset(TapGestureDetector.kt:365)@2436c141]){Completed}@2624c324
    at kotlinx.coroutines.CancellableContinuationImpl.callOnCancellation(CancellableContinuationImpl.kt:224)
    at kotlinx.coroutines.CompletedContinuation.invokeHandlers(CancellableContinuationImpl.kt:590)
    at kotlinx.coroutines.CancellableContinuationImpl.cancelCompletedResult$kotlinx_coroutines_core(CancellableContinuationImpl.kt:149)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:100)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2$1.invoke(FlushCoroutineDispatcher.skiko.kt:62)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2$1.invoke(FlushCoroutineDispatcher.skiko.kt:57)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.performRun(FlushCoroutineDispatcher.skiko.kt:91)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher.access$performRun(FlushCoroutineDispatcher.skiko.kt:37)
    at androidx.compose.ui.platform.FlushCoroutineDispatcher$dispatch$2.invokeSuspend(FlushCoroutineDispatcher.skiko.kt:57)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(ContinuationImpl.kt:33)
    at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:106)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:771)
    at java.awt.EventQueue$4.run(EventQueue.java:722)
    at java.awt.EventQueue$4.run(EventQueue.java:716)
    at java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:741)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:203)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:124)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:109)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:101)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:90)

@brendanw
Copy link

Just saw this on my app which is using compose 1.6.0-rc02

kotlinx.coroutines.CompletionHandlerException: Exception in resume onCancellation handler for CancellableContinuation(DispatchedContinuation[AndroidUiDispatcher@8f05670, Continuation at androidx.compose.foundation.gestures.PressGestureScopeImpl.reset(TapGestureDetector.kt:357)@d1b850f]){Completed}@fdc699c
        at kotlinx.coroutines.CancellableContinuationImpl.callOnCancellation(CancellableContinuationImpl.kt:264)
        at kotlinx.coroutines.CompletedContinuation.invokeHandlers(CancellableContinuationImpl.kt:659)
        at kotlinx.coroutines.CancellableContinuationImpl.cancelCompletedResult$kotlinx_coroutines_core(CancellableContinuationImpl.kt:180)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
        at android.os.Handler.handleCallback(Handler.java:958)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:205)
        at android.os.Looper.loop(Looper.java:294)
        at android.app.ActivityThread.main(ActivityThread.java:8177)
        at java.lang.reflect.Method.invoke(Method.java:-2)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

Caused by: java.lang.IllegalStateException: This mutex is not locked
        at kotlinx.coroutines.sync.MutexImpl.unlock(Mutex.kt:212)
        at kotlinx.coroutines.sync.MutexImpl$CancellableContinuationWithOwner$tryResume$token$1.invoke(Mutex.kt:260)
        at kotlinx.coroutines.sync.MutexImpl$CancellableContinuationWithOwner$tryResume$token$1.invoke(Mutex.kt:257)
        at kotlinx.coroutines.CancellableContinuationImpl.callOnCancellation(CancellableContinuationImpl.kt:259)
        at kotlinx.coroutines.CompletedContinuation.invokeHandlers(CancellableContinuationImpl.kt:659)
        at kotlinx.coroutines.CancellableContinuationImpl.cancelCompletedResult$kotlinx_coroutines_core(CancellableContinuationImpl.kt:180)
        at kotlinx.coroutines.DispatchedTask.run(DispatchedTask.kt:102)
        at androidx.compose.ui.platform.AndroidUiDispatcher.performTrampolineDispatch(AndroidUiDispatcher.android.kt:81)
        at androidx.compose.ui.platform.AndroidUiDispatcher.access$performTrampolineDispatch(AndroidUiDispatcher.android.kt:41)
        at androidx.compose.ui.platform.AndroidUiDispatcher$dispatchCallback$1.run(AndroidUiDispatcher.android.kt:57)
        at android.os.Handler.handleCallback(Handler.java:958)
        at android.os.Handler.dispatchMessage(Handler.java:99)
        at android.os.Looper.loopOnce(Looper.java:205)
        at android.os.Looper.loop(Looper.java:294)
        at android.app.ActivityThread.main(ActivityThread.java:8177)
        at java.lang.reflect.Method.invoke(Method.java:-2)
        at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:552)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:971)

@dima-avdeev-jb
Copy link
Contributor

@Syer10 @brendanw
Hello!
Can you please try to use Compose version 1.6.0-rc03 and if problems still occurs, then create a mininal reproducible sample project?

Also can you please describe some details:
Are you using Windows with touchscreen?
How to reproduce this exception?

@dima-avdeev-jb
Copy link
Contributor

@brendanw As I understand in your logs is that you founded this crash on Android device?

@acarlsen
Copy link

acarlsen commented Mar 11, 2024

I just had this error with 1.6.0 for one of my users (reported on Sentry.io).
The app is a JVM desktop app, and was running on a Windows x64/AcerAspireS3602.

Affected platforms

  • Desktop (Windows JVM)

Versions

  • Kotlin version: 1.9.22
  • Compose Multiplatform version*: 1.6.0
  • OS version(s)* (required for Desktop and iOS issues): Windows x64 (Sentry.io doesn't give my more)
  • OS architecture (x86 or arm64): x86
  • JDK (for desktop issues): 17 (JetBrains s.r.o 17.0.9)

To Reproduce

  • I don't know how to recreate it (don't have desktop with touchscreen).

Stacktrace below:

java.lang.IllegalStateException: This mutex is not locked
    at kotlinx.coroutines.sync.MutexImpl.unlock(SourceFile:208)
    at kotlinx.coroutines.sync.MutexImpl$CancellableContinuationWithOwner$tryResume$token$1.invoke(SourceFile:256)
    at kotlinx.coroutines.sync.MutexImpl$CancellableContinuationWithOwner$tryResume$token$1.invoke(SourceFile:253)
    at kotlinx.coroutines.CancellableContinuationImpl.callOnCancellation(SourceFile:255)
    at kotlinx.coroutines.CompletedContinuation.invokeHandlers(SourceFile:655)
    at kotlinx.coroutines.CancellableContinuationImpl.cancelCompletedResult$kotlinx_coroutines_core(SourceFile:176)
    at kotlinx.coroutines.DispatchedTask.run(SourceFile:98)
    at b.b.f.l.F$b.a(SourceFile:90)
    at b.b.f.l.F$b.invoke(SourceFile:78)
    at b.b.f.l.F.a(SourceFile:99)
    at b.b.f.l.F.a(SourceFile:78)
    at b.b.f.n.A.c(SourceFile:88)
    at b.b.f.n.a.a(SourceFile:165)
    at b.b.f.n.u.onRender(SourceFile:562)
    at org.jetbrains.skiko.SkiaLayer.update$skiko(SourceFile:548)
    at org.jetbrains.skiko.redrawer.AWTRedrawer.update(SourceFile:54)
    at org.jetbrains.skiko.redrawer.WindowsOpenGLRedrawer$Companion$frameDispatcher$1.invokeSuspend(SourceFile:98)
    at org.jetbrains.skiko.redrawer.WindowsOpenGLRedrawer$Companion$frameDispatcher$1.invoke(SourceFile)
    at org.jetbrains.skiko.redrawer.WindowsOpenGLRedrawer$Companion$frameDispatcher$1.invoke(SourceFile)
    at org.jetbrains.skiko.FrameDispatcher$job$1.invokeSuspend(SourceFile:33)
    at kotlin.coroutines.jvm.internal.BaseContinuationImpl.resumeWith(SourceFile:33)
    at kotlinx.coroutines.DispatchedTask.run(SourceFile:104)
    at java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:318)
    at java.awt.EventQueue.dispatchEventImpl(EventQueue.java:792)
    at java.awt.EventQueue$3.run(EventQueue.java:739)
    at java.awt.EventQueue$3.run(EventQueue.java:733)
    at java.security.AccessController.doPrivileged(AccessController.java:399)
    at java.security.ProtectionDomain$JavaSecurityAccessImpl.doIntersectionPrivilege(ProtectionDomain.java:86)
    at java.awt.EventQueue.dispatchEvent(EventQueue.java:761)
    at java.awt.EventDispatchThread.pumpOneEventForFilters(EventDispatchThread.java:207)
    at java.awt.EventDispatchThread.pumpEventsForFilter(EventDispatchThread.java:128)
    at java.awt.EventDispatchThread.pumpEventsForHierarchy(EventDispatchThread.java:117)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:113)
    at java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:105)
    at java.awt.EventDispatchThread.run(EventDispatchThread.java:92)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants