Skip to content

Commit 0cf99bc

Browse files
committed
Explain why non-constant placeholder is required
1 parent 5f2e94b commit 0cf99bc

File tree

1 file changed

+10
-1
lines changed
  • core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/internal

1 file changed

+10
-1
lines changed

core/kotlinx-coroutines-core/src/main/kotlin/kotlinx/coroutines/experimental/internal/LockFreeMPSCQueue.kt

+10-1
Original file line numberDiff line numberDiff line change
@@ -123,8 +123,17 @@ internal class LockFreeMPSCQueueCore<E : Any>(private val capacity: Int) {
123123

124124
private fun fillPlaceholder(index: Int, element: E): Core<E>? {
125125
val old = array.get(index and mask)
126+
/*
127+
* addLast actions:
128+
* 1) Commit tail slot
129+
* 2) Write element to array slot
130+
* 3) Check for array copy
131+
*
132+
* If copy happened between 2 and 3 then the consumer might have consumed our element,
133+
* then another producer might have written its placeholder in our slot, so we should
134+
* perform *unique* check that current placeholder is our to avoid overwriting another producer placeholder
135+
*/
126136
if (old is Placeholder && old.index == index) {
127-
// that is OUR placeholder and only we can fill it in
128137
array.set(index and mask, element)
129138
// we've corrected missing element, should check if that propagated to further copies, just in case
130139
return this

0 commit comments

Comments
 (0)