Adjust how thread exit is handled for anime controller

This commit is contained in:
Luke D. Jones
2022-06-20 22:43:12 +12:00
parent 2ee7fc9910
commit 13a90b00f3
11 changed files with 109 additions and 89 deletions

View File

@@ -141,6 +141,7 @@ impl CtrlAnime {
warn!("AniMe system actions was empty");
return;
}
// Loop rules:
// - Lock the mutex **only when required**. That is, the lock must be held for the shortest duration possible.
// - An AtomicBool used for thread exit should be checked in every loop, including nested
@@ -150,55 +151,54 @@ impl CtrlAnime {
std::thread::Builder::new()
.name("AniMe system thread start".into())
.spawn(move || {
info!("AniMe system thread started");
info!("AniMe new system thread started");
// Getting copies of these Atomics is done *in* the thread to ensure
// we don't block other threads/main
let thread_exit;
let thread_running;
// First two loops are to ensure we *do* aquire a lock on the mutex
// The reason the loop is required is because the USB writes can block
// for up to 10ms. We can't fail to get the atomics.
loop {
if let Ok(lock) = inner.try_lock() {
thread_exit = lock.thread_exit.clone();
thread_running = lock.thread_running.clone();
// Make any running loop exit first
thread_exit.store(true, Ordering::SeqCst);
break;
}
}
loop {
// wait for other threads to set not running so we know they exited
if !thread_running.load(Ordering::SeqCst) {
info!("AniMe forced a thread to exit");
break;
}
// First two loops are to ensure we *do* aquire a lock on the mutex
// The reason the loop is required is because the USB writes can block
// for up to 10ms. We can't fail to get the atomics.
while thread_running.load(Ordering::SeqCst) {
// Make any running loop exit first
thread_exit.store(true, Ordering::SeqCst);
break;
}
info!("AniMe no previous system thread running (now)");
thread_exit.store(false, Ordering::SeqCst);
thread_running.store(true, Ordering::SeqCst);
'main: loop {
thread_running.store(true, Ordering::SeqCst);
for action in actions.iter() {
if thread_exit.load(Ordering::SeqCst) {
break 'main;
}
match action {
ActionData::Animation(frames) => {
if let Err(err) = rog_anime::run_animation(
frames,
thread_exit.clone(),
&|frame| {
inner
.try_lock()
.map(|lock| lock.write_data_buffer(frame))
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
AnimeError::NoFrames
})
},
) {
if let Err(err) = rog_anime::run_animation(frames, &|frame| {
if thread_exit.load(Ordering::Acquire) {
info!("rog-anime: frame-loop was asked to exit");
return Ok(true); // Do safe exit
}
inner
.try_lock()
.map(|lock| {
lock.write_data_buffer(frame);
false // Don't exit yet
})
.map_err(|err| {
warn!("rog_anime::run_animation:callback {}", err);
AnimeError::NoFrames
})
}) {
warn!("rog_anime::run_animation:Animation {}", err);
break 'main;
};

View File

@@ -83,7 +83,6 @@ impl AuraConfigV407 {
}
}
#[derive(Deserialize, Serialize)]
pub struct AuraConfig {
pub brightness: LedBrightness,
@@ -94,7 +93,7 @@ pub struct AuraConfig {
pub sleep_anim_enabled: bool,
pub all_leds_enabled: bool,
pub keys_leds_enabled: bool,
pub side_leds_enabled: bool
pub side_leds_enabled: bool,
}
impl Default for AuraConfig {

View File

@@ -9,10 +9,9 @@ use crate::{
use async_trait::async_trait;
use log::{error, info, warn};
use logind_zbus::manager::ManagerProxy;
use rog_aura::usb::leds_message;
use rog_aura::{
usb::{
LED_APPLY, LED_SET
},
usb::{LED_APPLY, LED_SET},
AuraEffect, LedBrightness, LED_MSG_LEN,
};
use rog_supported::LedSupportedFunctions;
@@ -23,14 +22,11 @@ use std::path::Path;
use std::sync::Arc;
use std::sync::Mutex;
use zbus::Connection;
use rog_aura::usb::leds_message;
use crate::GetSupported;
use super::config::AuraConfig;
impl GetSupported for CtrlKbdLed {
type A = LedSupportedFunctions;
@@ -281,20 +277,19 @@ impl CtrlKbdLed {
self.set_brightness(self.config.brightness)
}
/// Set combination state for boot animation/sleep animation/all leds/keys leds/side leds LED active
pub(super) fn set_power_states(&self, config: &AuraConfig) -> Result<(), RogError> {
let bytes = leds_message(config.boot_anim_enabled,
config.sleep_anim_enabled,
config.all_leds_enabled,
config.keys_leds_enabled,
config.side_leds_enabled);
let bytes = leds_message(
config.boot_anim_enabled,
config.sleep_anim_enabled,
config.all_leds_enabled,
config.keys_leds_enabled,
config.side_leds_enabled,
);
// Quite ugly, must be a more idiomatic way to do
let message = [
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
0x5d, 0xbd, 0x01, bytes[0], bytes[1], bytes[2], 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
];
self.write_bytes(&message)?;

View File

@@ -38,15 +38,15 @@ impl CtrlKbdLedZbus {
ctrl.config.write();
ctrl.set_power_states(&ctrl.config)
.map_err(|err| warn!("{}", err))
.ok();
.map_err(|err| warn!("{}", err))
.ok();
states = Some(LedPowerStates {
boot_anim: ctrl.config.boot_anim_enabled,
sleep_anim: ctrl.config.sleep_anim_enabled,
all_leds: ctrl.config.all_leds_enabled,
keys_leds: ctrl.config.keys_leds_enabled,
side_leds: ctrl.config.side_leds_enabled
side_leds: ctrl.config.side_leds_enabled,
});
}
// Need to pull state out like this due to MutexGuard
@@ -69,15 +69,15 @@ impl CtrlKbdLedZbus {
ctrl.config.write();
ctrl.set_power_states(&ctrl.config)
.map_err(|err| warn!("{}", err))
.ok();
.map_err(|err| warn!("{}", err))
.ok();
states = Some(LedPowerStates {
boot_anim: ctrl.config.boot_anim_enabled,
sleep_anim: ctrl.config.sleep_anim_enabled,
all_leds: ctrl.config.all_leds_enabled,
keys_leds: ctrl.config.keys_leds_enabled,
side_leds: ctrl.config.side_leds_enabled
side_leds: ctrl.config.side_leds_enabled,
});
}
if let Some(states) = states {
@@ -109,7 +109,7 @@ impl CtrlKbdLedZbus {
sleep_anim: ctrl.config.sleep_anim_enabled,
all_leds: ctrl.config.all_leds_enabled,
keys_leds: ctrl.config.keys_leds_enabled,
side_leds: ctrl.config.side_leds_enabled
side_leds: ctrl.config.side_leds_enabled,
});
}
// Need to pull state out like this due to MutexGuard
@@ -140,7 +140,7 @@ impl CtrlKbdLedZbus {
sleep_anim: ctrl.config.sleep_anim_enabled,
all_leds: ctrl.config.all_leds_enabled,
keys_leds: ctrl.config.keys_leds_enabled,
side_leds: ctrl.config.side_leds_enabled
side_leds: ctrl.config.side_leds_enabled,
});
}
// Need to pull state out like this due to MutexGuard
@@ -171,7 +171,7 @@ impl CtrlKbdLedZbus {
sleep_anim: ctrl.config.sleep_anim_enabled,
all_leds: ctrl.config.all_leds_enabled,
keys_leds: ctrl.config.keys_leds_enabled,
side_leds: ctrl.config.side_leds_enabled
side_leds: ctrl.config.side_leds_enabled,
});
}
// Need to pull state out like this due to MutexGuard