Debug toString for channels
Fixes #185
diff --git a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/AbstractChannel.kt b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/AbstractChannel.kt
index 16862d1..a42517a 100644
--- a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/AbstractChannel.kt
+++ b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/AbstractChannel.kt
@@ -16,17 +16,11 @@
package kotlinx.coroutines.experimental.channels
-import kotlinx.coroutines.experimental.CancellableContinuation
-import kotlinx.coroutines.experimental.DisposableHandle
+import kotlinx.coroutines.experimental.*
import kotlinx.coroutines.experimental.internal.*
-import kotlinx.coroutines.experimental.intrinsics.startCoroutineUndispatched
-import kotlinx.coroutines.experimental.removeOnCancel
-import kotlinx.coroutines.experimental.selects.ALREADY_SELECTED
-import kotlinx.coroutines.experimental.selects.SelectClause1
-import kotlinx.coroutines.experimental.selects.SelectClause2
-import kotlinx.coroutines.experimental.selects.SelectInstance
-import kotlinx.coroutines.experimental.suspendAtomicCancellableCoroutine
-import kotlin.coroutines.experimental.startCoroutine
+import kotlinx.coroutines.experimental.intrinsics.*
+import kotlinx.coroutines.experimental.selects.*
+import kotlin.coroutines.experimental.*
/**
* Abstract send channel. It is a base class for all send channel implementations.
@@ -374,6 +368,37 @@
}
}
+ // ------ debug ------
+
+ public override fun toString() =
+ "$classSimpleName@$hexAddress{$queueDebugStateString}$bufferDebugString"
+
+ private val queueDebugStateString: String
+ get() {
+ val head = queue.next
+ if (head === queue) return "EmptyQueue"
+ var result = when (head) {
+ is Closed<*> -> head.toString()
+ is Receive<*> -> "ReceiveQueued"
+ is Send -> "SendQueued"
+ else -> "UNEXPECTED:$head" // should not happen
+ }
+ val tail = queue.prev
+ if (tail !== head) {
+ result += ",queueSize=${countQueueSize()}"
+ if (tail is Closed<*>) result += ",closedForSend=$tail"
+ }
+ return result
+ }
+
+ private fun countQueueSize(): Int {
+ var size = 0
+ queue.forEach<LockFreeLinkedListNode> { size++ }
+ return size
+ }
+
+ protected open val bufferDebugString: String get() = ""
+
// ------ private ------
private class SendSelect<E, R>(
diff --git a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayBroadcastChannel.kt b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayBroadcastChannel.kt
index e11237f..5c4fa55 100644
--- a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayBroadcastChannel.kt
+++ b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayBroadcastChannel.kt
@@ -16,11 +16,10 @@
package kotlinx.coroutines.experimental.channels
-import kotlinx.coroutines.experimental.selects.ALREADY_SELECTED
-import kotlinx.coroutines.experimental.selects.SelectInstance
-import java.util.concurrent.CopyOnWriteArrayList
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.concurrent.withLock
+import kotlinx.coroutines.experimental.selects.*
+import java.util.concurrent.*
+import java.util.concurrent.locks.*
+import kotlin.concurrent.*
/**
* Broadcast channel with array buffer of a fixed [capacity].
@@ -353,4 +352,9 @@
return result
}
}
+
+ // ------ debug ------
+
+ override val bufferDebugString: String
+ get() = "(buffer:capacity=${buffer.size},size=$size)"
}
\ No newline at end of file
diff --git a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayChannel.kt b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayChannel.kt
index 8ce9008..fd8c79d 100644
--- a/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayChannel.kt
+++ b/core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/channels/ArrayChannel.kt
@@ -16,10 +16,9 @@
package kotlinx.coroutines.experimental.channels
-import kotlinx.coroutines.experimental.selects.ALREADY_SELECTED
-import kotlinx.coroutines.experimental.selects.SelectInstance
-import java.util.concurrent.locks.ReentrantLock
-import kotlin.concurrent.withLock
+import kotlinx.coroutines.experimental.selects.*
+import java.util.concurrent.locks.*
+import kotlin.concurrent.*
/**
* Channel with array buffer of a fixed [capacity].
@@ -245,4 +244,9 @@
// then clean all queued senders
super.cleanupSendQueueOnCancel()
}
+
+ // ------ debug ------
+
+ override val bufferDebugString: String
+ get() = "(buffer:capacity=${buffer.size},size=$size)"
}
\ No newline at end of file