Skip to content

Commit 1004f39

Browse files
authored
Use DirectExecutor for Task.addOnCompleteListener (#2992)
Fixes #2990
1 parent 4c6aa54 commit 1004f39

File tree

1 file changed

+17
-3
lines changed
  • integration/kotlinx-coroutines-play-services/src

1 file changed

+17
-3
lines changed

integration/kotlinx-coroutines-play-services/src/Tasks.kt

+17-3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ package kotlinx.coroutines.tasks
88

99
import com.google.android.gms.tasks.*
1010
import kotlinx.coroutines.*
11+
import java.lang.Runnable
12+
import java.util.concurrent.Executor
1113
import kotlin.coroutines.*
1214

1315
/**
@@ -71,7 +73,8 @@ private fun <T> Task<T>.asDeferredImpl(cancellationTokenSource: CancellationToke
7173
deferred.completeExceptionally(e)
7274
}
7375
} else {
74-
addOnCompleteListener {
76+
// Run the callback directly to avoid unnecessarily scheduling on the main thread.
77+
addOnCompleteListener(DirectExecutor) {
7578
val e = it.exception
7679
if (e == null) {
7780
@Suppress("UNCHECKED_CAST")
@@ -114,7 +117,8 @@ public suspend fun <T> Task<T>.await(): T = awaitImpl(null)
114117
* leads to an unspecified behaviour.
115118
*/
116119
@ExperimentalCoroutinesApi // Since 1.5.1, tentatively until 1.6.0
117-
public suspend fun <T> Task<T>.await(cancellationTokenSource: CancellationTokenSource): T = awaitImpl(cancellationTokenSource)
120+
public suspend fun <T> Task<T>.await(cancellationTokenSource: CancellationTokenSource): T =
121+
awaitImpl(cancellationTokenSource)
118122

119123
private suspend fun <T> Task<T>.awaitImpl(cancellationTokenSource: CancellationTokenSource?): T {
120124
// fast path
@@ -133,7 +137,8 @@ private suspend fun <T> Task<T>.awaitImpl(cancellationTokenSource: CancellationT
133137
}
134138

135139
return suspendCancellableCoroutine { cont ->
136-
addOnCompleteListener {
140+
// Run the callback directly to avoid unnecessarily scheduling on the main thread.
141+
addOnCompleteListener(DirectExecutor) {
137142
val e = it.exception
138143
if (e == null) {
139144
@Suppress("UNCHECKED_CAST")
@@ -150,3 +155,12 @@ private suspend fun <T> Task<T>.awaitImpl(cancellationTokenSource: CancellationT
150155
}
151156
}
152157
}
158+
159+
/**
160+
* An [Executor] that just directly executes the [Runnable].
161+
*/
162+
private object DirectExecutor : Executor {
163+
override fun execute(r: Runnable) {
164+
r.run()
165+
}
166+
}

0 commit comments

Comments
 (0)