From 798ff32c40805495435771db23c044b9fe178eb8 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Tue, 17 Jun 2025 15:55:10 +0200 Subject: [PATCH] cleanup --- .../gpio/binary_sensor/gpio_binary_sensor.cpp | 7 ++++++- .../gpio/binary_sensor/gpio_binary_sensor.h | 21 +++++++------------ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp index 4a12ef834e..160c657c24 100644 --- a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp +++ b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.cpp @@ -70,7 +70,12 @@ void GPIOBinarySensor::dump_config() { void GPIOBinarySensor::loop() { if (this->use_interrupt_) { - if (this->store_.has_changed()) { + if (this->store_.is_changed()) { + // Clear the flag immediately to minimize the window where we might miss changes + this->store_.clear_changed(); + // Read the state and publish it + // Note: If the ISR fires between clear_changed() and get_state(), that's fine - + // we'll process the new change on the next loop iteration bool state = this->store_.get_state(); this->publish_state(state); } diff --git a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h index a25f8fc7fe..43ae5aa23c 100644 --- a/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h +++ b/esphome/components/gpio/binary_sensor/gpio_binary_sensor.h @@ -21,21 +21,14 @@ class GPIOBinarySensorStore { return this->state_; } - bool has_changed() { - // No lock needed: single writer (ISR) / single reader (main loop) pattern - // Volatile bool operations are atomic on all ESPHome-supported platforms - // - // Note: There's a benign race where ISR could set changed_ = true between - // our read and clear. This is intentional and causes no issues because: - // 1. We'll process the state change on the next loop iteration - // 2. Multiple rapid changes between loop iterations would only result in - // one update anyway (we only care about the final state) - // 3. This avoids the overhead of atomic operations in the ISR - if (!this->changed_) { - return false; - } + bool is_changed() const { + // Simple read of volatile bool - no clearing here + return this->changed_; + } + + void clear_changed() { + // Separate method to clear the flag this->changed_ = false; - return true; } protected: