@@ -119,12 +119,18 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
119
119
return null
120
120
}
121
121
122
- /* *
123
- * @suppress **This is unstable API and it is subject to change.**
124
- */
125
122
protected fun conflatePreviousSendBuffered (node : LockFreeLinkedListNode ) {
126
- val prev = node.prevNode
127
- (prev as ? SendBuffered <* >)?.remove()
123
+ /*
124
+ * Conflate all previous SendBuffered,
125
+ * helping other sends to coflate
126
+ */
127
+ var prev = node.prevNode
128
+ while (prev is SendBuffered <* >) {
129
+ if (! prev.remove()) {
130
+ prev.helpRemove()
131
+ }
132
+ prev = prev.prevNode
133
+ }
128
134
}
129
135
130
136
/* *
@@ -249,15 +255,15 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
249
255
*/
250
256
val closeAdded = queue.addLastIfPrev(closed, { it !is Closed <* > })
251
257
if (! closeAdded) {
252
- helpClose(queue.prevNode as Closed <* >)
258
+ val actualClosed = queue.prevNode as Closed <* >
259
+ helpClose(actualClosed)
260
+ onClosedIdempotent(actualClosed)
253
261
return false
254
262
}
255
263
256
264
helpClose(closed)
257
265
invokeOnCloseHandler(cause)
258
- // TODO We can get rid of afterClose
259
- onClosed(closed)
260
- afterClose(cause)
266
+ onClosedIdempotent(closed)
261
267
return true
262
268
}
263
269
@@ -322,15 +328,10 @@ internal abstract class AbstractSendChannel<E> : SendChannel<E> {
322
328
}
323
329
324
330
/* *
325
- * Invoked when [Closed] element was just added.
326
- * @suppress **This is unstable API and it is subject to change.**
327
- */
328
- protected open fun onClosed (closed : Closed <E >) {}
329
-
330
- /* *
331
- * Invoked after successful [close].
331
+ * Invoked when channel is closed as the last action of [close] invocation.
332
+ * This method should be idempotent and can be called multiple times.
332
333
*/
333
- protected open fun afterClose ( cause : Throwable ? ) {}
334
+ protected open fun onClosedIdempotent ( closed : LockFreeLinkedListNode ) {}
334
335
335
336
/* *
336
337
* Retrieves first receiving waiter from the queue or returns closed token.
0 commit comments