Skip to content

Commit 8f0e85d

Browse files
authored
Merge pull request #51 from Cysharp/codex/fix-round-robin-overflow
Fix round-robin index overflow
2 parents 05cd67c + 0f28f2e commit 8f0e85d

2 files changed

Lines changed: 22 additions & 1 deletion

File tree

src/LogicLooper/RoundRobinLogicLooperPoolBalancer.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ internal RoundRobinLogicLooperPoolBalancer()
1111

1212
public ILogicLooper GetPooledLooper(ILogicLooper[] pooledLoopers)
1313
{
14-
return pooledLoopers[Interlocked.Increment(ref _index) % pooledLoopers.Length];
14+
var index = unchecked((uint)Interlocked.Increment(ref _index));
15+
return pooledLoopers[(int)(index % (uint)pooledLoopers.Length)];
1516
}
1617
}

test/LogicLooper.Test/RoundRobinLogicLooperPoolBalancerTest.cs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,24 @@ public void GetPooledLooper_ReturnsLoopersInRoundRobinOrder()
1919
Assert.Equal(loopers[2], balancer.GetPooledLooper(loopers));
2020
Assert.Equal(loopers[0], balancer.GetPooledLooper(loopers));
2121
}
22+
23+
[Fact]
24+
public void GetPooledLooper_ReturnsLoopersInRoundRobinOrder_WhenIndexOverflows()
25+
{
26+
var balancer = new RoundRobinLogicLooperPoolBalancer();
27+
var indexField = typeof(RoundRobinLogicLooperPoolBalancer).GetField("_index", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
28+
Assert.NotNull(indexField);
29+
indexField.SetValue(balancer, int.MaxValue - 1);
30+
31+
var loopers = new ILogicLooper[]
32+
{
33+
new ManualLogicLooper(1),
34+
new ManualLogicLooper(2),
35+
new ManualLogicLooper(3)
36+
};
37+
38+
Assert.Equal(loopers[1], balancer.GetPooledLooper(loopers));
39+
Assert.Equal(loopers[2], balancer.GetPooledLooper(loopers));
40+
Assert.Equal(loopers[0], balancer.GetPooledLooper(loopers));
41+
}
2242
}

0 commit comments

Comments
 (0)