Skip to content

Commit

Permalink
handle SIGINT by breaking out of løøps
Browse files Browse the repository at this point in the history
  • Loading branch information
dctucker committed Mar 8, 2022
1 parent 51ebc02 commit 4394387
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 43 deletions.
46 changes: 37 additions & 9 deletions rust/src/app.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,20 @@ use std::sync::atomic::{AtomicBool, Ordering};
use crate::config::{Config,ConfigLine};
use crate::r#macro::MacroData;
use crate::devices::{ReadThreadMap,OutputDeviceMap};
use std::time::Duration;
use std::thread;

#[derive(Debug)]
pub struct Flags {
pub hup : Arc<AtomicBool>,
pub int : Arc<AtomicBool>,
pub run : Arc<AtomicBool>,
}
impl Flags {
pub fn new() -> Flags {
Flags {
hup : Flags::newflag(false),
int : Flags::newflag(false),
run : Flags::newflag(false),
}
}
Expand Down Expand Up @@ -76,9 +80,9 @@ impl App {
if key == "server" || key == "macro" { println!("TODO implement {} support", key); return; }
if line.out == "server" || line.out == "macro" { println!("TODO implement {} support", line.out); return; }
println!();
let read = read_threads.by_name(&line.r#in);
let out = output_devices.by_name(&line.out);
read.setup_write( out.clone(), line.func.to_string(), line.args.to_string());
let read = &read_threads.by_name(&line.r#in);
let out = &output_devices.by_name(&line.out);
read.setup_write( &out, line.func.to_string(), line.args.to_string());
}

pub fn ready(&mut self) {
Expand All @@ -89,20 +93,39 @@ impl App {
}

pub fn join(&mut self) {
println!("joining");
loop {
println!("App thread signal yield loop");
'signal: loop {
if self.flags.hup.swap(false, Ordering::Relaxed) {
println!("Got SIGHUP");
for (_name,thread) in self.read_threads.iter_mut() {
thread.flags.hup.store(true, Ordering::Relaxed);
}
}
if self.flags.int.swap(false, Ordering::Relaxed) {
println!("Got SIGINT");
for (_name,thread) in self.read_threads.iter_mut() {
thread.flags.int.store(true, Ordering::Relaxed);
}
break 'signal;
}
std::thread::yield_now();
}
/*
for (_name,thread) in self.read_threads {
thread.join();

let mut done = false;
while ! done {
done = true;
for (_name,thread) in self.read_threads.iter() {
if thread.flags.int.load(Ordering::Relaxed) {
done = false;
//println!("{} not done", _name);
std::thread::yield_now();
thread::sleep(Duration::from_millis(500));
break;
}
}
}
*/
//println!("Finishing up");
//self.read_threads.join_all();
}

/*
Expand All @@ -114,3 +137,8 @@ impl App {
}
*/
}
impl Drop for App {
fn drop(&mut self) {
println!("Bye!");
}
}
10 changes: 10 additions & 0 deletions rust/src/devices.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ impl Create<ReadThread> for ReadThreadMap {
}
}

/*
impl ReadThreadMap {
pub fn join_all(&self) {
for (_,j) in self.iter() {
j.join();
}
}
}
*/

pub type OutputDeviceMap = DeviceMap<Arc<RwLock<OutputDevice>>>;
impl Create<Arc<RwLock<OutputDevice>>> for OutputDeviceMap {
fn create( key : &String ) -> Arc<RwLock<OutputDevice>> {
Expand Down
35 changes: 33 additions & 2 deletions rust/src/filters/ccmap.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,38 @@ impl CallbackFn for CCMap {
);
}
fn callback(&self, data : &mut CallbackData, buf : &Vec<u8>) -> usize {
//println!("{}", buf);
0
let exp_state : u8 = 0xb0 + self.channel;
let mut out_buf = [0u8 ; BUFSIZE];
let mut cc : u8 = 0xff;
let mut val : u8 = 0xff;

let mut a = 0;
for c in buf {
let cur_state : u8 = data.output_device.scan_status(*c);
if cur_state == exp_state && *c < 0x80 {
if cc == 0xff {
let s : usize = (*c).try_into().unwrap();
let out_cc : u8 = self.out_cc[s];
if out_cc < 0x80 {
cc = out_cc;
} else {
cc = 0xfe;
}
} else if val == 0xff {
if cc < 0x80 {
val = *c;
out_buf[a] = exp_state; a += 1;
out_buf[a] = cc; a += 1;
out_buf[a] = val; a += 1;
}
val = 0xff;
cc = 0xff;
}
} else {
cc = 0xff;
val = 0xff;
}
}
data.output_device.send_buffer(&out_buf[0..a].to_vec()).unwrap()
}
}
11 changes: 5 additions & 6 deletions rust/src/filters/channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,21 +22,20 @@ impl CallbackFn for Channel {
let mut out_buf = [0u8 ; BUFSIZE];
let mut current_mask = 0;

let mut output_device = data.output_device.write().unwrap();
if output_device.midi_in_exclusive == data.midi_in {
if data.output_device.midi_in_exclusive == data.midi_in {
current_mask = MASK_SYSEX;
}

let mut a = 0;
for c in buf {
let _cur_state = output_device.scan_status(*c);
let _cur_state = data.output_device.scan_status(*c);
if *c >= 0xf8 {
current_mask = MASK_RT;
} else if *c >= 0xf0 {
if *c == 0xf0 {
output_device.midi_in_exclusive = data.midi_in.clone();
data.output_device.midi_in_exclusive = data.midi_in.clone();
} else if *c == 0xf7 {
output_device.midi_in_exclusive = "".to_string();
data.output_device.midi_in_exclusive = "".to_string();
}
current_mask = MASK_SYSEX;
} else if *c >= 0x80 {
Expand All @@ -48,6 +47,6 @@ impl CallbackFn for Channel {
a += 1;
}
}
output_device.send_buffer(&out_buf[0..a].to_vec()).unwrap()
data.output_device.send_buffer(&out_buf[0..a].to_vec()).unwrap()
}
}
11 changes: 5 additions & 6 deletions rust/src/filters/funnel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,21 +12,20 @@ impl CallbackFn for Funnel {
let mut out_buf = [0u8 ; BUFSIZE];
let mut current_mask = 0;

let mut output_device = data.output_device.write().unwrap();
if output_device.midi_in_exclusive == data.midi_in {
if data.output_device.midi_in_exclusive == data.midi_in {
current_mask = MASK_SYSEX;
}

let mut a = 0;
for c in buf {
let _cur_state = output_device.scan_status(*c);
let _cur_state = data.output_device.scan_status(*c);
if *c >= 0xf8 {
current_mask = MASK_RT;
} else if *c >= 0xf0 {
if *c == 0xf0 {
output_device.midi_in_exclusive = data.midi_in.clone();
data.output_device.midi_in_exclusive = data.midi_in.clone();
} else if *c == 0xf7 {
output_device.midi_in_exclusive = "".to_string();
data.output_device.midi_in_exclusive = "".to_string();
}
current_mask = MASK_SYSEX;
} else if *c >= 0x80 {
Expand All @@ -41,6 +40,6 @@ impl CallbackFn for Funnel {
a += 1;
}
}
output_device.send_buffer(&out_buf[0..a].to_vec()).unwrap()
data.output_device.send_buffer(&out_buf[0..a].to_vec()).unwrap()
}
}
2 changes: 1 addition & 1 deletion rust/src/filters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ pub enum Callback {
#[enum_dispatch(Callback)]
pub trait CallbackFn {
fn callback(&self, _data : &mut CallbackData, _buf : &Vec<u8>) -> usize;
fn add_args( &mut self, args : String ) {}
fn add_args( &mut self, _args : String ) {}
}

impl Callback {
Expand Down
5 changes: 2 additions & 3 deletions rust/src/filters/status.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,17 @@ impl CallbackFn for Status {
fn callback(&self, data : &mut CallbackData, buf : &Vec<u8>) -> usize {
let mut out_buf = [0u8 ; BUFSIZE];

let mut output_device = data.output_device.write().unwrap();
let mut a = 0;
let out_status = &self.out_status;

for c in buf {
let cur_state = output_device.scan_status(*c);
let cur_state = data.output_device.scan_status(*c);
let i : usize = ((0x80 | cur_state) - 0x80).try_into().unwrap();
if out_status[i] == cur_state {
out_buf[ a ] = *c;
a += 1;
}
}
output_device.send_buffer(&out_buf[0..a].to_vec()).unwrap()
data.output_device.send_buffer(&out_buf[0..a].to_vec()).unwrap()
}
}
1 change: 1 addition & 0 deletions rust/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ fn main() -> Result<(), Error> {
println!("Starting up");
let mut app = app::App::new();
signal_hook::flag::register(signal_hook::SIGHUP, Arc::clone(&app.flags.hup))?;
signal_hook::flag::register(signal_hook::SIGINT, Arc::clone(&app.flags.int))?;

// println!("{:#?}", app);

Expand Down
4 changes: 4 additions & 0 deletions rust/src/output.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ impl OutputDevice {
out
}
pub fn connect( &mut self ) {
match self.midi {
Some(_) => { return; },
None => {},
};
self.midi = match Rawmidi::new(&self.port_name, alsa::Direction::output(), false) {
Ok(midi) => {
println!("Opened {} for output", self.port_name);
Expand Down
28 changes: 16 additions & 12 deletions rust/src/thru.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,15 +40,15 @@ impl ReadData {
macros: vec![],
}
}
pub fn setup_write(&mut self, out : Arc<RwLock<OutputDevice>>, func : String, args : String) {
pub fn setup_write(&mut self, out : &Arc<RwLock<OutputDevice>>, func : String, args : String) {
let port_name = out.read().unwrap().port_name.clone();
for wd in self.outs.iter_mut() {
if wd.func_name == func && wd.output_device.read().unwrap().port_name == port_name {
wd.add_args(args);
return;
}
}
self.outs.push( WriteData::new(out, func, args) );
self.outs.push( WriteData::new(&out, func, args) );

}
fn handle_read(&mut self, buf : Vec<u8>) {
Expand All @@ -62,7 +62,7 @@ impl ReadData {
}

pub struct ReadThread {
//handle : JoinHandle<()>,
pub handle : std::thread::JoinHandle<()>,
data : Arc<RwLock<ReadData>>,
pub flags : Arc<Flags>,
}
Expand All @@ -77,12 +77,11 @@ impl ReadThread {
use alsa::PollDescriptors;
let mut buf : Vec<u8> = vec![0; BUFSIZE];
while ! flags.run.load(Ordering::Relaxed) {
if flags.hup.swap(false, Ordering::Relaxed) {
break 'read;
}
if flags.hup.swap(false, Ordering::Relaxed) { break 'read; }
thread::sleep(Duration::from_millis(500));
}
thread::yield_now();
if flags.int.load(Ordering::Relaxed) { break 'read; }

let res = alsa::poll::poll(&mut midi.get().unwrap(), 500).unwrap();
if res == 0 { continue; }
Expand All @@ -104,10 +103,12 @@ impl ReadThread {
tries += 1;
thread::sleep(Duration::from_millis(500));
if flags.hup.swap(false, Ordering::Relaxed) { break 'wait; }
if flags.int.load(Ordering::Relaxed) { break 'wait; }
if tries % 5 == 0 {
let mut snooze = 10;
while snooze > 0 {
if flags.hup.swap(false, Ordering::Relaxed) { break 'wait; }
if flags.int.load(Ordering::Relaxed) { break 'wait; }
thread::sleep(Duration::from_millis(1000));
snooze -= 1;
}
Expand All @@ -127,6 +128,7 @@ impl ReadThread {
thread::sleep(Duration::from_millis(1000));
}
'outer: loop {
if flags.int.load(Ordering::Relaxed) { break 'outer; }
println!("Scanning for {}", port_name);
match Rawmidi::new(&port_name, Direction::input(), false) {
Err(_) => {},
Expand All @@ -138,22 +140,24 @@ impl ReadThread {
thread::yield_now();
ReadThread::wait_loop(&flags);
}
println!("Read thread {} done", port_name);
flags.int.store(false, Ordering::Relaxed);
};
let _handle = thread::spawn(routine);
let handle = thread::spawn(routine);
println!("Spawning new thread");

ReadThread {
flags: flags2.clone(),
flags: flags2,
data: arc2,
//handle: handle,
handle: handle,
}
}
/*
pub fn join(self) {
self.handle.join().unwrap();
pub fn join(&self) {
//self.handle.join();
}
*/
pub fn setup_write(&self, out : Arc<RwLock<OutputDevice>>, func : String, args : String) {
pub fn setup_write(&self, out : &Arc<RwLock<OutputDevice>>, func : String, args : String) {
self.data.write().unwrap().setup_write(out,func,args);
}
}
8 changes: 4 additions & 4 deletions rust/src/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ use crate::filters::CallbackFn;
use crate::output::OutputDevice;
use crate::filters;

pub struct CallbackData {
pub output_device : Arc<RwLock<OutputDevice>>,
pub struct CallbackData<'a> {
pub output_device : &'a mut OutputDevice,
pub midi_in : String,
}

Expand All @@ -24,7 +24,7 @@ impl fmt::Debug for WriteData {
}

impl WriteData {
pub fn new( out : Arc<RwLock<OutputDevice>>, func : String, args : String ) -> WriteData {
pub fn new( out : &Arc<RwLock<OutputDevice>>, func : String, args : String ) -> WriteData {
WriteData {
output_device: out.clone(),
func_name: func.clone(),
Expand All @@ -38,7 +38,7 @@ impl WriteData {
}
pub fn call(&mut self, buf : &Vec<u8>) {
let mut data = CallbackData {
output_device: self.output_device.clone(),
output_device: &mut self.output_device.write().unwrap(),
midi_in: self.midi_in.to_string(),
};
self.callback.callback(&mut data, buf);
Expand Down

0 comments on commit 4394387

Please sign in to comment.