fix: program stuck in infinite loop on config error
This commit is contained in:
parent
1a5bb96e41
commit
9b97114dcd
5 changed files with 31 additions and 18 deletions
|
|
@ -15,10 +15,10 @@ lazy_static = "1.4"
|
||||||
clap = { version = "4.1", features = ["derive"] }
|
clap = { version = "4.1", features = ["derive"] }
|
||||||
thiserror = "1.0"
|
thiserror = "1.0"
|
||||||
enum-display-derive = "0.1"
|
enum-display-derive = "0.1"
|
||||||
queues = "1.1.0"
|
queues = "1.1"
|
||||||
duration-str = { version = "0.5.1", features = ["serde"] }
|
duration-str = { version = "0.5", features = ["serde"] }
|
||||||
signal-hook = "0.3.17"
|
signal-hook = "0.3"
|
||||||
|
|
||||||
[target.'cfg(target_os = "linux")'.dependencies]
|
[target.'cfg(target_os = "linux")'.dependencies]
|
||||||
alsa = "0.7.0"
|
alsa = "0.7"
|
||||||
libc = "0.2.21"
|
libc = "0.2.21"
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,8 @@ impl<'a> EventMap<'a> {
|
||||||
for ev in v {
|
for ev in v {
|
||||||
if ev.match_value(event) {
|
if ev.match_value(event) {
|
||||||
for r in &ev.run {
|
for r in &ev.run {
|
||||||
r.run(event.make_env(ev.remap.as_ref(), ev.float )?.to_map(r.envconf.as_ref()))?;
|
let env = event.make_env(ev.remap.as_ref(), ev.float )?.to_map(r.envconf.as_ref());
|
||||||
|
r.run(env)?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -24,13 +24,16 @@ fn main() {
|
||||||
loop {
|
loop {
|
||||||
match run_file(&c.map_file) {
|
match run_file(&c.map_file) {
|
||||||
Ok(_) => (),
|
Ok(_) => (),
|
||||||
Err(err) => println!("Error: {}", err)
|
Err(err) => {
|
||||||
|
eprintln!("Error: {}", err);
|
||||||
|
std::process::exit(1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn run_file(filepath: &Path) -> Result<(), Error> {
|
fn run_file(filepath: &Path) -> Result<(), Error> {
|
||||||
println!("Load file {}", filepath.to_str().unwrap());
|
println!("Load file {}", filepath.to_str().unwrap_or("<unknown>"));
|
||||||
let dat = std::fs::read( filepath )?;
|
let dat = std::fs::read( filepath )?;
|
||||||
let conf = Config::try_from(&dat[..])?;
|
let conf = Config::try_from(&dat[..])?;
|
||||||
run::run_config(&conf)
|
run::run_config(&conf)
|
||||||
|
|
|
||||||
|
|
@ -202,6 +202,7 @@ where T: MidiInputHandler + Send
|
||||||
// parking signal for runner, true = stop
|
// parking signal for runner, true = stop
|
||||||
let (pts,prs) = mpsc::channel::<bool>();
|
let (pts,prs) = mpsc::channel::<bool>();
|
||||||
|
|
||||||
|
// event queue populated by the main thread and consumed by the exec thread
|
||||||
let evq = Arc::new(Mutex::new(CircularBuffer::<EventBuf>::new(conf.queue_length)));
|
let evq = Arc::new(Mutex::new(CircularBuffer::<EventBuf>::new(conf.queue_length)));
|
||||||
|
|
||||||
// background execution loop
|
// background execution loop
|
||||||
|
|
@ -222,6 +223,7 @@ where T: MidiInputHandler + Send
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
eventmap.run_event(&ev.as_event()).unwrap_or_else(|e| eprintln!("ERROR: error on run: {}", e) );
|
eventmap.run_event(&ev.as_event()).unwrap_or_else(|e| eprintln!("ERROR: error on run: {}", e) );
|
||||||
|
// wait until interval has been reached
|
||||||
let elapsed_time = start.elapsed();
|
let elapsed_time = start.elapsed();
|
||||||
if elapsed_time < conf.interval {
|
if elapsed_time < conf.interval {
|
||||||
thread::sleep(conf.interval - elapsed_time);
|
thread::sleep(conf.interval - elapsed_time);
|
||||||
|
|
|
||||||
29
src/run.rs
29
src/run.rs
|
|
@ -11,7 +11,7 @@ use crate::config::{Config,DeviceConfig};
|
||||||
use crate::eventmap::EventMap;
|
use crate::eventmap::EventMap;
|
||||||
|
|
||||||
type DeviceRunItem<'a> = (&'a DeviceConfig, EventMap<'a>, Option<Arc<Mutex<(u32, u32)>>>);
|
type DeviceRunItem<'a> = (&'a DeviceConfig, EventMap<'a>, Option<Arc<Mutex<(u32, u32)>>>);
|
||||||
type DeviceRunResult<'a> =(thread::ScopedJoinHandle<'a, ()>, mpsc::Sender<bool>);
|
type DeviceRunResult<'a> =(thread::ScopedJoinHandle<'a, Result<(), Error>>, mpsc::Sender<bool>);
|
||||||
|
|
||||||
pub fn cross_shell(cmd: &str) -> Vec<String> {
|
pub fn cross_shell(cmd: &str) -> Vec<String> {
|
||||||
if cfg!(target_os = "windows") {
|
if cfg!(target_os = "windows") {
|
||||||
|
|
@ -54,7 +54,7 @@ pub fn run_config(conf: &Config) -> Result<(), Error> {
|
||||||
});
|
});
|
||||||
|
|
||||||
thread::scope(|s| -> Result<(), Error> {
|
thread::scope(|s| -> Result<(), Error> {
|
||||||
let mut threads: Vec<(thread::ScopedJoinHandle<'_, ()>, mpsc::Sender<bool>)> = Vec::new();
|
let mut threads: Vec<DeviceRunResult> = Vec::new();
|
||||||
let ports = input.ports()?;
|
let ports = input.ports()?;
|
||||||
for p in ports {
|
for p in ports {
|
||||||
if let Some(v) = try_connect_process(&input, s, &p, &cfevmap)? { threads.push(v) }
|
if let Some(v) = try_connect_process(&input, s, &p, &cfevmap)? { threads.push(v) }
|
||||||
|
|
@ -77,7 +77,7 @@ pub fn run_config(conf: &Config) -> Result<(), Error> {
|
||||||
event_thread.join().unwrap()?;
|
event_thread.join().unwrap()?;
|
||||||
for (thread,ss) in threads {
|
for (thread,ss) in threads {
|
||||||
let _ = ss.send(true);
|
let _ = ss.send(true);
|
||||||
thread.join().unwrap();
|
let _ = thread.join().unwrap().map_err(|e| eprintln!("WARN: error in thread: {}", e));
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
})?;
|
})?;
|
||||||
|
|
@ -91,29 +91,36 @@ fn try_connect_process<'a>(
|
||||||
cfevmap: &'a[DeviceRunItem<'a>],
|
cfevmap: &'a[DeviceRunItem<'a>],
|
||||||
)
|
)
|
||||||
-> Result<Option<DeviceRunResult<'a>>, Error> {
|
-> Result<Option<DeviceRunResult<'a>>, Error> {
|
||||||
for (dev, eventmap, m) in cfevmap {
|
for (dev, eventmap, counter) in cfevmap {
|
||||||
if let Some(m) = m {
|
// device counter is full
|
||||||
|
if let Some(m) = counter {
|
||||||
let m = m.lock().unwrap();
|
let m = m.lock().unwrap();
|
||||||
if m.0 >= m.1 {
|
if m.0 >= m.1 {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(mut c) = input.try_connect(p.clone(), PortFilter::from(*dev))? {
|
if let Some(mut c) = input.try_connect(p.clone(), PortFilter::from(*dev))? {
|
||||||
if let Some(m) = m {
|
// increase device counter
|
||||||
|
if let Some(m) = counter {
|
||||||
let mut m = m.lock().unwrap();
|
let mut m = m.lock().unwrap();
|
||||||
m.0 += 1;
|
m.0 += 1;
|
||||||
}
|
}
|
||||||
|
// stop signal channel
|
||||||
let (sts,srs) = mpsc::channel::<bool>();
|
let (sts,srs) = mpsc::channel::<bool>();
|
||||||
|
let mm = counter.as_ref().map(Arc::clone);
|
||||||
let nsts = sts.clone();
|
let nsts = sts.clone();
|
||||||
let mm = m.as_ref().map(Arc::clone);
|
let t = s.spawn( move || -> Result<(), Error> {
|
||||||
let t = s.spawn( move || {
|
dev.run_connect()?;
|
||||||
dev.run_connect().unwrap();
|
// blocking process
|
||||||
c.run(dev, eventmap, (nsts,srs)).unwrap();
|
c.run(dev, eventmap, (nsts,srs))?;
|
||||||
|
// decrease device counter
|
||||||
if let Some(m) = mm {
|
if let Some(m) = mm {
|
||||||
let mut m = m.lock().unwrap();
|
let mut m = m.lock().unwrap();
|
||||||
m.0 -= 1;
|
m.0 -= 1;
|
||||||
}
|
}
|
||||||
dev.run_disconnect().unwrap();
|
dev.run_disconnect()?;
|
||||||
|
Ok(())
|
||||||
});
|
});
|
||||||
return Ok(Some((t, sts)));
|
return Ok(Some((t, sts)));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue