Kotlinx.coroutines: native-mt: Mutex cannot be frozen

Created on 22 Sep 2020  路  2Comments  路  Source: Kotlin/kotlinx.coroutines

Version: 1.3.9-native-mt-2

When freezing Mutex and using it like this:

import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.sync.Mutex
import kotlin.native.concurrent.freeze

fun mutexExample() = runBlocking {
    val mutex = Mutex()
    mutex.freeze()

    mutex.lock()

    GlobalScope.launch {
        mutex.lock()
        mutex.unlock()
    }

    // Make sure GlobalScope.launch tries to lock, I'm sure there is a better way but this reproduces the issue.
    delay(1000)

    mutex.unlock()
}

The following exception is thrown:

Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.sync.MutexImpl.LockedQueue@825444e8
    at 0   common                              0x0000000106b58198 kfun:kotlin.Throwable#<init>(kotlin.String?){} + 92
    at 1   common                              0x0000000106b510b4 kfun:kotlin.Exception#<init>(kotlin.String?){} + 88
    at 2   common                              0x0000000106b50acc kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 88
    at 3   common                              0x0000000106b84c70 kfun:kotlin.native.concurrent.InvalidMutabilityException#<init>(kotlin.String){} + 88
    at 4   common                              0x0000000106b86088 ThrowInvalidMutabilityException + 468
    at 5   common                              0x0000000107f67178 MutationCheck + 132
    at 6   common                              0x0000000106ce8750 kfun:kotlinx.coroutines.sync.MutexImpl.LockedQueue.<set-owner>#internal + 104
    at 7   common                              0x0000000106ce7c4c kfun:kotlinx.coroutines.sync.MutexImpl#unlock(kotlin.Any?){} + 2628
    at 8   common                              0x0000000106ce3460 kfun:kotlinx.coroutines.sync.Mutex#unlock$default(kotlin.Any?;kotlin.Int){} + 264
    at 9   common                              0x0000000106f41d00 kfun:com.superthomaslab.hueessentials.common.utils.$mutexExample$lambda-3COROUTINE$30.invokeSuspend#internal + 1336
    at 10  common                              0x0000000106b784ec kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 532
    at 11  common                              0x0000000106cd0da0 kfun:kotlinx.coroutines.DispatchedTask#run(){} + 2236
    at 12  common                              0x0000000106c4875c kfun:kotlinx.coroutines.EventLoopImplBase#processNextEvent(){}kotlin.Long + 616
    at 13  common                              0x0000000106cfa5cc kfun:kotlinx.coroutines#runEventLoop(kotlinx.coroutines.EventLoop?;kotlin.Function0<kotlin.Boolean>){} + 716
    at 14  common                              0x0000000106cf96a0 kfun:kotlinx.coroutines.BlockingCoroutine.joinBlocking#internal + 284
    at 15  common                              0x0000000106cf886c kfun:kotlinx.coroutines#runBlocking(kotlin.coroutines.CoroutineContext;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>){0搂<kotlin.Any?>}0:0 + 1000
    at 16  common                              0x0000000106cf8cc8 kfun:kotlinx.coroutines#runBlocking$default(kotlin.coroutines.CoroutineContext?;kotlin.coroutines.SuspendFunction1<kotlinx.coroutines.CoroutineScope,0:0>;kotlin.Int){0搂<kotlin.Any?>}0:0 + 260
    at 17  common                              0x0000000106f3f2c8 kfun:com.superthomaslab.hueessentials.common.utils#mutexExample(){} + 156
    at 18  common                              0x0000000107f29d64 objc2kotlin.24755 + 96
    at 19  HueEssentials-dev                   0x000000010459182c $s17HueEssentials_dev11AppDelegateC11application_29didFinishLaunchingWithOptionsSbSo13UIApplicationC_SDySo0l6LaunchK3KeyaypGSgtFTo + 212
    at 20  UIKitCore                           0x000000019186ca68 47154C6D-47DF-3ABB-A152-56B159B014E4 + 12032616
    at 21  UIKitCore                           0x000000019186eac4 47154C6D-47DF-3ABB-A152-56B159B014E4 + 12040900
    at 22  UIKitCore                           0x0000000191874478 47154C6D-47DF-3ABB-A152-56B159B014E4 + 12063864
    at 23  UIKitCore                           0x0000000190f05db0 47154C6D-47DF-3ABB-A152-56B159B014E4 + 2174384
    at 24  UIKitCore                           0x00000001918702f0 47154C6D-47DF-3ABB-A152-56B159B014E4 + 12047088
    at 25  UIKitCore                           0x0000000191870710 47154C6D-47DF-3ABB-A152-56B159B014E4 + 12048144
    at 26  UIKitCore                           0x0000000191875e10 UIApplicationMain + 168
    at 27  HueEssentials-dev                   0x0000000104592878 main + 88
    at 28  libdyld.dylib                       0x000000018eb93e60 90A4E82E-250C-35E3-8B2D-51D6D8B1119B + 3680

Because of this bug Mutex cannot be used on native as it crashes when trying to unlock. A workaround is to use Semaphore(1) instead of Mutex, but it would be nice if support for freezing Mutex could be added as well.

See also: https://youtrack.jetbrains.com/issue/KT-38770

native

Most helpful comment

Wow you fixed that really fast, thanks!

Unfortunately this issue is affecting a few features of Ktor 1.4.1 as well (AcceptAllCookiesStorage, MockEngine, and Logging). I included the stack trace below of a crash I keep running into with Ktor Logging. Looks like exactly the same bug, so that should be fixed already in a future native-mt version. I'm only using the Logging feature of these, so not a big issue for me as I can just disable that for now.

Uncaught Kotlin exception: kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for CancellableContinuation(Shareable[used]){CancelledContinuation[kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@7c3603c8]}@7d9eacf8. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
    at 0   common                              0x00000001052fb790 kfun:kotlin.Error#<init>(kotlin.String?;kotlin.Throwable?){} + 116
    at 1   common                              0x00000001053f6c98 kfun:kotlinx.coroutines.CoroutinesInternalError#<init>(kotlin.String;kotlin.Throwable){} + 116
    at 2   common                              0x000000010547b684 kfun:kotlinx.coroutines.DispatchedTask#handleFatalException(kotlin.Throwable?;kotlin.Throwable?){} + 708
    at 3   common                              0x000000010547b35c kfun:kotlinx.coroutines.DispatchedTask#run(){} + 2872
    at 4   common                              0x00000001054b5bbc kfun:kotlinx.coroutines.DarwinMainDispatcher.dispatch$lambda-0#internal + 112
    at 5   common                              0x00000001054b5f60 kfun:kotlinx.coroutines.DarwinMainDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$760.invoke#internal + 64
    at 6   common                              0x00000001054b5fc0 kfun:kotlinx.coroutines.DarwinMainDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$760.$<bridge-UNN>invoke(){}#internal + 64
    at 7   common                              0x00000001054b7058 _6f72672e6a6574627261696e732e6b6f746c696e783a6b6f746c696e782d636f726f7574696e65732d636f7265_knbridge1052 + 188
    at 8   libdispatch.dylib                   0x0000000108dfbb68 _dispatch_call_block_and_release + 32
    at 9   libdispatch.dylib                   0x0000000108dfd5f0 _dispatch_client_callout + 20
    at 10  libdispatch.dylib                   0x0000000108e0c890 _dispatch_main_queue_callback_4CF + 1000
    at 11  CoreFoundation                      0x000000018eed31e4 472C9193-115D-34CD-AD1D-0E7E091C9432 + 647652
    at 12  CoreFoundation                      0x000000018eecd3b4 472C9193-115D-34CD-AD1D-0E7E091C9432 + 623540
    at 13  CoreFoundation                      0x000000018eecc4bc CFRunLoopRunSpecific + 600
    at 14  GraphicsServices                    0x00000001a5951820 GSEventRunModal + 164
    at 15  UIKitCore                           0x0000000191870734 47154C6D-47DF-3ABB-A152-56B159B014E4 + 12048180
    at 16  UIKitCore                           0x0000000191875e10 UIApplicationMain + 168
    at 17  HueEssentials-dev                   0x0000000102c5174c main + 88
    at 18  libdyld.dylib                       0x000000018eb93e60 90A4E82E-250C-35E3-8B2D-51D6D8B1119B + 3680
Caused by: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.sync.MutexImpl.LockedQueue@83cf97a8
    at 0   common                              0x00000001053020b8 kfun:kotlin.Throwable#<init>(kotlin.String?){} + 92
    at 1   common                              0x00000001052fafd4 kfun:kotlin.Exception#<init>(kotlin.String?){} + 88
    at 2   common                              0x00000001052fa9ec kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 88
    at 3   common                              0x000000010532eb90 kfun:kotlin.native.concurrent.InvalidMutabilityException#<init>(kotlin.String){} + 88
    at 4   common                              0x000000010532ffa8 ThrowInvalidMutabilityException + 468
    at 5   common                              0x000000010675706c MutationCheck + 132
    at 6   common                              0x0000000105492a90 kfun:kotlinx.coroutines.sync.MutexImpl.LockedQueue.<set-owner>#internal + 104
    at 7   common                              0x0000000105491f8c kfun:kotlinx.coroutines.sync.MutexImpl#unlock(kotlin.Any?){} + 2628
    at 8   common                              0x000000010548da70 kfun:kotlinx.coroutines.sync.Mutex#unlock$default(kotlin.Any?;kotlin.Int){} + 264
    at 9   common                              0x000000010563e760 kfun:io.ktor.client.features.logging.Logging.doneLogging#internal + 164
    at 10  common                              0x0000000105644ecc kfun:io.ktor.client.features.logging.Logging.Companion.$install$lambda-3COROUTINE$1218.invokeSuspend#internal + 740
    at 11  common                              0x000000010532240c kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 532
    at 12  common                              0x000000010547c480 kfun:kotlinx.coroutines#[email protected]<0:0>(kotlin.coroutines.Continuation<0:0>;kotlin.Int){0搂<kotlin.Any?>} + 1188
    at 13  common                              0x000000010547be4c kfun:kotlinx.coroutines.resumeUnconfined#internal + 440
    at 14  common                              0x000000010547bad8 kfun:kotlinx.coroutines#[email protected]<0:0>(kotlin.Int){0搂<kotlin.Any?>} + 744
    at 15  common                              0x00000001053e7f00 kfun:kotlinx.coroutines.CancellableContinuationImpl.dispatchResume#internal + 108
    at 16  common                              0x00000001053e81a4 kfun:kotlinx.coroutines.CancellableContinuationImpl.resumeImpl#internal + 640
    at 17  common                              0x00000001053e6f10 kfun:kotlinx.coroutines.CancellableContinuationImpl#resumeWith(kotlin.Result<1:0>){} + 236
    at 18  common                              0x000000010540e0d4 kfun:kotlinx.coroutines.ResumeOnCompletion.invoke#internal + 364
    at 19  common                              0x00000001053fb678 kfun:kotlinx.coroutines.JobSupport.completeStateFinalization#internal + 676
    at 20  common                              0x00000001053fb1a8 kfun:kotlinx.coroutines.JobSupport.tryFinalizeSimpleState#internal + 652
    at 21  common                              0x0000000105403dc4 kfun:kotlinx.coroutines.JobSupport.tryMakeCompleting#internal + 712
    at 22  common                              0x0000000105403570 kfun:kotlinx.coroutines.JobSupport#makeCompleting(kotlin.Any?){}kotlin.Boolean + 264
    at 23  common                              0x000000010540be48 kfun:kotlinx.coroutines.JobImpl#complete(){}kotlin.Boolean + 68
    at 24  common                              0x0000000105540438 kfun:io.ktor.utils.io.internal.AwaitingSlot#cancel(kotlin.Throwable?){} + 464
    at 25  common                              0x00000001054d28cc kfun:io.ktor.utils.io.ByteChannelSequentialBase#close(kotlin.Throwable?){}kotlin.Boolean + 444
    at 26  common                              0x0000000105546bf0 kfun:io.ktor.utils.io.ByteChannelNative#close(kotlin.Throwable?){}kotlin.Boolean + 172
    at 27  common                              0x00000001054dac54 kfun:io.ktor.utils.io#[email protected](){}kotlin.Boolean + 116
    at 28  common                              0x0000000105573e98 kfun:io.ktor.util.$split$lambda-0COROUTINE$1278.invokeSuspend#internal + 2768
    at 29  common                              0x000000010532240c kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 532

All 2 comments

Wow you fixed that really fast, thanks!

Unfortunately this issue is affecting a few features of Ktor 1.4.1 as well (AcceptAllCookiesStorage, MockEngine, and Logging). I included the stack trace below of a crash I keep running into with Ktor Logging. Looks like exactly the same bug, so that should be fixed already in a future native-mt version. I'm only using the Logging feature of these, so not a big issue for me as I can just disable that for now.

Uncaught Kotlin exception: kotlinx.coroutines.CoroutinesInternalError: Fatal exception in coroutines machinery for CancellableContinuation(Shareable[used]){CancelledContinuation[kotlinx.coroutines.JobCancellationException: StandaloneCoroutine was cancelled; job=StandaloneCoroutine{Cancelling}@7c3603c8]}@7d9eacf8. Please read KDoc to 'handleFatalException' method and report this incident to maintainers
    at 0   common                              0x00000001052fb790 kfun:kotlin.Error#<init>(kotlin.String?;kotlin.Throwable?){} + 116
    at 1   common                              0x00000001053f6c98 kfun:kotlinx.coroutines.CoroutinesInternalError#<init>(kotlin.String;kotlin.Throwable){} + 116
    at 2   common                              0x000000010547b684 kfun:kotlinx.coroutines.DispatchedTask#handleFatalException(kotlin.Throwable?;kotlin.Throwable?){} + 708
    at 3   common                              0x000000010547b35c kfun:kotlinx.coroutines.DispatchedTask#run(){} + 2872
    at 4   common                              0x00000001054b5bbc kfun:kotlinx.coroutines.DarwinMainDispatcher.dispatch$lambda-0#internal + 112
    at 5   common                              0x00000001054b5f60 kfun:kotlinx.coroutines.DarwinMainDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$760.invoke#internal + 64
    at 6   common                              0x00000001054b5fc0 kfun:kotlinx.coroutines.DarwinMainDispatcher.$dispatch$lambda-0$FUNCTION_REFERENCE$760.$<bridge-UNN>invoke(){}#internal + 64
    at 7   common                              0x00000001054b7058 _6f72672e6a6574627261696e732e6b6f746c696e783a6b6f746c696e782d636f726f7574696e65732d636f7265_knbridge1052 + 188
    at 8   libdispatch.dylib                   0x0000000108dfbb68 _dispatch_call_block_and_release + 32
    at 9   libdispatch.dylib                   0x0000000108dfd5f0 _dispatch_client_callout + 20
    at 10  libdispatch.dylib                   0x0000000108e0c890 _dispatch_main_queue_callback_4CF + 1000
    at 11  CoreFoundation                      0x000000018eed31e4 472C9193-115D-34CD-AD1D-0E7E091C9432 + 647652
    at 12  CoreFoundation                      0x000000018eecd3b4 472C9193-115D-34CD-AD1D-0E7E091C9432 + 623540
    at 13  CoreFoundation                      0x000000018eecc4bc CFRunLoopRunSpecific + 600
    at 14  GraphicsServices                    0x00000001a5951820 GSEventRunModal + 164
    at 15  UIKitCore                           0x0000000191870734 47154C6D-47DF-3ABB-A152-56B159B014E4 + 12048180
    at 16  UIKitCore                           0x0000000191875e10 UIApplicationMain + 168
    at 17  HueEssentials-dev                   0x0000000102c5174c main + 88
    at 18  libdyld.dylib                       0x000000018eb93e60 90A4E82E-250C-35E3-8B2D-51D6D8B1119B + 3680
Caused by: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.sync.MutexImpl.LockedQueue@83cf97a8
    at 0   common                              0x00000001053020b8 kfun:kotlin.Throwable#<init>(kotlin.String?){} + 92
    at 1   common                              0x00000001052fafd4 kfun:kotlin.Exception#<init>(kotlin.String?){} + 88
    at 2   common                              0x00000001052fa9ec kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 88
    at 3   common                              0x000000010532eb90 kfun:kotlin.native.concurrent.InvalidMutabilityException#<init>(kotlin.String){} + 88
    at 4   common                              0x000000010532ffa8 ThrowInvalidMutabilityException + 468
    at 5   common                              0x000000010675706c MutationCheck + 132
    at 6   common                              0x0000000105492a90 kfun:kotlinx.coroutines.sync.MutexImpl.LockedQueue.<set-owner>#internal + 104
    at 7   common                              0x0000000105491f8c kfun:kotlinx.coroutines.sync.MutexImpl#unlock(kotlin.Any?){} + 2628
    at 8   common                              0x000000010548da70 kfun:kotlinx.coroutines.sync.Mutex#unlock$default(kotlin.Any?;kotlin.Int){} + 264
    at 9   common                              0x000000010563e760 kfun:io.ktor.client.features.logging.Logging.doneLogging#internal + 164
    at 10  common                              0x0000000105644ecc kfun:io.ktor.client.features.logging.Logging.Companion.$install$lambda-3COROUTINE$1218.invokeSuspend#internal + 740
    at 11  common                              0x000000010532240c kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 532
    at 12  common                              0x000000010547c480 kfun:kotlinx.coroutines#[email protected]<0:0>(kotlin.coroutines.Continuation<0:0>;kotlin.Int){0搂<kotlin.Any?>} + 1188
    at 13  common                              0x000000010547be4c kfun:kotlinx.coroutines.resumeUnconfined#internal + 440
    at 14  common                              0x000000010547bad8 kfun:kotlinx.coroutines#[email protected]<0:0>(kotlin.Int){0搂<kotlin.Any?>} + 744
    at 15  common                              0x00000001053e7f00 kfun:kotlinx.coroutines.CancellableContinuationImpl.dispatchResume#internal + 108
    at 16  common                              0x00000001053e81a4 kfun:kotlinx.coroutines.CancellableContinuationImpl.resumeImpl#internal + 640
    at 17  common                              0x00000001053e6f10 kfun:kotlinx.coroutines.CancellableContinuationImpl#resumeWith(kotlin.Result<1:0>){} + 236
    at 18  common                              0x000000010540e0d4 kfun:kotlinx.coroutines.ResumeOnCompletion.invoke#internal + 364
    at 19  common                              0x00000001053fb678 kfun:kotlinx.coroutines.JobSupport.completeStateFinalization#internal + 676
    at 20  common                              0x00000001053fb1a8 kfun:kotlinx.coroutines.JobSupport.tryFinalizeSimpleState#internal + 652
    at 21  common                              0x0000000105403dc4 kfun:kotlinx.coroutines.JobSupport.tryMakeCompleting#internal + 712
    at 22  common                              0x0000000105403570 kfun:kotlinx.coroutines.JobSupport#makeCompleting(kotlin.Any?){}kotlin.Boolean + 264
    at 23  common                              0x000000010540be48 kfun:kotlinx.coroutines.JobImpl#complete(){}kotlin.Boolean + 68
    at 24  common                              0x0000000105540438 kfun:io.ktor.utils.io.internal.AwaitingSlot#cancel(kotlin.Throwable?){} + 464
    at 25  common                              0x00000001054d28cc kfun:io.ktor.utils.io.ByteChannelSequentialBase#close(kotlin.Throwable?){}kotlin.Boolean + 444
    at 26  common                              0x0000000105546bf0 kfun:io.ktor.utils.io.ByteChannelNative#close(kotlin.Throwable?){}kotlin.Boolean + 172
    at 27  common                              0x00000001054dac54 kfun:io.ktor.utils.io#[email protected](){}kotlin.Boolean + 116
    at 28  common                              0x0000000105573e98 kfun:io.ktor.util.$split$lambda-0COROUTINE$1278.invokeSuspend#internal + 2768
    at 29  common                              0x000000010532240c kfun:kotlin.coroutines.native.internal.BaseContinuationImpl#resumeWith(kotlin.Result<kotlin.Any?>){} + 532

Fixed in 1.4.1-native-mt

Was this page helpful?
0 / 5 - 0 ratings