Skip to content

withContext may execute code in the wrong context if the coroutineContext misleads it #4193

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

Closed
dkhalanskyjb opened this issue Jul 24, 2024 · 3 comments
Labels

Comments

@dkhalanskyjb
Copy link
Collaborator

Describe the bug

Encountered by the IntelliJ team.
withContext looks at the current coroutine context and decides whether it should perform a dispatch. However, the current coroutine context does not always correctly reflect which thread the coroutine executes on. So, withContext may believe that it doesn't have to dispatch when it actually does.

Provide a Reproducer

import kotlinx.coroutines.*

fun main() {
    runBlocking {
        launch(Dispatchers.Default, start = CoroutineStart.UNDISPATCHED) {
            // yield() // one way to work around this
            withContext(Dispatchers.Default) {
                // yield() // another way to work around this
                println("Current thread is ${Thread.currentThread()}")
            }
        }
    }
}

(https://pl.kotl.in/POeZD53Uw) prints

Current thread is Thread[main @coroutine#2,5,main]

which is not a Dispatchers.Default thread.

@dkhalanskyjb
Copy link
Collaborator Author

A slightly different case of the same:

import kotlinx.coroutines.withContext
import kotlinx.coroutines.Dispatchers
import kotlin.coroutines.*
import kotlin.coroutines.intrinsics.*

suspend fun x(input: Unit): Int {
    withContext(Dispatchers.Default) {
        println("Current thread is ${Thread.currentThread()}")
    }
    return 5
}

object MyContinuation: Continuation<Int> {
    override val context: CoroutineContext = Dispatchers.Default
    override fun resumeWith(result: Result<Int>) {
        println(result)
    }
}

fun main() {
    ::x.createCoroutineUnintercepted(Unit, MyContinuation).resumeWith(Result.success(Unit))
    Thread.sleep(200)
}

https://pl.kotl.in/iIvxOM2pT

Current thread is Thread[main,5,main]
Success(5)

@qwwdfsad
Copy link
Collaborator

See also #286

@dovchinnikov
Copy link
Contributor

I propose to proceed in #286

@dkhalanskyjb dkhalanskyjb closed this as not planned Won't fix, can't repro, duplicate, stale Jul 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants