Guard against calling PoolThreadCache.free() multiple times. (#8108)
Motivation:
5b1fe611a6
introduced the usage of a finalizer as last resort for PoolThreadCache. As we may call free() from the FastThreadLocal.onRemoval(...) and finalize() we need to guard against multiple calls as otherwise we will corrupt internal state (that is used for metrics).
Modifications:
Use AtomicBoolean to guard against multiple calls of PoolThreadCache.free().
Result:
No more corruption of internal state caused by calling PoolThreadCache.free() multuple times.
This commit is contained in:
parent
0920738932
commit
6afab517b0
@ -27,6 +27,7 @@ import io.netty.util.internal.logging.InternalLoggerFactory;
|
||||
|
||||
import java.nio.ByteBuffer;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
|
||||
/**
|
||||
* Acts a Thread cache for allocations. This implementation is moduled after
|
||||
@ -54,6 +55,7 @@ final class PoolThreadCache {
|
||||
private final int numShiftsNormalDirect;
|
||||
private final int numShiftsNormalHeap;
|
||||
private final int freeSweepAllocationThreshold;
|
||||
private final AtomicBoolean freed = new AtomicBoolean();
|
||||
|
||||
private int allocations;
|
||||
|
||||
@ -233,23 +235,28 @@ final class PoolThreadCache {
|
||||
* Should be called if the Thread that uses this cache is about to exist to release resources out of the cache
|
||||
*/
|
||||
void free() {
|
||||
int numFreed = free(tinySubPageDirectCaches) +
|
||||
free(smallSubPageDirectCaches) +
|
||||
free(normalDirectCaches) +
|
||||
free(tinySubPageHeapCaches) +
|
||||
free(smallSubPageHeapCaches) +
|
||||
free(normalHeapCaches);
|
||||
// As free() may be called either by the finalizer or by FastThreadLocal.onRemoval(...) we need to ensure
|
||||
// we only call this one time.
|
||||
if (freed.compareAndSet(false, true)) {
|
||||
int numFreed = free(tinySubPageDirectCaches) +
|
||||
free(smallSubPageDirectCaches) +
|
||||
free(normalDirectCaches) +
|
||||
free(tinySubPageHeapCaches) +
|
||||
free(smallSubPageHeapCaches) +
|
||||
free(normalHeapCaches);
|
||||
|
||||
if (numFreed > 0 && logger.isDebugEnabled()) {
|
||||
logger.debug("Freed {} thread-local buffer(s) from thread: {}", numFreed, Thread.currentThread().getName());
|
||||
}
|
||||
if (numFreed > 0 && logger.isDebugEnabled()) {
|
||||
logger.debug("Freed {} thread-local buffer(s) from thread: {}", numFreed,
|
||||
Thread.currentThread().getName());
|
||||
}
|
||||
|
||||
if (directArena != null) {
|
||||
directArena.numThreadCaches.getAndDecrement();
|
||||
}
|
||||
if (directArena != null) {
|
||||
directArena.numThreadCaches.getAndDecrement();
|
||||
}
|
||||
|
||||
if (heapArena != null) {
|
||||
heapArena.numThreadCaches.getAndDecrement();
|
||||
if (heapArena != null) {
|
||||
heapArena.numThreadCaches.getAndDecrement();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user