Skip to content

Commit 39a8854

Browse files
author
Sergey Mashkov
committed
IO: minor performance improvements
1 parent 6e61c23 commit 39a8854

File tree

1 file changed

+15
-11
lines changed

1 file changed

+15
-11
lines changed

core/kotlinx-coroutines-io/src/main/kotlin/kotlinx/coroutines/experimental/io/ByteBufferChannel.kt

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -215,9 +215,7 @@ internal class ByteBufferChannel(
215215
}
216216

217217
private fun setupStateForRead(): ByteBuffer? {
218-
if (readOp != null) throw IllegalStateException("Read operation is already in progress")
219-
220-
val (_, newState) = updateState { state ->
218+
val newState = updateStateAndGet { state ->
221219
when (state) {
222220
ReadWriteBufferState.Terminated -> closed?.cause?.let { throw it } ?: return null
223221
ReadWriteBufferState.IdleEmpty -> closed?.cause?.let { throw it } ?: return null
@@ -236,7 +234,7 @@ internal class ByteBufferChannel(
236234
private fun restoreStateAfterRead() {
237235
var toRelease: ReadWriteBufferState.IdleNonEmpty? = null
238236

239-
val (_, newState) = updateState { state ->
237+
val newState = updateStateAndGet { state ->
240238
toRelease?.let {
241239
it.capacity.resetForWrite()
242240
resumeWriteOp()
@@ -2040,17 +2038,14 @@ internal class ByteBufferChannel(
20402038
}
20412039

20422040
private fun writeSuspendPredicate(size: Int): Boolean {
2043-
if (closed != null) return false
20442041
val joined = joining
20452042
val state = state
20462043
val closed = closed
20472044

2048-
// println("writeSuspend? $joined, $state, ${state.capacity.availableForWrite}, $closed")
2049-
2050-
return if (joined == null) {
2051-
state.capacity.availableForWrite < size && state !== ReadWriteBufferState.IdleEmpty && closed == null
2052-
} else {
2053-
state !== ReadWriteBufferState.Terminated
2045+
return when {
2046+
closed != null -> false
2047+
joined == null -> state.capacity.availableForWrite < size && state !== ReadWriteBufferState.IdleEmpty
2048+
else -> state !== ReadWriteBufferState.Terminated
20542049
}
20552050
}
20562051

@@ -2109,6 +2104,15 @@ internal class ByteBufferChannel(
21092104
pool.recycle(buffer)
21102105
}
21112106

2107+
private inline fun updateStateAndGet(block: (ReadWriteBufferState) -> ReadWriteBufferState?): ReadWriteBufferState {
2108+
val updater = State
2109+
while (true) {
2110+
val old = state
2111+
val newState = block(old) ?: continue
2112+
if (old === newState || updater.compareAndSet(this, old, newState)) return newState
2113+
}
2114+
}
2115+
21122116
// todo: replace with atomicfu
21132117
private inline fun updateState(block: (ReadWriteBufferState) -> ReadWriteBufferState?):
21142118
Pair<ReadWriteBufferState, ReadWriteBufferState> = update({ state }, State, block)

0 commit comments

Comments
 (0)