Was running into couple different race conditions when calling blink then trying to set the LED back to on. Minimal program to recreate bug :
use std::{thread, time::Duration};
use rust_gpiozero::LED;
fn main() {
let mut led = LED::new(12);
led.on();
thread::sleep(Duration::from_secs(5));
led.blink(3, 3);
thread::sleep(Duration::from_secs(5));
led.on();
thread::sleep(Duration::from_secs(5));
led.off();
}
Two race conditions I was hitting:
led.on() called while blinker is running; it sets the blinking to false then turns the device to on but by the time blinker wakes from sleep the device is on and it then turns it off again before bailing from its loop
If you call led.on() between the on/off sleep interval the blinker will then turn it off
The first is remediated by removing device.lock().unwrap().off(); from the if !blinking.load(Ordering::SeqCst){ .. } condition and just relying on who ever calls self.stop() to set the final state it wants.
The second remediated by adding the if !blinking.load(Ordering::SeqCst){ .. } check between sleeps to avoid clobbering the state whoever called stop set (feel there might be cleaner way to do this part 😅).
Was running into couple different race conditions when calling blink then trying to set the LED back to on. Minimal program to recreate bug :
Two race conditions I was hitting:
led.on()
called while blinker is running; it sets theblinking
tofalse
then turns the device to on but by the time blinker wakes from sleep the device is on and it then turns it off again before bailing from its loopled.on()
between the on/off sleep interval the blinker will then turn it offThe first is remediated by removing
device.lock().unwrap().off();
from theif !blinking.load(Ordering::SeqCst){ .. }
condition and just relying on who ever callsself.stop()
to set the final state it wants.The second remediated by adding the
if !blinking.load(Ordering::SeqCst){ .. }
check between sleeps to avoid clobbering the state whoever called stop set (feel there might be cleaner way to do this part 😅).