Skip to content

Commit b4544bb

Browse files
Stop RCTIdentifierPool::dequeue from spinning forever when the pool is full
dequeue() scanned for a free identifier in an unbounded loop. Once every identifier was taken, which happens when the touch handlers leak them over a long-lived process, the loop never exited and hung the main thread. Bound the scan to one pass over the pool. If no identifier is free, reclaim them all and reuse one. Also initialise lastIndex, which was read before being assigned. Fixes #58441 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent be5235d commit b4544bb

1 file changed

Lines changed: 9 additions & 2 deletions

File tree

‎packages/react-native/React/Fabric/Utils/RCTIdentifierPool.h‎

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,20 @@ class RCTIdentifierPool {
2121

2222
int dequeue()
2323
{
24-
while (true) {
24+
for (size_t attempt = 0; attempt < size; attempt++) {
2525
if (!usage[lastIndex]) {
2626
usage[lastIndex] = true;
2727
return lastIndex;
2828
}
2929
lastIndex = (lastIndex + 1) % size;
3030
}
31+
32+
// Every identifier is taken, which only happens when identifiers were leaked.
33+
// Reclaim them all instead of scanning forever: a reused identifier is a
34+
// transient glitch, while an endless loop here hangs the main thread.
35+
usage.reset();
36+
usage[lastIndex] = true;
37+
return lastIndex;
3138
}
3239

3340
void reset()
@@ -39,7 +46,7 @@ class RCTIdentifierPool {
3946

4047
private:
4148
std::bitset<size> usage;
42-
int lastIndex;
49+
int lastIndex{0};
4350
};
4451

4552
} // namespace facebook::react

0 commit comments

Comments
 (0)