diff --git a/Cargo.toml b/Cargo.toml index 4b9b684..a422c88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,10 +15,10 @@ lazy_static = "1.4" clap = { version = "4.1", features = ["derive"] } thiserror = "1.0" enum-display-derive = "0.1" -queues = "1.1.0" -duration-str = { version = "0.5.1", features = ["serde"] } -signal-hook = "0.3.17" +queues = "1.1" +duration-str = { version = "0.5", features = ["serde"] } +signal-hook = "0.3" [target.'cfg(target_os = "linux")'.dependencies] -alsa = "0.7.0" +alsa = "0.7" libc = "0.2.21" diff --git a/src/eventmap.rs b/src/eventmap.rs index a2ad23d..b61ef19 100644 --- a/src/eventmap.rs +++ b/src/eventmap.rs @@ -44,7 +44,8 @@ impl<'a> EventMap<'a> { for ev in v { if ev.match_value(event) { 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)?; } } } diff --git a/src/main.rs b/src/main.rs index c49fe3c..4650771 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,13 +24,16 @@ fn main() { loop { match run_file(&c.map_file) { Ok(_) => (), - Err(err) => println!("Error: {}", err) + Err(err) => { + eprintln!("Error: {}", err); + std::process::exit(1); + } } } } fn run_file(filepath: &Path) -> Result<(), Error> { - println!("Load file {}", filepath.to_str().unwrap()); + println!("Load file {}", filepath.to_str().unwrap_or("")); let dat = std::fs::read( filepath )?; let conf = Config::try_from(&dat[..])?; run::run_config(&conf) diff --git a/src/midi/mod.rs b/src/midi/mod.rs index 411b8b7..6e00571 100644 --- a/src/midi/mod.rs +++ b/src/midi/mod.rs @@ -202,6 +202,7 @@ where T: MidiInputHandler + Send // parking signal for runner, true = stop let (pts,prs) = mpsc::channel::(); + // event queue populated by the main thread and consumed by the exec thread let evq = Arc::new(Mutex::new(CircularBuffer::::new(conf.queue_length))); // 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) ); + // wait until interval has been reached let elapsed_time = start.elapsed(); if elapsed_time < conf.interval { thread::sleep(conf.interval - elapsed_time); diff --git a/src/run.rs b/src/run.rs index 12dabda..cdb3dc4 100644 --- a/src/run.rs +++ b/src/run.rs @@ -11,7 +11,7 @@ use crate::config::{Config,DeviceConfig}; use crate::eventmap::EventMap; type DeviceRunItem<'a> = (&'a DeviceConfig, EventMap<'a>, Option>>); -type DeviceRunResult<'a> =(thread::ScopedJoinHandle<'a, ()>, mpsc::Sender); +type DeviceRunResult<'a> =(thread::ScopedJoinHandle<'a, Result<(), Error>>, mpsc::Sender); pub fn cross_shell(cmd: &str) -> Vec { if cfg!(target_os = "windows") { @@ -54,7 +54,7 @@ pub fn run_config(conf: &Config) -> Result<(), Error> { }); thread::scope(|s| -> Result<(), Error> { - let mut threads: Vec<(thread::ScopedJoinHandle<'_, ()>, mpsc::Sender)> = Vec::new(); + let mut threads: Vec = Vec::new(); let ports = input.ports()?; for p in ports { 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()?; for (thread,ss) in threads { let _ = ss.send(true); - thread.join().unwrap(); + let _ = thread.join().unwrap().map_err(|e| eprintln!("WARN: error in thread: {}", e)); } Ok(()) })?; @@ -91,29 +91,36 @@ fn try_connect_process<'a>( cfevmap: &'a[DeviceRunItem<'a>], ) -> Result>, Error> { - for (dev, eventmap, m) in cfevmap { - if let Some(m) = m { + for (dev, eventmap, counter) in cfevmap { + // device counter is full + if let Some(m) = counter { let m = m.lock().unwrap(); if m.0 >= m.1 { continue; } } + 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(); m.0 += 1; } + // stop signal channel let (sts,srs) = mpsc::channel::(); + let mm = counter.as_ref().map(Arc::clone); let nsts = sts.clone(); - let mm = m.as_ref().map(Arc::clone); - let t = s.spawn( move || { - dev.run_connect().unwrap(); - c.run(dev, eventmap, (nsts,srs)).unwrap(); + let t = s.spawn( move || -> Result<(), Error> { + dev.run_connect()?; + // blocking process + c.run(dev, eventmap, (nsts,srs))?; + // decrease device counter if let Some(m) = mm { let mut m = m.lock().unwrap(); m.0 -= 1; } - dev.run_disconnect().unwrap(); + dev.run_disconnect()?; + Ok(()) }); return Ok(Some((t, sts))); }