Need to revert tokio mpsc to sync

This commit is contained in:
Luke
2020-06-11 17:29:44 +12:00
parent 3eba038b16
commit 93c6b28409
3 changed files with 93 additions and 105 deletions

View File

@@ -13,9 +13,9 @@ use dbus_tokio::connection;
use log::{error, info, warn}; use log::{error, info, warn};
use rog_client::{DBUS_IFACE, DBUS_NAME, DBUS_PATH}; use rog_client::{DBUS_IFACE, DBUS_NAME, DBUS_PATH};
use std::error::Error; use std::error::Error;
use std::sync::{mpsc, Arc}; use std::sync::Arc;
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use tokio::sync::Mutex; use tokio::sync::{mpsc, Mutex};
pub(super) type FanModeType = Arc<Mutex<Option<u8>>>; pub(super) type FanModeType = Arc<Mutex<Option<u8>>>;
pub(super) type LedMsgType = Arc<Mutex<Option<Vec<u8>>>>; pub(super) type LedMsgType = Arc<Mutex<Option<Vec<u8>>>>;
@@ -87,10 +87,14 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
.request_name(DBUS_NAME, false, true, true) .request_name(DBUS_NAME, false, true, true)
.await?; .await?;
let (aura_command_send, aura_command_recv) = mpsc::sync_channel::<AuraCommand>(1); let (
tree,
let (tree, input, effect, mut animatrix_recv, fan_mode, effect_cancel_signal) = aura_command_sender,
dbus_create_tree(); mut aura_command_recv,
mut animatrix_recv,
fan_mode,
effect_cancel_signal,
) = dbus_create_tree();
// We add the tree to the connection so that incoming method calls will be handled. // We add the tree to the connection so that incoming method calls will be handled.
tree.start_receive_send(&*connection); tree.start_receive_send(&*connection);
@@ -115,11 +119,10 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
.unwrap_or_else(|err| warn!("{:?}", err)); .unwrap_or_else(|err| warn!("{:?}", err));
} }
} }
let acs = aura_command_send.clone();
let data = keyboard_reader.poll_keyboard().await; let data = keyboard_reader.poll_keyboard().await;
if let Some(bytes) = data { if let Some(bytes) = data {
laptop laptop
.run(&mut rogcore, &config1, bytes, acs) .run(&mut rogcore, &config1, bytes, aura_command_sender.clone())
.await .await
.unwrap_or_else(|err| warn!("{:?}", err)); .unwrap_or_else(|err| warn!("{:?}", err));
} }
@@ -128,80 +131,31 @@ pub async fn start_daemon() -> Result<(), Box<dyn Error>> {
// start the LED writer loop // start the LED writer loop
let led_write_handle = tokio::spawn(async move { let led_write_handle = tokio::spawn(async move {
let mut time_mark = Instant::now();
loop { loop {
connection.process_all(); //connection.process_all();
// Check if a key press issued a command // Check if a key press issued a command
let res = aura_command_recv.recv_timeout(Duration::from_micros(50)); while let Some(command) = aura_command_recv.recv().await {
if let Ok(command) = res {
let mut config = config.lock().await; let mut config = config.lock().await;
led_writer match command {
.do_command(command, &mut config) AuraCommand::WriteEffect(_) | AuraCommand::WriteMultizone(_) => led_writer
.await .do_command(command, &mut config)
.unwrap_or_else(|err| warn!("{:?}", err)); .await
.unwrap_or_else(|err| warn!("{:?}", err)),
connection _ => {
.send( led_writer
effect_cancel_signal .do_command(command, &mut config)
.msg(&DBUS_PATH.into(), &DBUS_IFACE.into()) .await
.append1(true), .unwrap_or_else(|err| warn!("{:?}", err));
) connection
.unwrap_or_else(|_| 0); .send(
// Clear any possible queued effect effect_cancel_signal
let mut effect = effect.lock().await; .msg(&DBUS_PATH.into(), &DBUS_IFACE.into())
*effect = None; .append1(true),
time_mark = Instant::now(); )
} else { .unwrap_or_else(|_| 0);
// Check if single mode
if let Ok(mut lock) = input.try_lock() {
if let Some(bytes) = lock.take() {
if !bytes.is_empty() {
let mut config = config.lock().await;
led_writer
.do_command(AuraCommand::WriteBytes(bytes), &mut config)
.await
.unwrap_or_else(|err| warn!("{:?}", err));
// Also cancel any effect client
connection
.send(
effect_cancel_signal.msg(&DBUS_PATH.into(), &DBUS_IFACE.into()),
)
.unwrap();
time_mark = Instant::now();
}
} }
} }
// Write a colour block
let mut effect_lock = effect.lock().await;
if let Some(effect) = effect_lock.take() {
if effect.len() == 11 {
let mut config = config.lock().await;
if effect.len() > 4 {
led_writer
.do_command(AuraCommand::WriteEffect(effect), &mut config)
.await
.unwrap_or_else(|err| warn!("{:?}", err));
} else {
led_writer
.do_command(AuraCommand::WriteMultizone(effect), &mut config)
.await
.unwrap_or_else(|err| warn!("{:?}", err));
}
time_mark = Instant::now();
}
}
}
let now = Instant::now();
// Cool-down steps
// This block is to prevent the loop spooling as fast as possible and saturating the CPU
if now.duration_since(time_mark).as_millis() > 500 {
tokio::time::delay_for(Duration::from_millis(200)).await;
} else if now.duration_since(time_mark).as_millis() > 100 {
tokio::time::delay_for(Duration::from_millis(50)).await;
} else {
tokio::time::delay_for(Duration::from_micros(300)).await;
} }
} }
}); });

View File

@@ -109,8 +109,7 @@ pub(super) struct LaptopBase {
//backlight: Backlight, //backlight: Backlight,
} }
use std::sync::mpsc; use tokio::sync::{mpsc, Mutex};
use tokio::sync::Mutex;
impl LaptopBase { impl LaptopBase {
/// Pass in LedWriter as Mutex so it is only locked when required /// Pass in LedWriter as Mutex so it is only locked when required
@@ -119,7 +118,7 @@ impl LaptopBase {
rogcore: &mut RogCore, rogcore: &mut RogCore,
config: &Mutex<Config>, config: &Mutex<Config>,
key_buf: [u8; 32], key_buf: [u8; 32],
aura_command: mpsc::SyncSender<AuraCommand>, aura_command: mpsc::Sender<AuraCommand>,
) -> Result<(), AuraError> { ) -> Result<(), AuraError> {
match self.usb_product { match self.usb_product {
0x1869 | 0x1866 => { 0x1869 | 0x1866 => {
@@ -168,20 +167,32 @@ impl LaptopBase {
rogcore: &mut RogCore, rogcore: &mut RogCore,
config: &Mutex<Config>, config: &Mutex<Config>,
key_buf: [u8; 32], key_buf: [u8; 32],
aura_command: mpsc::SyncSender<AuraCommand>, mut aura_command: mpsc::Sender<AuraCommand>,
) -> Result<(), AuraError> { ) -> Result<(), AuraError> {
match GX502Keys::from(key_buf[1]) { match GX502Keys::from(key_buf[1]) {
GX502Keys::LedBrightUp => { GX502Keys::LedBrightUp => {
aura_command.send(AuraCommand::BrightInc).unwrap(); aura_command
.send(AuraCommand::BrightInc)
.await
.unwrap_or_else(|_| {});
} }
GX502Keys::LedBrightDown => { GX502Keys::LedBrightDown => {
aura_command.send(AuraCommand::BrightDec).unwrap(); aura_command
.send(AuraCommand::BrightDec)
.await
.unwrap_or_else(|_| {});
} }
GX502Keys::AuraNext => { GX502Keys::AuraNext => {
aura_command.send(AuraCommand::BuiltinNext).unwrap(); aura_command
.send(AuraCommand::BuiltinNext)
.await
.unwrap_or_else(|_| {});
} }
GX502Keys::AuraPrevious => { GX502Keys::AuraPrevious => {
aura_command.send(AuraCommand::BuiltinPrev).unwrap(); aura_command
.send(AuraCommand::BuiltinPrev)
.await
.unwrap_or_else(|_| {});
} }
GX502Keys::ScreenBrightUp => { GX502Keys::ScreenBrightUp => {
rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into()) rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())
@@ -231,14 +242,20 @@ impl LaptopBase {
rogcore: &mut RogCore, rogcore: &mut RogCore,
_config: &Mutex<Config>, _config: &Mutex<Config>,
key_buf: [u8; 32], key_buf: [u8; 32],
aura_command: mpsc::SyncSender<AuraCommand>, mut aura_command: mpsc::Sender<AuraCommand>,
) -> Result<(), AuraError> { ) -> Result<(), AuraError> {
match GL753Keys::from(key_buf[1]) { match GL753Keys::from(key_buf[1]) {
GL753Keys::LedBrightUp => { GL753Keys::LedBrightUp => {
aura_command.send(AuraCommand::BrightInc).unwrap(); aura_command
.send(AuraCommand::BrightInc)
.await
.unwrap_or_else(|_| {});
} }
GL753Keys::LedBrightDown => { GL753Keys::LedBrightDown => {
aura_command.send(AuraCommand::BrightDec).unwrap(); aura_command
.send(AuraCommand::BrightDec)
.await
.unwrap_or_else(|_| {});
} }
GL753Keys::ScreenBrightUp => { GL753Keys::ScreenBrightUp => {
rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into()) rogcore.virt_keys().press(ConsumerKeys::BacklightInc.into())

View File

@@ -1,6 +1,8 @@
use crate::daemon::{FanModeType, LedMsgType, NestedVecType}; use crate::daemon::{FanModeType, LedMsgType, NestedVecType};
use crate::led_control::AuraCommand;
use crate::rogcore::FanLevel; use crate::rogcore::FanLevel;
use dbus::tree::{Factory, MTSync, Method, MethodErr, Signal, Tree}; use dbus::tree::{Factory, MTSync, Method, MethodErr, Signal, Tree};
use log::{error, info, warn};
use rog_client::{DBUS_IFACE, DBUS_PATH}; use rog_client::{DBUS_IFACE, DBUS_PATH};
use std::sync::Arc; use std::sync::Arc;
use tokio::sync::{ use tokio::sync::{
@@ -8,15 +10,17 @@ use tokio::sync::{
Mutex, Mutex,
}; };
pub(super) fn dbus_create_ledmsg_method(msg: LedMsgType) -> Method<MTSync, ()> { pub(super) fn dbus_create_ledmsg_method(sender: Mutex<Sender<AuraCommand>>) -> Method<MTSync, ()> {
let factory = Factory::new_sync::<()>(); let factory = Factory::new_sync::<()>();
factory factory
// method for ledmessage // method for ledmessage
.method("LedWriteBytes", (), { .method("LedWriteBytes", (), {
move |m| { move |m| {
let bytes: Vec<u8> = m.msg.read1()?; let bytes: Vec<u8> = m.msg.read1()?;
if let Ok(mut lock) = msg.try_lock() { if let Ok(mut lock) = sender.try_lock() {
*lock = Some(bytes.to_vec()); let command = AuraCommand::WriteBytes(bytes.to_vec());
lock.try_send(command)
.unwrap_or_else(|err| warn!("LedWriteBytes over mpsc failed: {}", err));
let mret = m let mret = m
.msg .msg
.method_return() .method_return()
@@ -31,17 +35,21 @@ pub(super) fn dbus_create_ledmsg_method(msg: LedMsgType) -> Method<MTSync, ()> {
.inarg::<Vec<u8>, _>("bytearray") .inarg::<Vec<u8>, _>("bytearray")
} }
pub(super) fn dbus_create_ledmultizone_method(effect: NestedVecType) -> Method<MTSync, ()> { pub(super) fn dbus_create_ledmultizone_method(
sender: Mutex<Sender<AuraCommand>>,
) -> Method<MTSync, ()> {
let factory = Factory::new_sync::<()>(); let factory = Factory::new_sync::<()>();
factory factory
// method for ledmessage // method for ledmessage
.method("LedWriteMultizone", (), { .method("LedWriteMultizone", (), {
move |m| { move |m| {
if let Ok(mut lock) = effect.try_lock() { if let Ok(mut lock) = sender.try_lock() {
let mut iter = m.msg.iter_init(); let mut iter = m.msg.iter_init();
let byte_array: Vec<Vec<u8>> = let byte_array: Vec<Vec<u8>> =
vec![iter.read()?, iter.read()?, iter.read()?, iter.read()?]; vec![iter.read()?, iter.read()?, iter.read()?, iter.read()?];
*lock = Some(byte_array); let command = AuraCommand::WriteMultizone(byte_array);
lock.try_send(command)
.unwrap_or_else(|err| warn!("LedWriteMultizone over mpsc failed: {}", err));
let mret = m let mret = m
.msg .msg
.method_return() .method_return()
@@ -60,13 +68,15 @@ pub(super) fn dbus_create_ledmultizone_method(effect: NestedVecType) -> Method<M
.annotate("org.freedesktop.DBus.Method.NoReply", "true") .annotate("org.freedesktop.DBus.Method.NoReply", "true")
} }
pub(super) fn dbus_create_ledeffect_method(effect: NestedVecType) -> Method<MTSync, ()> { pub(super) fn dbus_create_ledeffect_method(
sender: Mutex<Sender<AuraCommand>>,
) -> Method<MTSync, ()> {
let factory = Factory::new_sync::<()>(); let factory = Factory::new_sync::<()>();
factory factory
// method for ledmessage // method for ledmessage
.method("LedWriteEffect", (), { .method("LedWriteEffect", (), {
move |m| { move |m| {
if let Ok(mut lock) = effect.try_lock() { if let Ok(mut lock) = sender.try_lock() {
let mut iter = m.msg.iter_init(); let mut iter = m.msg.iter_init();
let byte_array: Vec<Vec<u8>> = vec![ let byte_array: Vec<Vec<u8>> = vec![
iter.read()?, iter.read()?,
@@ -81,7 +91,9 @@ pub(super) fn dbus_create_ledeffect_method(effect: NestedVecType) -> Method<MTSy
iter.read()?, iter.read()?,
iter.read()?, iter.read()?,
]; ];
*lock = Some(byte_array); let command = AuraCommand::WriteEffect(byte_array);
lock.try_send(command)
.unwrap_or_else(|err| warn!("LedWriteEffect over mpsc failed: {}", err));
Ok(vec![]) Ok(vec![])
} else { } else {
Err(MethodErr::failed("Could not lock daemon for access")) Err(MethodErr::failed("Could not lock daemon for access"))
@@ -152,14 +164,13 @@ pub(super) fn dbus_create_fan_mode_method(fan_mode: FanModeType) -> Method<MTSyn
pub(super) fn dbus_create_tree() -> ( pub(super) fn dbus_create_tree() -> (
Tree<MTSync, ()>, Tree<MTSync, ()>,
LedMsgType, Sender<AuraCommand>,
NestedVecType, Receiver<AuraCommand>,
Receiver<Vec<Vec<u8>>>, Receiver<Vec<Vec<u8>>>,
FanModeType, FanModeType,
Arc<Signal<()>>, Arc<Signal<()>>,
) { ) {
let input_bytes: LedMsgType = Arc::new(Mutex::new(None)); let (aura_command_send, aura_command_recv) = channel::<AuraCommand>(1);
let input_effect: NestedVecType = Arc::new(Mutex::new(None));
let (animatrix_send, animatrix_recv) = channel::<Vec<Vec<u8>>>(1); let (animatrix_send, animatrix_recv) = channel::<Vec<Vec<u8>>>(1);
let fan_mode: FanModeType = Arc::new(Mutex::new(None)); let fan_mode: FanModeType = Arc::new(Mutex::new(None));
@@ -171,9 +182,15 @@ pub(super) fn dbus_create_tree() -> (
factory.object_path(DBUS_PATH, ()).introspectable().add( factory.object_path(DBUS_PATH, ()).introspectable().add(
factory factory
.interface(DBUS_IFACE, ()) .interface(DBUS_IFACE, ())
.add_m(dbus_create_ledmsg_method(input_bytes.clone())) .add_m(dbus_create_ledmsg_method(Mutex::new(
.add_m(dbus_create_ledmultizone_method(input_effect.clone())) aura_command_send.clone(),
.add_m(dbus_create_ledeffect_method(input_effect.clone())) )))
.add_m(dbus_create_ledmultizone_method(Mutex::new(
aura_command_send.clone(),
)))
.add_m(dbus_create_ledeffect_method(Mutex::new(
aura_command_send.clone(),
)))
.add_m(dbus_create_animatrix_method(Mutex::new(animatrix_send))) .add_m(dbus_create_animatrix_method(Mutex::new(animatrix_send)))
.add_m(dbus_create_fan_mode_method(fan_mode.clone())) .add_m(dbus_create_fan_mode_method(fan_mode.clone()))
.add_s(effect_cancel_sig.clone()), .add_s(effect_cancel_sig.clone()),
@@ -182,8 +199,8 @@ pub(super) fn dbus_create_tree() -> (
.add(factory.object_path("/", ()).introspectable()); .add(factory.object_path("/", ()).introspectable());
( (
tree, tree,
input_bytes, aura_command_send,
input_effect, aura_command_recv,
animatrix_recv, animatrix_recv,
fan_mode, fan_mode,
effect_cancel_sig, effect_cancel_sig,