File tree Expand file tree Collapse file tree 2 files changed +25
-3
lines changed
kotlinx-coroutines-core/src
main/kotlin/kotlinx/coroutines/experimental/channels
test/kotlin/kotlinx/coroutines/experimental/channels Expand file tree Collapse file tree 2 files changed +25
-3
lines changed Original file line number Diff line number Diff line change @@ -24,7 +24,7 @@ import kotlin.concurrent.withLock
24
24
25
25
/* *
26
26
* Broadcast channel with array buffer of a fixed [capacity].
27
- * Sender suspends only when buffer is fully due to one of the receives not being late and
27
+ * Sender suspends only when buffer is full due to one of the receives being slow to consume and
28
28
* receiver suspends only when buffer is empty.
29
29
*
30
30
* Note, that elements that are sent to the broadcast channel while there are no [open] subscribers are immediately
@@ -128,11 +128,13 @@ class ArrayBroadcastChannel<E>(
128
128
129
129
private fun checkSubOffers () {
130
130
var updated = false
131
+ var hasSubs = false
131
132
@Suppress(" LoopToCallChain" ) // must invoke `checkOffer` on every sub
132
133
for (sub in subs) {
134
+ hasSubs = true
133
135
if (sub.checkOffer()) updated = true
134
136
}
135
- if (updated)
137
+ if (updated || ! hasSubs )
136
138
updateHead()
137
139
}
138
140
Original file line number Diff line number Diff line change @@ -19,7 +19,7 @@ package kotlinx.coroutines.experimental.channels
19
19
import kotlinx.coroutines.experimental.*
20
20
import org.hamcrest.core.IsEqual
21
21
import org.hamcrest.core.IsNull
22
- import org.junit.Assert.*
22
+ import org.junit.Assert.assertThat
23
23
import org.junit.Test
24
24
25
25
class ArrayBroadcastChannelTest : TestBase () {
@@ -112,4 +112,24 @@ class ArrayBroadcastChannelTest : TestBase() {
112
112
assertThat(sub.isClosedForReceive, IsEqual (true ))
113
113
finish(7 )
114
114
}
115
+
116
+ @Test
117
+ fun testForgetUnsubscribed () = runBlocking {
118
+ expect(1 )
119
+ val broadcast = ArrayBroadcastChannel <Int >(1 )
120
+ broadcast.send(1 )
121
+ broadcast.send(2 )
122
+ broadcast.send(3 )
123
+ expect(2 ) // should not suspend anywhere above
124
+ val sub = broadcast.open()
125
+ launch(context, CoroutineStart .UNDISPATCHED ) {
126
+ expect(3 )
127
+ assertThat(sub.receive(), IsEqual (4 )) // suspends
128
+ expect(5 )
129
+ }
130
+ expect(4 )
131
+ broadcast.send(4 ) // sends
132
+ yield ()
133
+ finish(6 )
134
+ }
115
135
}
You can’t perform that action at this time.
0 commit comments