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

View File

@ -3,17 +3,37 @@ package cn.tursom.core.buffer.impl
import cn.tursom.core.buffer.ByteBuffer import cn.tursom.core.buffer.ByteBuffer
import cn.tursom.core.buffer.ProxyByteBuffer import cn.tursom.core.buffer.ProxyByteBuffer
import cn.tursom.core.pool.MemoryPool import cn.tursom.core.pool.MemoryPool
import java.util.concurrent.atomic.AtomicInteger
class InstantByteBuffer( class InstantByteBuffer(
override val agent: ByteBuffer, override val agent: ByteBuffer,
val pool: MemoryPool val pool: MemoryPool,
) : ProxyByteBuffer, ByteBuffer by agent { ) : ProxyByteBuffer, ByteBuffer by agent {
override var closed = false override var closed = false
private val childCount = AtomicInteger(0)
override fun close() { override fun close() {
agent.close() if (childCount.get() == 0) {
pool.free(this) agent.close()
closed = true 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)" override fun toString() = "InstantByteBuffer(agent=$agent)"

View File

@ -29,8 +29,15 @@ class PooledByteBuffer(
override val resized get() = agent.resized override val resized get() = agent.resized
override fun close() { override fun close() {
if (tryClose()) { if (tryClose() && childCount.get() == 0) {
if (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() reference?.cancel()
pool.free(this) pool.free(this)
} }