From c436bd42c5961c02eb439fe4ce2584b27f832eff Mon Sep 17 00:00:00 2001 From: Daniel Novak Date: Sat, 28 Feb 2026 16:22:58 +0100 Subject: [PATCH] Fix countBefore sentinel regression from millis wraparound fix PR #1795 changed PacketQueue::countBefore() to use signed 2's complement arithmetic for millis wraparound safety. However, this broke the 0xFFFFFFFF sentinel pattern used by callers to mean "count all packets regardless of schedule". With the signed comparison, countBefore(0xFFFFFFFF) always returns 0, causing hasPendingWork() to report false and repeaters to sleep with packets still queued. Stats reporting also shows queue_len as 0. Add an early-return for the sentinel value before the loop, and document the sentinel convention on the virtual interface and implementation. --- src/Dispatcher.h | 2 +- src/helpers/StaticPoolPacketManager.cpp | 1 + src/helpers/StaticPoolPacketManager.h | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Dispatcher.h b/src/Dispatcher.h index 0a448c40..7ecee1a4 100644 --- a/src/Dispatcher.h +++ b/src/Dispatcher.h @@ -89,7 +89,7 @@ public: virtual void queueOutbound(Packet* packet, uint8_t priority, uint32_t scheduled_for) = 0; virtual Packet* getNextOutbound(uint32_t now) = 0; // by priority - virtual int getOutboundCount(uint32_t now) const = 0; + virtual int getOutboundCount(uint32_t now) const = 0; // pass now=0xFFFFFFFF to count all virtual int getFreeCount() const = 0; virtual Packet* getOutboundByIdx(int i) = 0; virtual Packet* removeOutboundByIdx(int i) = 0; diff --git a/src/helpers/StaticPoolPacketManager.cpp b/src/helpers/StaticPoolPacketManager.cpp index 67d63979..c89d5088 100644 --- a/src/helpers/StaticPoolPacketManager.cpp +++ b/src/helpers/StaticPoolPacketManager.cpp @@ -9,6 +9,7 @@ PacketQueue::PacketQueue(int max_entries) { } int PacketQueue::countBefore(uint32_t now) const { + if (now == 0xFFFFFFFF) return _num; // sentinel: count all entries regardless of schedule int n = 0; for (int j = 0; j < _num; j++) { if ((int32_t)(_schedule_table[j] - now) > 0) continue; // scheduled for future... ignore for now diff --git a/src/helpers/StaticPoolPacketManager.h b/src/helpers/StaticPoolPacketManager.h index 52c299db..bcc5deb9 100644 --- a/src/helpers/StaticPoolPacketManager.h +++ b/src/helpers/StaticPoolPacketManager.h @@ -13,7 +13,7 @@ public: mesh::Packet* get(uint32_t now); bool add(mesh::Packet* packet, uint8_t priority, uint32_t scheduled_for); int count() const { return _num; } - int countBefore(uint32_t now) const; + int countBefore(uint32_t now) const; // pass now=0xFFFFFFFF to count all mesh::Packet* itemAt(int i) const { return _table[i]; } mesh::Packet* removeByIdx(int i); };