JetBrains / kotlin-native

Kotlin/Native infrastructure
Apache License 2.0
7.02k stars 566 forks source link

kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.StandaloneCoroutine@28a82d8 #3745

Closed mishrabhilash closed 4 years ago

mishrabhilash commented 4 years ago

works on android, breaks on ios

code:

fun triggerNetworkCall(){
      GlobalScope.apply {
            launch(Background) {
                try {
                    val data = repository.getSettings()
                } catch (t: Throwable) {
                    Logger.d("ktor", t.message?:"null")
                }
            }
        }
}
 suspend fun getSettings(): String? {
        val response =  apiConfig.getReferralData()
        return response
}
suspend fun getReferralData(): String? {
       val localClient = HttpClient(PlatformHttpClient.httpClientEngine){
            install(JsonFeature)
        }
        return localClient.post {
            url {
                protocol = URLProtocol.HTTPS
                host = "postman-echo.com"
                encodedPath = "post"
            }
            contentType(ContentType.Application.Json)
            body = "{}"
            HttpMethod.Post
        }
}

This post request works in android but fails in iOS with following stack trace:

Uncaught Kotlin exception: kotlin.native.concurrent.InvalidMutabilityException: mutation attempt of frozen kotlinx.coroutines.StandaloneCoroutine@1a8b4e8

whereas a get request works on both platforms. Following is the function being used:

suspend fun getReferralData(): String? {
       val localClient = HttpClient(PlatformHttpClient.httpClientEngine){
            install(JsonFeature)
        }

        val address = Url("https://postman-echo.com/get?foo1=bar1&foo2=bar2")
        return localClient.get {
            url {
                url(address.toString())
            }
        }
}

Dispatchers definition: iOS

internal actual val Main: CoroutineDispatcher = NsQueueDispatcher(dispatch_get_main_queue())

internal actual val Background: CoroutineDispatcher = Main

internal class NsQueueDispatcher(
    private val dispatchQueue: dispatch_queue_t
) : CoroutineDispatcher() {
    override fun dispatch(context: CoroutineContext, block: Runnable) {
        dispatch_async(dispatchQueue) {
            block.run()
        }
    }
}

android

internal actual val Main: CoroutineDispatcher = Dispatchers.Main

internal actual val Background: CoroutineDispatcher = Dispatchers.Default
bharathns commented 4 years ago

@mishrabhilash Did you manage to get a solution for this

SvyatoslavScherbina commented 4 years ago

If you still encounter this problem, please open new issue on YouTrack with a reproducer (Gradle project that we could run locally and observe the problem)