是什么阻止DOMTimerCoordinator::NextID进入无休止的循环

What does prevent DOMTimerCoordinator::NextID from entering a endless loop?

本文关键字:无休止 循环 NextID DOMTimerCoordinator 是什么      更新时间:2023-10-16

我查看了Blink代码库,以回答关于JavaScript中定时器的最大可能数量的问题。

DOMTimerCoordinator::InstallNewTimeout()创建了新的定时器。它调用NextID()来检索可用的整数密钥。然后,它将新的定时器和相应的密钥插入到timers_中。

int timeout_id = NextID();
timers_.insert(timeout_id, DOMTimer::Create(context, action, timeout,
single_shot, timeout_id));

NextID()在从1到231-1:的循环序列中获得下一个id

int DOMTimerCoordinator::NextID() {
while (true) {
++circular_sequential_id_;
if (circular_sequential_id_ <= 0)
circular_sequential_id_ = 1;
if (!timers_.Contains(circular_sequential_id_))
return circular_sequential_id_;
}
}

如果所有ID都在使用,会发生什么
是什么阻止NextID()进入无休止的循环?

我在回答这个问题时对整个过程作了更详细的解释。

我需要一点理解,但我相信我做到了。

这些步骤让我明白了这一点

  1. circular_sequential_id_被用作唯一标识符。它没有公开,但从其他信息来看,我怀疑它是一个32位的int(例如std::int32_t(。

  2. 我怀疑circular_sequential_id_class(或struct(DOMTimerCoordinator的成员变量。因此,在NextID()的每次调用之后;记得";最后返回的值。当输入NextID()时,circular_sequential_id_首先递增:

    ++circular_sequential_id_;
  3. ++circular_sequential_id_;的增量迟早会导致溢出(Uuuh。如果我没记错的话,这被认为是未定义的行为,但在现实世界中,它大多只是循环。(并变为负值。为了处理这个问题,下一行适合:

    if (circular_sequential_id_ <= 0)
    circular_sequential_id_ = 1;
  4. 循环中的最后一条语句检查生成的ID是否仍在任何计时器中使用:

    if (!timers_.Contains(circular_sequential_id_))
    return circular_sequential_id_;

    如果未使用,则返回ID。否则,“再玩一遍,山姆。";

这给我带来了最合理的答案:

是的,这可能会成为一个无休止的循环。。。

如果231-1个定时器已被占用,因此,所有ID都已被消耗。

  1. 我认为对于231-1定时器,你会遇到更重要的其他问题。(单独对这些计时器可能需要的存储以及处理所有这些计时器的时间进行成像…(

  2. 即使231-1计时器不是致命的问题,该功能也可能会继续循环,直到其中一个计时器释放其ID,它可以再次被占用。因此,如果资源(计时器的空闲ID(暂时不可用,NextID()将被阻塞。

三思而后行。这种选择是相当理论化的。我不敢相信有人会以这种方式管理有限的资源。

我想,这段代码是在这样的假设下工作的,即永远不会有231-1个定时器同时存在,因此它将通过几次迭代找到一个免费的ID。