Skip to content

Commit 14968cd

Browse files
committed
BlockingChecker: Updated docs and renamed to checkRunBlocking function
1 parent c75fd40 commit 14968cd

File tree

8 files changed

+35
-26
lines changed

8 files changed

+35
-26
lines changed

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-android.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,6 @@ public final class kotlinx/coroutines/experimental/android/HandlerContextKt {
2323

2424
public final class kotlinx/coroutines/experimental/android/MainLooperChecker : kotlinx/coroutines/experimental/BlockingChecker {
2525
public fun <init> ()V
26-
public fun runBlockingAllowed ()Z
26+
public fun checkRunBlocking ()V
2727
}
2828

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-core.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public final class kotlinx/coroutines/experimental/AwaitKt {
2323
}
2424

2525
public abstract interface class kotlinx/coroutines/experimental/BlockingChecker {
26-
public abstract fun runBlockingAllowed ()Z
26+
public abstract fun checkRunBlocking ()V
2727
}
2828

2929
public final class kotlinx/coroutines/experimental/BuildersKt {

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-javafx.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
public final class kotlinx/coroutines/experimental/javafx/ApplicationThreadChecker : kotlinx/coroutines/experimental/BlockingChecker {
22
public fun <init> ()V
3-
public fun runBlockingAllowed ()Z
3+
public fun checkRunBlocking ()V
44
}
55

66
public final class kotlinx/coroutines/experimental/javafx/JavaFx : kotlinx/coroutines/experimental/CoroutineDispatcher, kotlinx/coroutines/experimental/Delay {

binary-compatibility-validator/reference-public-api/kotlinx-coroutines-swing.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
public final class kotlinx/coroutines/experimental/swing/EventDispatchThreadChecker : kotlinx/coroutines/experimental/BlockingChecker {
22
public fun <init> ()V
3-
public fun runBlockingAllowed ()Z
3+
public fun checkRunBlocking ()V
44
}
55

66
public final class kotlinx/coroutines/experimental/swing/Swing : kotlinx/coroutines/experimental/CoroutineDispatcher, kotlinx/coroutines/experimental/Delay {

core/kotlinx-coroutines-core/src/Builders.kt

Lines changed: 14 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,8 @@ import kotlin.coroutines.experimental.*
3737
*/
3838
@Throws(InterruptedException::class)
3939
public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T {
40+
blockingChecker?.checkRunBlocking()
4041
val currentThread = Thread.currentThread()
41-
42-
if (blockingChecker?.runBlockingAllowed() == false) {
43-
throw IllegalStateException("runBlocking is forbidden in $currentThread")
44-
}
45-
4642
val contextInterceptor = context[ContinuationInterceptor]
4743
val privateEventLoop = contextInterceptor == null // create private event loop if no dispatcher is specified
4844
val eventLoop = if (privateEventLoop) BlockingEventLoop(currentThread) else contextInterceptor as? EventLoop
@@ -55,32 +51,31 @@ public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, bl
5551
}
5652

5753
/**
58-
* Element of classpath which determines whether invoking [runBlocking] in current thread is allowed.
59-
* [runBlocking] discovers all checkers via [ServiceLoader]
54+
* Extension point which determines whether invoking [runBlocking] in the current thread is allowed.
55+
* [runBlocking] discovers all checkers via [ServiceLoader] and invokes [checkRunBlocking] on
56+
* each attempt to invoke [runBlocking].
6057
*
6158
* Common example is checking whether we're not in UI thread:
59+
*
6260
* ```
63-
* class UiFilter : BlockingFilter {
64-
* fun runBlockingAllowed(): Boolean = !UiFramework.isInUiThread()
61+
* class UiChecker : BlockingChecker {
62+
* fun checkRunBlocking() =
63+
* check(!UiFramework.isInUiThread()) { "runBlocking is not allowed in UI thread" }
6564
* }
6665
* ```
6766
*/
68-
interface BlockingChecker {
69-
67+
public interface BlockingChecker {
7068
/**
71-
* @return whether [runBlocking] calls are allowed in current thread
69+
* Throws [IllegalStateException] if [runBlocking] calls are not allowed in the current thread.
7270
*/
73-
fun runBlockingAllowed(): Boolean
71+
fun checkRunBlocking()
7472
}
7573

7674
// Nullable to enable DCE when no filters are present in classpath
77-
private val blockingChecker: BlockingChecker? = loadBlockingCheckers()
78-
79-
private fun loadBlockingCheckers(): BlockingChecker? {
75+
private val blockingChecker: BlockingChecker? = run {
8076
val filters = ServiceLoader.load(BlockingChecker::class.java).toList().toTypedArray()
81-
if (filters.isEmpty()) return null
82-
return object : BlockingChecker {
83-
override fun runBlockingAllowed(): Boolean = filters.all { it.runBlockingAllowed() }
77+
if (filters.isEmpty()) null else object : BlockingChecker {
78+
override fun checkRunBlocking() = filters.forEach { it.checkRunBlocking() }
8479
}
8580
}
8681

ui/kotlinx-coroutines-android/src/HandlerContext.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
package kotlinx.coroutines.experimental.android
66

77
import android.os.*
8+
import android.support.annotation.*
89
import android.view.*
910
import kotlinx.coroutines.experimental.*
1011
import java.util.concurrent.*
@@ -89,6 +90,11 @@ public class HandlerContext(
8990
override fun hashCode(): Int = System.identityHashCode(handler)
9091
}
9192

93+
/**
94+
* @suppress This is an internal impl class.
95+
*/
96+
@Keep
9297
class MainLooperChecker : BlockingChecker {
93-
override fun runBlockingAllowed(): Boolean = Looper.myLooper() != Looper.getMainLooper()
98+
override fun checkRunBlocking() =
99+
check(Looper.myLooper() != Looper.getMainLooper()) { "runBlocking is not allowed in Android main looper thread" }
94100
}

ui/kotlinx-coroutines-javafx/src/JavaFx.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,8 +77,12 @@ object JavaFx : CoroutineDispatcher(), Delay {
7777
override fun toString() = "JavaFx"
7878
}
7979

80+
/**
81+
* @suppress This is an internal impl class.
82+
*/
8083
class ApplicationThreadChecker : BlockingChecker {
81-
override fun runBlockingAllowed(): Boolean = !Platform.isFxApplicationThread()
84+
override fun checkRunBlocking() =
85+
check(!Platform.isFxApplicationThread()) { "runBlocking is not allowed in JavaFx application thread" }
8286
}
8387

8488
internal fun initPlatform() {

ui/kotlinx-coroutines-swing/src/Swing.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ object Swing : CoroutineDispatcher(), Delay {
4444
override fun toString() = "Swing"
4545
}
4646

47+
/**
48+
* @suppress This is an internal impl class.
49+
*/
4750
class EventDispatchThreadChecker : BlockingChecker {
48-
override fun runBlockingAllowed(): Boolean = !SwingUtilities.isEventDispatchThread()
51+
override fun checkRunBlocking() =
52+
check(!SwingUtilities.isEventDispatchThread()) { "runBlocking is not allowed in Swing event dispatch thread" }
4953
}

0 commit comments

Comments
 (0)