RF24Mesh: replace rollover-unsafe millis() deadlines with elapsed-time checks#270
Merged
Merged
Conversation
Copilot
AI
changed the title
[WIP] Patch rollover-unsafe millis timeout patterns
RF24Mesh: replace rollover-unsafe Jun 4, 2026
millis() deadlines with elapsed-time checks
Contributor
Memory usage change @ 31b59d1
Click for full report per board
|
| Sketch | Flash | % | RAM for global variables | % |
|---|---|---|---|---|
| examples/RF24Mesh_Example | 0 | 0 | 0 | 0 |
| examples/RF24Mesh_Example_Master_Statics | -2 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Master_To_Nodes | -2 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Node2Node | -2 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Node2NodeExtra | -2 | -0.01 | 0 | 0 |
| examples/RF24Mesh_SerialConfig | 0 | 0 | 0 | 0 |
| examples/RF24Mesh_Example_Master | -2 | -0.01 | 0 | 0 |
arduino:samd:mkrzero
| Sketch | Flash | % | RAM for global variables | % |
|---|---|---|---|---|
| examples/RF24Mesh_Example | -16 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Master_Statics | -16 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Master_To_Nodes | -16 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Node2Node | -16 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Node2NodeExtra | -16 | -0.01 | 0 | 0 |
| examples/RF24Mesh_SerialConfig | -16 | -0.01 | 0 | 0 |
| examples/RF24Mesh_Example_Master | -16 | -0.01 | 0 | 0 |
2bndy5
approved these changes
Jun 4, 2026
2bndy5
left a comment
Member
There was a problem hiding this comment.
again with the const in a func body: looks good on a size delta report. Has this been tested IRL?
Member
|
I think I'm confusing |
Member
|
Nope, still gotta test out all these millis() changes to make it official. And yeah, I barely know the difference between |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This updates RF24Mesh timeout handling to eliminate
millis() + Nabsolute-deadline comparisons that can misbehave across timer wraparound. All affected paths now use unsigned elapsed-time subtraction (millis() - start) while preserving existing timeout durations and control flow.Patched timeout logic in
RF24Mesh.cppwrite(const void*, uint8_t, size_t, uint8_t):lookupTimeout = millis() + MESH_WRITE_TIMEOUT/millis() > lookupTimeoutlookupStart+ elapsed-time comparisonrequestAddress()poll window:timeout = millis() + 55/while (millis() < timeout && ...)pollStart+while (millis() - pollStart < 55 && ...)requestAddress()response wait:timeout = millis() + 225/while (millis() < timeout)responseStart+while (millis() - responseStart < 225)Behavior preserved
MESH_WRITE_TIMEOUT,55,225)Original prompt
Patch all rollover-unsafe
millis()timeout patterns across these repositories by replacing absolute-deadline logic likeuint32_t timeout = millis() + N; while (millis() < timeout) {}andif (millis() > timeout)with rollover-safe elapsed-time comparisons using unsigned subtraction (for exampleconst uint32_t start = millis(); while (millis() - start < N) {}andif (millis() - start > N)).Create pull requests in the following repositories:
Confirmed unsafe sites already identified from repository code/search results include:
unsigned long inputTimeout = millis() + 7000;andwhile (!Serial.available() && millis() < inputTimeout).uint32_t timeout = millis() + 100;withif (millis() > timeout)inupdate().uint32_t timer = millis() + 2; while (millis() < timer) {}.uint32_t lookupTimeout = millis() + MESH_WRITE_TIMEOUT;withif (millis() > lookupTimeout || toNode == -2)inwrite(const void*, uint8_t, size_t, uint8_t).uint32_t timeout = millis() + 55; while (millis() < timeout && pollCount < MESH_MAXPOLLS)inrequestAddress().timeout = millis() + 225; while (millis() < timeout)inrequestAddress().uint32_t timeout = millis() + serverConnectionTimeout; while (len > tcp_sndbuf(fpcb)) { ... if (millis() > timeout) ... }inblocking_write().volatile uint32_t timer = millis() + 5000; while (...) { if (millis() > timer) ... }inblocking_write().clTimeout = millis() + 5001,if (millis() > clTimeout), andtimer = millis() + 1000; while (millis() < timer).uint32_t txQueueTimer = millis() + 750;withif (millis() > txQueueTimer && queueSize >= 10)inhandleRadioOut().Requirements:
startvariables and elapsed-time comparisons rather than changing public APIs.millis()deadline comparisons are discovered during implementation in the targeted repos, patch them too if they are clearly the same class of bug.The following is the prior conversation context from the user's chat exploration (may be truncated):
User: can you find all rollover unsafe millis() calls in RF24, RF24Network, RF24Mesh, RF24Ethernet & RF24Gateway?
Assistant: Yes — I found the clearly rollover-unsafe
millis()usage patterns in those repos.Unsafe pattern I looked for: storing an absolute deadline like
timeout = millis() + Nand later comparing withmillis() < timeoutor similar. That breaks acrossmillis()wraparound.Safe pattern:
if (millis() - start >= interval)using unsigned subtraction.Confirmed rollover-unsafe calls
RF24Mesh
RF24Mesh.cpp—requestAddress()This is rollover-unsafe because it compares current time to an absolute future timestamp. If wrap happens before/around the loop, the condition can fail early or behave incorrectly.
RF24Ethernet
RF24Client.h—ConnectStatein-class initializationThese initializations are not inherently unsafe by themselves, but they are suspect state seeds because they store absolute times. Whether they’re unsafe depends on how they’re compared later.
RF24Client.cpp— reopen-window timing