fix SplitByteBuffer close bug

This commit is contained in:
tursom 2021-07-16 13:29:56 +08:00
parent e683712c4f
commit cc3ea3c0a5
4 changed files with 41 additions and 12 deletions

View File

@ -58,6 +58,7 @@ interface ByteBuffer : Closeable {
val resized: Boolean
override fun close() {}
fun closeChild(child: ByteBuffer) {}
fun readBuffer(): java.nio.ByteBuffer
fun finishRead(buffer: java.nio.ByteBuffer) {

View File

@ -6,9 +6,9 @@ import java.util.concurrent.atomic.AtomicBoolean
import java.util.concurrent.atomic.AtomicInteger
class SplitByteBuffer(
private val parent: ByteBuffer,
val parent: ByteBuffer,
private val childCount: AtomicInteger,
override val agent: ByteBuffer
override val agent: ByteBuffer,
) : ProxyByteBuffer, ByteBuffer by agent {
init {
childCount.incrementAndGet()
@ -21,10 +21,7 @@ class SplitByteBuffer(
override fun close() {
if (atomicClosed.compareAndSet(false, true)) {
agent.close()
childCount.decrementAndGet()
if (childCount.get() == 0 && (parent.closed || parent.resized)) {
parent.close()
}
parent.closeChild(this)
}
}
@ -43,4 +40,8 @@ class SplitByteBuffer(
protected fun finalize() {
close()
}
override fun toString(): String {
return "SplitByteBuffer(parent=$parent, childCount=$childCount, agent=$agent)"
}
}

View File

@ -3,18 +3,38 @@ package cn.tursom.core.buffer.impl
import cn.tursom.core.buffer.ByteBuffer
import cn.tursom.core.buffer.ProxyByteBuffer
import cn.tursom.core.pool.MemoryPool
import java.util.concurrent.atomic.AtomicInteger
class InstantByteBuffer(
override val agent: ByteBuffer,
val pool: MemoryPool
val pool: MemoryPool,
) : ProxyByteBuffer, ByteBuffer by agent {
override var closed = false
private val childCount = AtomicInteger(0)
override fun close() {
if (childCount.get() == 0) {
agent.close()
pool.free(this)
closed = true
}
}
override fun closeChild(child: ByteBuffer) {
if (child is SplitByteBuffer && child.parent == this && childCount.decrementAndGet() == 0) {
if (closed) {
close()
}
}
}
override fun slice(position: Int, size: Int): ByteBuffer {
return SplitByteBuffer(this, childCount, agent.slice(position, size))
}
override fun slice(position: Int, size: Int, readPosition: Int, writePosition: Int): ByteBuffer {
return SplitByteBuffer(this, childCount, agent.slice(position, size, readPosition, writePosition))
}
override fun toString() = "InstantByteBuffer(agent=$agent)"
}

View File

@ -29,8 +29,15 @@ class PooledByteBuffer(
override val resized get() = agent.resized
override fun close() {
if (tryClose()) {
if (childCount.get() == 0) {
if (tryClose() && childCount.get() == 0) {
reference?.cancel()
pool.free(this)
}
}
override fun closeChild(child: ByteBuffer) {
if (child is SplitByteBuffer && child.parent == this && childCount.decrementAndGet() == 0) {
if (closed) {
reference?.cancel()
pool.free(this)
}