Merge pull request #15 from netty/fix-drop-gate

Fix drop race with Cleaner
This commit is contained in:
Chris Vest 2020-12-07 17:56:02 +01:00 committed by GitHub
commit e8a38185bb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 9 additions and 5 deletions

View File

@ -61,9 +61,9 @@ class NativeMemoryCleanerDrop implements Drop<Buf> {
var mem = manager.unwrapRecoverableMemory(buf); var mem = manager.unwrapRecoverableMemory(buf);
var delegate = this.delegate; var delegate = this.delegate;
WeakReference<Buf> ref = new WeakReference<>(buf); WeakReference<Buf> ref = new WeakReference<>(buf);
AtomicBoolean gate = new AtomicBoolean(); AtomicBoolean gate = new AtomicBoolean(true);
cleanable = new GatedCleanable(gate, CLEANER.register(this, () -> { cleanable = new GatedCleanable(gate, CLEANER.register(this, () -> {
if (gate.compareAndSet(false, true)) { if (gate.getAndSet(false)) {
Buf b = ref.get(); Buf b = ref.get();
if (b == null) { if (b == null) {
pool.recoverMemory(mem); pool.recoverMemory(mem);
@ -84,7 +84,7 @@ class NativeMemoryCleanerDrop implements Drop<Buf> {
} }
public void disable() { public void disable() {
gate.set(true); gate.set(false);
} }
@Override @Override

View File

@ -70,7 +70,7 @@ class SizeClassedMemoryPool implements Allocator, AllocatorControl, Drop<Buf> {
Send<Buf> send; Send<Buf> send;
while ((send = v.poll()) != null) { while ((send = v.poll()) != null) {
try { try {
dispose(send.receive()); send.receive().close();
} catch (Exception e) { } catch (Exception e) {
capturedExceptions.add(e); capturedExceptions.add(e);
} }
@ -86,12 +86,16 @@ class SizeClassedMemoryPool implements Allocator, AllocatorControl, Drop<Buf> {
@Override @Override
public void drop(Buf buf) { public void drop(Buf buf) {
if (closed) {
dispose(buf);
return;
}
var sizeClassPool = getSizeClassPool(buf.capacity()); var sizeClassPool = getSizeClassPool(buf.capacity());
sizeClassPool.offer(buf.send()); sizeClassPool.offer(buf.send());
if (closed) { if (closed) {
Send<Buf> send; Send<Buf> send;
while ((send = sizeClassPool.poll()) != null) { while ((send = sizeClassPool.poll()) != null) {
dispose(send.receive()); send.receive().close();
} }
} }
} }