Skip to content

Commit 80a5bc7

Browse files
Restore the removed atomicfu workaround (#4682)
Already introduced once, then reverted in #4663, which led to new issues. * Ensure that inline functions only access atomics from the same class (#4041) Calling a function containing atomic operations from a different file results in the failure of Native incremental compilation. Made BufferedChannel#sendImpl function private. This is a WA for KT-65554 * Update the Kotlin issue numbers to not yet closed ones --------- Co-authored-by: mvicsokolova <82594708+mvicsokolova@users.noreply.github.com>
1 parent 67577ab commit 80a5bc7

2 files changed

Lines changed: 24 additions & 22 deletions

File tree

kotlinx-coroutines-core/common/src/channels/BufferedChannel.kt

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,7 @@ internal open class BufferedChannel<E>(
238238
/**
239239
* Abstract send implementation.
240240
*/
241-
protected inline fun <R> sendImpl(
241+
private inline fun <R> sendImpl(
242242
/* The element to be sent. */
243243
element: E,
244244
/* The waiter to be stored in case of suspension,
@@ -347,6 +347,29 @@ internal open class BufferedChannel<E>(
347347
}
348348
}
349349

350+
// Note: this function is temporarily moved from ConflatedBufferedChannel to BufferedChannel class, because of these issues: KT-81416, KT-86264.
351+
// For now, an inline function, which invokes atomic operations, may only be called within a parent class.
352+
protected fun trySendDropOldest(element: E): ChannelResult<Unit> =
353+
sendImpl( // <-- this is an inline function
354+
element = element,
355+
// Put the element into the logical buffer even
356+
// if this channel is already full, the `onSuspend`
357+
// callback below extract the first (oldest) element.
358+
waiter = BUFFERED,
359+
// Finish successfully when a rendezvous has happened
360+
// or the element has been buffered.
361+
onRendezvousOrBuffered = { return success(Unit) },
362+
// In case the algorithm decided to suspend, the element
363+
// was added to the buffer. However, as the buffer is now
364+
// overflowed, the first (oldest) element has to be extracted.
365+
onSuspend = { segm, i ->
366+
dropFirstElementUntilTheSpecifiedCellIsInTheBuffer(segm.id * SEGMENT_SIZE + i)
367+
return success(Unit)
368+
},
369+
// If the channel is closed, return the corresponding result.
370+
onClosed = { return closed(sendException) }
371+
)
372+
350373
private inline fun sendImplOnNoWaiter(
351374
/* The working cell is specified by
352375
the segment and the index in it. */

kotlinx-coroutines-core/common/src/channels/ConflatedBufferedChannel.kt

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -69,27 +69,6 @@ internal open class ConflatedBufferedChannel<E>(
6969
return success(Unit)
7070
}
7171

72-
private fun trySendDropOldest(element: E): ChannelResult<Unit> =
73-
sendImpl( // <-- this is an inline function
74-
element = element,
75-
// Put the element into the logical buffer even
76-
// if this channel is already full, the `onSuspend`
77-
// callback below extract the first (oldest) element.
78-
waiter = BUFFERED,
79-
// Finish successfully when a rendezvous has happened
80-
// or the element has been buffered.
81-
onRendezvousOrBuffered = { return success(Unit) },
82-
// In case the algorithm decided to suspend, the element
83-
// was added to the buffer. However, as the buffer is now
84-
// overflowed, the first (oldest) element has to be extracted.
85-
onSuspend = { segm, i ->
86-
dropFirstElementUntilTheSpecifiedCellIsInTheBuffer(segm.id * SEGMENT_SIZE + i)
87-
return success(Unit)
88-
},
89-
// If the channel is closed, return the corresponding result.
90-
onClosed = { return closed(sendException) }
91-
)
92-
9372
@Suppress("UNCHECKED_CAST")
9473
override fun registerSelectForSend(select: SelectInstance<*>, element: Any?) {
9574
// The plain `send(..)` operation never suspends. Thus, either this

0 commit comments

Comments
 (0)