mirror of
				https://github.com/esp8266/Arduino.git
				synced 2025-11-03 14:33:37 +03:00 
			
		
		
		
	Safeguard for Ticker internal storage that may be changed during callback execution (#8820)
Temporarily move callback into the function scope and execute it from there. Detaching would no longer destroy it, and re-scheduling would no longer be almost immediately cancelled by our code.
This commit is contained in:
		@@ -115,6 +115,11 @@ void Ticker::_static_callback()
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // it is technically allowed to call either schedule or detach
 | 
				
			||||||
 | 
					    // *during* callback execution. allow both to happen
 | 
				
			||||||
 | 
					    decltype(_callback) tmp;
 | 
				
			||||||
 | 
					    std::swap(tmp, _callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    std::visit([](auto&& callback) {
 | 
					    std::visit([](auto&& callback) {
 | 
				
			||||||
        using T = std::decay_t<decltype(callback)>;
 | 
					        using T = std::decay_t<decltype(callback)>;
 | 
				
			||||||
        if constexpr (std::is_same_v<T, callback_ptr_t>) {
 | 
					        if constexpr (std::is_same_v<T, callback_ptr_t>) {
 | 
				
			||||||
@@ -122,7 +127,16 @@ void Ticker::_static_callback()
 | 
				
			|||||||
        } else if constexpr (std::is_same_v<T, callback_function_t>) {
 | 
					        } else if constexpr (std::is_same_v<T, callback_function_t>) {
 | 
				
			||||||
            callback();
 | 
					            callback();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }, _callback);
 | 
					    }, tmp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // ...and move ourselves back only when object is in a valid state
 | 
				
			||||||
 | 
					    // * ticker was not detached, zeroing timer pointer
 | 
				
			||||||
 | 
					    // * nothing else replaced callback variant
 | 
				
			||||||
 | 
					    if ((_timer == nullptr) || !std::holds_alternative<std::monostate>(_callback)) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    std::swap(tmp, _callback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (_repeat) {
 | 
					    if (_repeat) {
 | 
				
			||||||
        if (_tick) {
 | 
					        if (_tick) {
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user