diff options
author | Vsevolod Tolstopyatov <qwwdfsad@gmail.com> | 2020-10-19 03:01:50 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-10-19 13:01:50 +0300 |
commit | 993c1920d17f1072fe17654f9fe553983f58098d (patch) | |
tree | 06f44f06f643342bd717ff57092860ba0b4cb61a /kotlinx-coroutines-core/jvm | |
parent | 20ad25fb3b0a2068677091d808c8b732c8b66662 (diff) | |
download | platform_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.kt | 23 |
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 |