定时器是参考linux内核定时器设计实现的. 遇到了两个比较致命而且比较隐蔽的bug.
用了各种方法debug, 看来是确实是代码写挫了.
bug1:
在后一个时间轮子向前一个时间轮子迁移定时器时步骤:
1. 移除后一个时间轮子头指针指向的双向链表表头的定时器.
2. 重新插入该定时器.
3. 重复1, 2直到该双向链表为空.
问题: 移除的定时器可能会重新插入到当前的双向链表, 出现这情况就会导致死循环.
改进: 先把移除的定时器保存起来, 在移除完后再一次性插入.
bug2:
根据bug1修改后迁移定时器时步骤:
1. 移除后一个时间轮子首指针指向的双向链表表头的定时器.
2. 把该定时器放到缓存里.
3. 重复1, 2直到该双向链表为空.
4. 插入缓存里的定时器.
5. 后一个时间轮子头指针顺时针移一格, 如果头指针回到了起始位置, 则继续和下一个轮子重复以上动作.
问题: 当缓存里的定时器是在原来头指针指向的格子时, 而恰好还没到时间迁移到前一个轮子,这时这定时器会重新插到头指针指向的格子(这就是导致bug1发生的情况), 看起来是没什么问题,不过下一步头指针移动后, 该定时器就相当于延长了一个轮子的时间, 只能等到下一次头指针重新移到该格子上时才能触发这定时器.
两个bug都是在特殊情况下才发生. 测试的时候没测出来, 在写定时心跳时, 才艰难地发现. 必需得继续努力..