File tree 2 files changed +26
-5
lines changed
kotlinx-coroutines-core/jvm/src
2 files changed +26
-5
lines changed Original file line number Diff line number Diff line change @@ -117,12 +117,13 @@ private class DispatcherExecutor(@JvmField val dispatcher: CoroutineDispatcher)
117
117
118
118
internal class ExecutorCoroutineDispatcherImpl (override val executor : Executor ) : ExecutorCoroutineDispatcher(), Delay {
119
119
120
+ /*
121
+ * Attempts to reflectively (to be Java 6 compatible) invoke
122
+ * ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy in order to cleanup
123
+ * internal scheduler queue on cancellation.
124
+ */
120
125
init {
121
- /* Attempt to invoke ScheduledThreadPoolExecutor.setRemoveOnCancelPolicy in order to clean up
122
- * the internal scheduler queue on cancellation. */
123
- if (executor is ScheduledThreadPoolExecutor ) {
124
- executor.removeOnCancelPolicy = true
125
- }
126
+ removeFutureOnCancel(executor)
126
127
}
127
128
128
129
override fun dispatch (context : CoroutineContext , block : Runnable ) {
Original file line number Diff line number Diff line change 1
1
package kotlinx.coroutines.internal
2
2
3
+ import java.lang.reflect.Method
3
4
import java.util.*
5
+ import java.util.concurrent.Executor
6
+ import java.util.concurrent.ScheduledThreadPoolExecutor
4
7
import kotlin.concurrent.withLock as withLockJvm
5
8
6
9
internal actual typealias ReentrantLock = java.util.concurrent.locks.ReentrantLock
@@ -18,3 +21,20 @@ internal actual annotation class BenignDataRace()
18
21
@Suppress(" NOTHING_TO_INLINE" ) // So that R8 can completely remove ConcurrentKt class
19
22
internal actual inline fun <E > identitySet (expectedSize : Int ): MutableSet <E > =
20
23
Collections .newSetFromMap(IdentityHashMap (expectedSize))
24
+
25
+ private val REMOVE_FUTURE_ON_CANCEL : Method ? = try {
26
+ ScheduledThreadPoolExecutor ::class .java.getMethod(" setRemoveOnCancelPolicy" , Boolean ::class .java)
27
+ } catch (_: Throwable ) {
28
+ null
29
+ }
30
+
31
+ @Suppress(" NAME_SHADOWING" )
32
+ internal fun removeFutureOnCancel (executor : Executor ): Boolean {
33
+ try {
34
+ val executor = executor as ? ScheduledThreadPoolExecutor ? : return false
35
+ (REMOVE_FUTURE_ON_CANCEL ? : return false ).invoke(executor, true )
36
+ return true
37
+ } catch (_: Throwable ) {
38
+ return false // failed to setRemoveOnCancelPolicy, assume it does not remove the future on cancel
39
+ }
40
+ }
You can’t perform that action at this time.
0 commit comments