From 47b598e6ce6c1f0e57d6955d10652dd5e5bc1462 Mon Sep 17 00:00:00 2001 From: buchgr Date: Sun, 13 Mar 2016 22:27:56 +0100 Subject: [PATCH] Fix race in PoolArena.allocate. Fixes #4829 Motivation: The statistic counters PoolArena.(allocationsTiny|allocationsSmall) are not protected by a per arena lock, but by a per size class lock. Thus, two concurrent allocations of different size (class) could lead to a race and ultimately to wrong statistics. Modifications: Use a thread-safe LongCounter instead of a plain long data type. Result: Fewer data races. --- .../src/main/java/io/netty/buffer/PoolArena.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/buffer/src/main/java/io/netty/buffer/PoolArena.java b/buffer/src/main/java/io/netty/buffer/PoolArena.java index 4cb6af2b6a..33445241b7 100644 --- a/buffer/src/main/java/io/netty/buffer/PoolArena.java +++ b/buffer/src/main/java/io/netty/buffer/PoolArena.java @@ -57,8 +57,8 @@ abstract class PoolArena implements PoolArenaMetric { private final List chunkListMetrics; // Metrics for allocations and deallocations - private long allocationsTiny; - private long allocationsSmall; + private LongCounter allocationsTiny = PlatformDependent.newLongCounter(); + private LongCounter allocationsSmall = PlatformDependent.newLongCounter(); private long allocationsNormal; // We need to use the LongCounter here as this is not guarded via synchronized block. private final LongCounter allocationsHuge = PlatformDependent.newLongCounter(); @@ -195,9 +195,9 @@ abstract class PoolArena implements PoolArenaMetric { s.chunk.initBufWithSubpage(buf, handle, reqCapacity); if (tiny) { - ++allocationsTiny; + allocationsTiny.increment(); } else { - ++allocationsSmall; + allocationsSmall.increment(); } return; } @@ -432,17 +432,17 @@ abstract class PoolArena implements PoolArenaMetric { @Override public long numAllocations() { - return allocationsTiny + allocationsSmall + allocationsNormal + allocationsHuge.value(); + return allocationsTiny.value() + allocationsSmall.value() + allocationsNormal + allocationsHuge.value(); } @Override public long numTinyAllocations() { - return allocationsTiny; + return allocationsTiny.value(); } @Override public long numSmallAllocations() { - return allocationsSmall; + return allocationsSmall.value(); } @Override