Hi, is `suspendCoroutine` broken in `1.3.9-native-...
# multiplatform
m
Hi, is
suspendCoroutine
broken in
1.3.9-native-mt-2
? I'm getting an error like on iOS:
Copy code
Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlin.coroutines.SafeContinuation@368d808
<unknown>:0: error: -[Example_iOS_Tests.SharedModuleTests testSharedModule] : Unexpected Failure
/Users/jenkins4/workspace/q-lib-branch_feature_screensArch/Example/Example-iOS/Example-Tests/SharedModuleTests.swift:113: error: -[Example_iOS_Tests.SharedModuleTests testSharedModule] : Failed due to unwaited expectation 'Test Shared Module'.
Test Case '-[Example_iOS_Tests.SharedModuleTests testSharedModule]' failed (0.190 seconds).
whole stack
Copy code
Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlin.coroutines.SafeContinuation@368d808
<unknown>:0: error: -[Example_iOS_Tests.SharedModuleTests testSharedModule] : Unexpected Failure
/Users/jenkins4/workspace/q-lib-branch_feature_screensArch/Example/Example-iOS/Example-Tests/SharedModuleTests.swift:113: error: -[Example_iOS_Tests.SharedModuleTests testSharedModule] : Failed due to unwaited expectation 'Test Shared Module'.
Test Case '-[Example_iOS_Tests.SharedModuleTests testSharedModule]' failed (0.190 seconds).
Test Case '-[Example_iOS_Tests.SharedModuleTests testSimple]' started.
########### make call
first
    at 0   MobileLibShared                    0x000000010d375c8d kfun:kotlin.Throwable#<init>(kotlin.String?){} + 93 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/Throwable.kt:23:37)
    at 1   MobileLibShared                    0x000000010d36f77b kfun:kotlin.Exception#<init>(kotlin.String?){} + 91 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/Exceptions.kt:23:44)
    at 2   MobileLibShared                    0x000000010d36f9cb kfun:kotlin.RuntimeException#<init>(kotlin.String?){} + 91 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/Exceptions.kt:34:44)
    at 3   MobileLibShared                    0x000000010d39d8fb kfun:kotlin.native.concurrent.InvalidMutabilityException#<init>(kotlin.String){} + 91 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/native/concurrent/Freezing.kt:22:60)
    at 4   MobileLibShared                    0x000000010d39f1b2 ThrowInvalidMutabilityException + 690 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/native/concurrent/Internal.kt:92:11)
    at 5   MobileLibShared                    0x000000010d40633c MutationCheck + 108
    at 6   MobileLibShared                    0x000000010d397866 kfun:kotlin.coroutines.SafeContinuation.<set-result>#internal + 102 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/coroutines/SafeContinuationNative.kt:25:13)
    at 7   MobileLibShared                    0x000000010d397b1e kfun:kotlin.coroutines.SafeContinuation#resumeWith(kotlin.Result<1:0>){} + 638 (/Users/teamcity/buildAgent/work/cae0e6559deed4c4/runtime/src/main/kotlin/kotlin/coroutines/SafeContinuationNative.kt:30:34)
    at 8   MobileLibShared                    0x000000010d32ed16 kfun:pl.project.square.lib.network.SuspendApiCall.object-1.result#internal + 550 (/Users/jenkins4/workspace/q-lib-branch_feature_screensArch/Sources/shared/src/commonMain/kotlin/pl/project/square/lib/network/SuspendApiCall.kt:26:21)
    at 9   MobileLibShared                    0x000000010d332897 objc2kotlin.33 + 247
    at 10  Example-iOS-Tests                   0x000000010da96ef0 $sIeg_IeyB_TR + 48
    at 11  libdispatch.dylib                   0x00007fff2010535b _dispatch_call_block_and_release + 12
    at 12  libdispatch.dylib                   0x00007fff20106534 _dispatch_client_callout + 8
    at 13  libdispatch.dylib                   0x00007fff2010c425 _dispatch_lane_serial_drain + 715
    at 14  libdispatch.dylib                   0x00007fff2010cfa0 _dispatch_lane_invoke + 403
    at 15  libdispatch.dylib                   0x00007fff20117591 _dispatch_workloop_worker_thread + 782
    at 16  libsystem_pthread.dylib             0x00007fff5dcd8a3d _pthread_wqthread + 290
    at 17  libsystem_pthread.dylib             0x00007fff5dcd7b77 start_wqthread + 15
and code with probably to many freezes looks like this
Copy code
return suspendCoroutine { continuation ->
            continuation.freeze()
            apiCall.freeze()
            println("########### make call")
            val success: (String) -> Unit = {
                println("########### response: $it")
            }
            success.freeze()
            val callback = object : ApiCallback {
                override fun result(res: Response) {
                    res.freeze()
                    continuation.resume(res)
                    println("result $res")
                }

                override fun error(error: Throwable) {
                    TODO("Not yet implemented")
                }
            }
            callback.freeze()
            request.freeze()
            apiCall.get(request, callback)
        }
it failes on line:
continuation.resume(res)
m
that is why we have this
mt
coroutines, right?
I wanted to conver callback function to suspend function in common code
l
Do you run this code on more than one thread?
native-mt
enables switching dispatcher so long you don't capture mutable objects
m
yes, it's on multiplethreads
l
Then confine it to the main thread to avoid the issues
m
so we need to ensure that ios will return callback on the same thread as we called?
l
Yes, or you need to redispatch the callback to that thread
m
i'm trying to solve making request on iOS via interface in common
and ios is calling my callback from different thread
l
DispatchQueue.main.async
from Swift code, and a variant with Obj-C names from Kotlin code.
m
ok, makes sense, I just thought that
suspendCoroutine
implementation is immutable
l
You might want to use
suspendCancellableCoroutine
BTW
👍 1
m
It worked, thank you. Still I think that 
suspendCoroutine
 implementation should be immutable, created an issue for that if you are interested: https://youtrack.jetbrains.com/issue/KT-42876
l
I don't think it's possible to have
suspendCancellableCoroutine
be immutable since they hold a state machine.