aboutsummaryrefslogtreecommitdiffstats
path: root/kotlinx-coroutines-core/jvm
diff options
context:
space:
mode:
authorVsevolod Tolstopyatov <qwwdfsad@gmail.com>2020-10-19 03:01:50 -0700
committerGitHub <noreply@github.com>2020-10-19 13:01:50 +0300
commit993c1920d17f1072fe17654f9fe553983f58098d (patch)
tree06f44f06f643342bd717ff57092860ba0b4cb61a /kotlinx-coroutines-core/jvm
parent20ad25fb3b0a2068677091d808c8b732c8b66662 (diff)
downloadplatform_external_kotlinx.coroutines-993c1920d17f1072fe17654f9fe553983f58098d.tar.gz
platform_external_kotlinx.coroutines-993c1920d17f1072fe17654f9fe553983f58098d.tar.bz2
platform_external_kotlinx.coroutines-993c1920d17f1072fe17654f9fe553983f58098d.zip
Cleanup lazy coroutines that have been cancelled but not yet garbage … (#2315)
Cleanup lazy coroutines that have been cancelled but not yet garbage collected Fixes #2294
Diffstat (limited to 'kotlinx-coroutines-core/jvm')
-rw-r--r--kotlinx-coroutines-core/jvm/src/debug/internal/DebugProbesImpl.kt23
1 files changed, 22 insertions, 1 deletions
diff --git a/kotlinx-coroutines-core/jvm/src/debug/internal/DebugProbesImpl.kt b/kotlinx-coroutines-core/jvm/src/debug/internal/DebugProbesImpl.kt
index 9dd6c5a5..4b7c09b3 100644
--- a/kotlinx-coroutines-core/jvm/src/debug/internal/DebugProbesImpl.kt
+++ b/kotlinx-coroutines-core/jvm/src/debug/internal/DebugProbesImpl.kt
@@ -156,7 +156,11 @@ internal object DebugProbesImpl {
// Stable ordering of coroutines by their sequence number
.sortedBy { it.info.sequenceNumber }
// Leave in the dump only the coroutines that were not collected while we were dumping them
- .mapNotNull { owner -> owner.info.context?.let { context -> create(owner, context) } }
+ .mapNotNull { owner ->
+ // Fuse map and filter into one operation to save an inline
+ if (owner.isFinished()) null
+ else owner.info.context?.let { context -> create(owner, context) }
+ }
}
/*
@@ -183,10 +187,27 @@ internal object DebugProbesImpl {
dumpCoroutinesSynchronized(out)
}
+ /*
+ * Filters out coroutines that do not call probeCoroutineCompleted,
+ * are completed, but not yet garbage collected.
+ *
+ * Typically, we intercept completion of the coroutine so it invokes "probeCoroutineCompleted",
+ * but it's not the case for lazy coroutines that get cancelled before start.
+ */
+ private fun CoroutineOwner<*>.isFinished(): Boolean {
+ // Guarded by lock
+ val job = info.context?.get(Job) ?: return false
+ if (!job.isCompleted) return false
+ capturedCoroutinesMap.remove(this) // Clean it up by the way
+ return true
+ }
+
private fun dumpCoroutinesSynchronized(out: PrintStream): Unit = coroutineStateLock.write {
check(isInstalled) { "Debug probes are not installed" }
out.print("Coroutines dump ${dateFormat.format(System.currentTimeMillis())}")
capturedCoroutines
+ .asSequence()
+ .filter { !it.isFinished() }
.sortedBy { it.info.sequenceNumber }
.forEach { owner ->
val info = owner.info