@@ -107,8 +107,8 @@ internal class ByteBufferChannel(
107
107
}
108
108
109
109
if (cause != null ) attachedJob?.cancel(cause)
110
- readSuspendContinuationCache.close()
111
- writeSuspendContinuationCache.close()
110
+ // readSuspendContinuationCache.close()
111
+ // writeSuspendContinuationCache.close()
112
112
113
113
return true
114
114
}
@@ -155,8 +155,8 @@ internal class ByteBufferChannel(
155
155
}
156
156
157
157
private fun setupStateForWrite (): ByteBuffer ? {
158
- if ( writeOp != null ) {
159
- throw IllegalStateException (" Write operation is already in progress" )
158
+ writeOp?. let { existing ->
159
+ throw IllegalStateException (" Write operation is already in progress: $existing " )
160
160
}
161
161
162
162
var _allocated : ReadWriteBufferState .Initial ? = null
@@ -183,7 +183,6 @@ internal class ByteBufferChannel(
183
183
}
184
184
}
185
185
186
- // joining?.let { restoreStateAfterWrite(); return null }
187
186
if (closed != null ) {
188
187
restoreStateAfterWrite()
189
188
tryTerminate()
@@ -348,12 +347,16 @@ internal class ByteBufferChannel(
348
347
val current = joining?.let { resolveDelegation(this , it) } ? : this
349
348
val buffer = current.setupStateForWrite() ? : return
350
349
val capacity = current.state.capacity
350
+ val before = current.totalBytesWritten
351
351
352
352
try {
353
353
current.closed?.let { throw it.sendException }
354
354
block(current, buffer, capacity)
355
355
} finally {
356
356
if (capacity.isFull() || current.autoFlush) current.flush()
357
+ if (current != = this ) {
358
+ totalBytesWritten + = current.totalBytesWritten - before
359
+ }
357
360
current.restoreStateAfterWrite()
358
361
current.tryTerminate()
359
362
}
@@ -692,7 +695,7 @@ internal class ByteBufferChannel(
692
695
return readShort()
693
696
}
694
697
695
- final suspend override fun readInt (): Int {
698
+ final override suspend fun readInt (): Int {
696
699
var i = 0
697
700
698
701
val rc = reading {
@@ -716,7 +719,7 @@ internal class ByteBufferChannel(
716
719
return readInt()
717
720
}
718
721
719
- final suspend override fun readLong (): Long {
722
+ final override suspend fun readLong (): Long {
720
723
var i = 0L
721
724
722
725
val rc = reading {
@@ -740,7 +743,7 @@ internal class ByteBufferChannel(
740
743
return readLong()
741
744
}
742
745
743
- final suspend override fun readDouble (): Double {
746
+ final override suspend fun readDouble (): Double {
744
747
var d = 0.0
745
748
746
749
val rc = reading {
@@ -764,7 +767,7 @@ internal class ByteBufferChannel(
764
767
return readDouble()
765
768
}
766
769
767
- final suspend override fun readFloat (): Float {
770
+ final override suspend fun readFloat (): Float {
768
771
var f = 0.0f
769
772
770
773
val rc = reading {
@@ -1182,7 +1185,6 @@ internal class ByteBufferChannel(
1182
1185
}
1183
1186
1184
1187
internal suspend fun copyDirect (src : ByteBufferChannel , limit : Long , joined : JoiningState ? ): Long {
1185
- // println("enter copyDirect")
1186
1188
if (limit == 0L ) return 0L
1187
1189
if (src.isClosedForRead) {
1188
1190
if (joined != null ) {
@@ -1234,13 +1236,11 @@ internal class ByteBufferChannel(
1234
1236
true
1235
1237
}
1236
1238
1237
- // println("rc = $rc, partSize = $partSize")
1238
1239
if (rc) {
1239
1240
dstBuffer.bytesWritten(state, partSize)
1240
1241
copied + = partSize
1241
1242
1242
1243
if (avWBefore - partSize == 0 || autoFlush) {
1243
- // println("flush")
1244
1244
flush()
1245
1245
}
1246
1246
} else {
@@ -1257,30 +1257,23 @@ internal class ByteBufferChannel(
1257
1257
}
1258
1258
}
1259
1259
1260
- if (joining != null ) break // TODO think of joining chain
1261
1260
if (copied >= limit) break
1262
1261
1263
- // println("readSuspend?")
1264
1262
flush()
1265
1263
1266
1264
if (src.availableForRead == 0 && ! src.readSuspendImpl(1 )) {
1267
- // println("readSuspend failed")
1268
1265
if (joined == null || src.tryCompleteJoining(joined)) break
1269
1266
}
1270
- // println("next loop")
1267
+
1268
+ if (joining != null ) {
1269
+ yield ()
1270
+ }
1271
1271
}
1272
1272
1273
1273
if (autoFlush) {
1274
- // println("final flush")
1275
1274
flush()
1276
1275
}
1277
1276
1278
- if (joined == null ) {
1279
- joining?.let { thisJoined ->
1280
- return copied + thisJoined.delegatedTo.copyDirect(src, limit - copied, null )
1281
- }
1282
- }
1283
-
1284
1277
return copied
1285
1278
} catch (t: Throwable ) {
1286
1279
close(t)
@@ -1293,7 +1286,17 @@ internal class ByteBufferChannel(
1293
1286
this .joining = null
1294
1287
1295
1288
if (joined.delegateClose) {
1296
- joined.delegatedTo.close(closed.cause)
1289
+ // writing state could be if we are inside of copyDirect loop
1290
+ // so in this case we shouldn't close channel
1291
+ // otherwise few bytes could be lost
1292
+ // it will be closed later in copyDirect's finalization
1293
+ // so we only do flush
1294
+ val writing = joined.delegatedTo.state.let { it is ReadWriteBufferState .Writing || it is ReadWriteBufferState .ReadingWriting }
1295
+ if (closed.cause != null || ! writing) {
1296
+ joined.delegatedTo.close(closed.cause)
1297
+ } else {
1298
+ joined.delegatedTo.flush()
1299
+ }
1297
1300
} else {
1298
1301
joined.delegatedTo.flush()
1299
1302
}
0 commit comments