From 00b0193a432da98840108a29494c7da8ef886a5d Mon Sep 17 00:00:00 2001 From: Christian Schwinne Date: Wed, 9 Feb 2022 08:43:35 +0100 Subject: [PATCH] Fix re-init segment data leak (fixes #2535 ) (#2536) --- wled00/FX.h | 4 ++-- wled00/FX_fcn.cpp | 17 +++++++++++------ 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/wled00/FX.h b/wled00/FX.h index c186fdeb..30cd5a48 100644 --- a/wled00/FX.h +++ b/wled00/FX.h @@ -81,7 +81,6 @@ #define SEGLEN _virtualSegmentLength #define SEGACT SEGMENT.stop #define SPEED_FORMULA_L 5U + (50U*(255U - SEGMENT.speed))/SEGLEN -#define RESET_RUNTIME memset(_segment_runtimes, 0, sizeof(_segment_runtimes)) // some common colors #define RED (uint32_t)0xFF0000 @@ -409,8 +408,9 @@ class WS2812FX { * Flags that before the next effect is calculated, * the internal segment state should be reset. * Call resetIfRequired before calling the next effect function. + * Safe to call from interrupts and network requests. */ - inline void reset() { _requiresReset = true; } + inline void markForReset() { _requiresReset = true; } private: uint16_t _dataLen = 0; bool _requiresReset = false; diff --git a/wled00/FX_fcn.cpp b/wled00/FX_fcn.cpp index 42a183a7..302464b6 100644 --- a/wled00/FX_fcn.cpp +++ b/wled00/FX_fcn.cpp @@ -67,7 +67,12 @@ //do not call this method from system context (network callback) void WS2812FX::finalizeInit(void) { - RESET_RUNTIME; + //reset segment runtimes + for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { + _segment_runtimes[i].markForReset(); + _segment_runtimes[i].resetIfRequired(); + } + _hasWhiteChannel = _isOffRefreshRequired = false; //if busses failed to load, add default (fresh install, FS issue, ...) @@ -373,7 +378,7 @@ void WS2812FX::setMode(uint8_t segid, uint8_t m) { if (_segments[segid].mode != m) { - _segment_runtimes[segid].reset(); + _segment_runtimes[segid].markForReset(); _segments[segid].mode = m; } } @@ -612,12 +617,12 @@ void WS2812FX::setSegment(uint8_t n, uint16_t i1, uint16_t i2, uint8_t grouping, seg.spacing = spacing; } if (offset < UINT16_MAX) seg.offset = offset; - _segment_runtimes[n].reset(); + _segment_runtimes[n].markForReset(); } void WS2812FX::restartRuntime() { for (uint8_t i = 0; i < MAX_NUM_SEGMENTS; i++) { - _segment_runtimes[i].reset(); + _segment_runtimes[i].markForReset(); } } @@ -648,9 +653,9 @@ void WS2812FX::resetSegments() { _segments[i].cct = 127; _segments[i].speed = DEFAULT_SPEED; _segments[i].intensity = DEFAULT_INTENSITY; - _segment_runtimes[i].reset(); + _segment_runtimes[i].markForReset(); } - _segment_runtimes[0].reset(); + _segment_runtimes[0].markForReset(); } void WS2812FX::makeAutoSegments() {