diff --git a/src/util/dlist.h b/src/util/dlist.h index 4c0e51e58..52cb25548 100644 --- a/src/util/dlist.h +++ b/src/util/dlist.h @@ -155,15 +155,23 @@ public: elem->init(elem); } - bool invariant() const { - auto* e = this; - do { - if (e->m_next->m_prev != e) - return false; - e = e->m_next; - } - while (e != this); - return true; + bool invariant() const { + auto* e = this; + const T* slow = static_cast(this); + const T* fast = m_next; + bool looped = false; + // m_next of each node should point back to m_prev of the following node, + // and m_prev of each node should point forward to m_next of the preceding node. + while (slow != fast) { + if (fast->m_prev->m_next != fast || fast->m_next->m_prev != fast) + return false; + fast = fast->m_next; + looped = looped || (fast == static_cast(this)); + if (!looped && fast == m_next) + // We should be able to traverse back to the starting node. + return false; + } + return true; } static bool contains(T const* list, T const* elem) {