# Coroutines and cancelling blocking code

**URL:** <https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165>\
**Category:** Libraries\
**Created:** [March 29, 2019, 3:46pm UTC](https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165 "2019-03-29T15:46:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![fra](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fra/32/4468_2.png) [@fra](https://discuss.kotlinlang.org/u/fra)\
**Post date:** [March 29, 2019, 3:46pm UTC](https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165/1 "2019-03-29T15:46:58Z")

</div>

I have to interact with a blocking library from coroutine code and want to be able to cancel the blocking call. The situation is something similar to the following

```auto
import kotlinx.coroutines.*

fun main() {
  val jobA = GlobalScope.launch {
    someSuspendedFun()
    println("Done A")
  }
  val jobB = GlobalScope.launch(Dispatchers.IO) {
    someLibraryBlockingFun()
    println("Done B")
  }

  runBlocking {
    delay(500)
    jobA.cancel()
    jobB.cancel()

    joinAll(jobA, jobB)
  }
}

suspend fun someSuspendedFun() {
  delay(1_000)
}

fun someLibraryBlockingFun() {
  Thread.sleep(1_000)
}

```

here `jobB.cancel()` doesn’t work because it will not `Thread#interrupt` the `Thread.sleep(...)` call, so `Done B` gets printed. What should I do in this kind of situation?

Thanks

---

<div class="post-metadata">

**Author:** ![fra](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/fra/32/4468_2.png) [@fra](https://discuss.kotlinlang.org/u/fra)\
**Post date:** [March 29, 2019, 4:14pm UTC](https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165/2 "2019-03-29T16:14:07Z")

</div>

I thought I should also post what I’m doing right now, which is something similar to this

```auto

import kotlinx.coroutines.*
import java.util.concurrent.Executors
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

val exec = Executors.newCachedThreadPool()

fun main() {
  val job = GlobalScope.launch {
    runCancellableBlocking {
      Thread.sleep(1_000)
    }
    println("Done")
  }

  runBlocking {
    delay(500)
    job.cancelAndJoin()
  }

  exec.shutdown()
}

suspend fun <E> runCancellableBlocking(block: () -> E): E {
  return suspendCancellableCoroutine { cont ->
    val f = exec.submit {
      try {
        cont.resume(block())
      }
      catch (e: InterruptedException) {
        cont.cancel()
      }
      catch(e: Exception) {
        cont.resumeWithException(e)
      }
    }
    cont.invokeOnCancellation {
      f.cancel(true)
    }
  }
}

```

but it doesn’t seem very idiomatic, so I was wondering if there is a better way.

---

<div class="post-metadata">

**Author:** ![wlezzar](https://avatars.discourse-cdn.com/v4/letter/w/d78d45/32.png) [@wlezzar](https://discuss.kotlinlang.org/u/wlezzar)\
**Post date:** [March 19, 2022, 8:41pm UTC](https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165/3 "2022-03-19T20:41:05Z")

</div>

Take a look at [runInterruptible](https://kotlin.github.io/kotlinx.coroutines/kotlinx-coroutines-core/kotlinx.coroutines/run-interruptible.html) which is exactly built for this purpose.

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [March 20, 2022, 11:14am UTC](https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165/4 "2022-03-20T11:14:29Z")

</div>

You can’t cancel blocking code from a coroutine. It is not possible at all. Some libraries check for the thread interuption flag in a cycle. If you want to use that, you need to launch a separate dispatcher for that.

`runInterruptible` allows to interrupt a coroutine in a suspesion point or during the `delay`, but not the blocking code.

---

<div class="post-metadata">

**Author:** ![broot](https://avatars.discourse-cdn.com/v4/letter/b/a88e57/32.png) [@broot](https://discuss.kotlinlang.org/u/broot)\
**Post date:** [March 20, 2022, 12:22pm UTC](https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165/5 "2022-03-20T12:22:54Z")

</div>

> [@darksnake](#):
>
> `runInterruptible` allows to interrupt a coroutine in a suspesion point or during the `delay` , but not the blocking code.

Doesn’t this depend on whether the blocking operation is interruptible or not? For example, `runInterruptible()` won’t work with `Socket`, but it should with `SocketChannel`. Although, it is a matter of what we mean by “blocking”. As I understand, `SocketChannel` uses non-blocking IO underneath, but it blocks the thread while waiting for IO.

But generally speaking: no, `runInterruptible()` isn’t a bulletproof solution to running synchronous IO.

Some time ago I explored the topic of how to properly handle synchronous IO with coroutines, especially regarding cancellations. I think this topic isn’t very well documented in official docs (?). I found 3 possible solutions:

1. `runInterruptible()` if we know IO is interruptible.
2. Create an utility that automatically closes a resource on cancellation. Something like: [Cancel blocking function after timeout without 'select' - #2 by broot](https://discuss.kotlinlang.org/t/cancel-blocking-function-after-timeout-without-select/24411/2) . This seems like the best solution in most cases, but it requires that we know a resource that is related to the IO operation.
3. Run IO inside a child coroutine and make the parent not wait for it on cancellation. I didn’t find a way to do it properly, but I was able to achieve this with some hacking: [Coroutine/Job that doesn't join its children when cancelled](https://discuss.kotlinlang.org/t/coroutine-job-that-doesnt-join-its-children-when-cancelled/23149)

---

<div class="post-metadata">

**Author:** ![darksnake](https://sea1.discourse-cdn.com/flex019/user_avatar/discuss.kotlinlang.org/darksnake/32/2479_2.png) [@darksnake](https://discuss.kotlinlang.org/u/darksnake)\
**Post date:** [March 20, 2022, 4:29pm UTC](https://discuss.kotlinlang.org/t/coroutines-and-cancelling-blocking-code/12165/6 "2022-03-20T16:29:20Z")

</div>

The only way to interrupt the blocking code externally if it does not support this in the API is to set interrupted flag in the thread (like [this](https://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#interrupt())). Then the code could tread this flag calling `isInterrupted` or not. From the coroutine in order to use it, you need to run the coroutine on the separate thread and then call `interrupt` on `Job` cancelation. The separate thread is required to ensure you do not spoil threads from default thread pool.

Actually, I just checked and runInterrputably is doing [just that](https://github.com/Kotlin/kotlinx.coroutines/blob/0d26d6c389ab29661383591f6e3c3f21caceb402/kotlinx-coroutines-core/jvm/src/Interruptible.kt#L41). So my previous comment was wrong. But still the blocking code must treat thread interruption correctly.
