pub fn connect_all_available_and_execute<F>(&mut self, tss: &[Mutex<TargetStackShield>], mut function: F) where F: FnMut(&mut Self, &TargetInfo, u8) {
        let mut unprocessed_tss_queue: Vec<&Mutex<TargetStackShield>> = tss.iter().collect();

        while !unprocessed_tss_queue.is_empty() {
            match unprocessed_tss_queue[0].try_lock() {
                Ok(tss) => {
                    log::trace!("{}: locked tss {}.", self.get_channel(), tss.get_position());

                    if let Some(targets) = tss.get_targets() {
                        for (pos, target) in targets.iter().enumerate() {
                            if let TargetState::Known(ref target_info) = target {
                                match retry(
                                    Fixed::from_millis(FIXED_RETRY_DELAY_MS)
                                        .take(CONNECT_RETRY_LIMIT),
                                    || {
                                        tss.inner.borrow_mut().connect_test_channel_to_target(
                                            self.channel,
                                            Target::try_from(pos as u8).unwrap(),
                                        )
                                    },
                                ){
                                    Ok(_) => function(self, target_info, tss.get_position()),
                                    Err(err) => match err {
                                        retry::Error::Operation { error, ..} => {
                                            log::error!(
                                                "Failed to connect testchannel {:?} to target {:?}: {}\nCaused by: {:?}",
                                                self.channel,
                                                Target::try_from(pos as u8).unwrap(),
                                                error,
                                                error.source()
    
                                            );
                                            // At this point it is uncertain in which state the busswitches are. Therefore we try to disconnect all affected switches, so any remaining operations are not influenced by this error.
                                            // If disconnecting fails the testrack hardware is in an undefined and unrecoverable state, therefore the application panics as such errors need manual power reset and are likely caused by faulty hardware
                                            tss.inner.borrow_mut().disconnect_all().expect("Failed to disconnect tss successfully, this error cannot be recovered, as further operation in such a state may influence other testchannels.\n This is likely caused by a hardware issue in the I2C communication, please verify that your hardware is working correctly.");
                                        },
                                        retry::Error::Internal(string) => panic!("Internal library error in retry crate: {}", string),
                                    },
                                }
                            }
                        }
                    }

                    drop(tss);
                    unprocessed_tss_queue.remove(0);
                }
                Err(std::sync::TryLockError::WouldBlock) => {
                    // If the lock is currently held by another testchannel (eg. the tss is currently connected to another testchannel), it is skipped and reinserted at the end of the queue
                    let removed = unprocessed_tss_queue.remove(0);
                    unprocessed_tss_queue.push(removed);
                }
                Err(std::sync::TryLockError::Poisoned(err)) => {
                    panic!("Mutex is poisoned! \n{}", err)
                }
            }
        }
    }
/// Loops through all available TSS and connects the testchannel to each available target, while executing the provided function on each connection.
Loops through all available TSS and connects the testchannel to each available target, while executing the provided function on each connection.
Loops through all available TSS and connects the testchannel to each available target while executing the provided function on each connection .
pub fn connect_all_available_and_execute<F>(&mut self, tss: &[Mutex<TargetStackShield>], mut function: F) where F: FnMut(&mut Self, &TargetInfo, u8) {
        let mut unprocessed_tss_queue: Vec<&Mutex<TargetStackShield>> = tss.iter().collect();
        while !unprocessed_tss_queue.is_empty() {
            match unprocessed_tss_queue[0].try_lock() {
                Ok(tss) => {
                    log::trace!("{}: locked tss {}.", self.get_channel(), tss.get_position());
                    if let Some(targets) = tss.get_targets() {
                        for (pos, target) in targets.iter().enumerate() {
                            if let TargetState::Known(ref target_info) = target {
                                match retry(
                                    Fixed::from_millis(FIXED_RETRY_DELAY_MS)
                                        .take(CONNECT_RETRY_LIMIT),
                                    || {
                                        tss.inner.borrow_mut().connect_test_channel_to_target(
                                            self.channel,
                                            Target::try_from(pos as u8).unwrap(),
                                        )
                                    },
                                ){
                                    Ok(_) => function(self, target_info, tss.get_position()),
                                    Err(err) => match err {
                                        retry::Error::Operation { error, ..} => {
                                            log::error!(
                                                "Failed to connect testchannel {:?} to target {:?}: {}\nCaused by: {:?}",
                                                self.channel,
                                                Target::try_from(pos as u8).unwrap(),
                                                error,
                                                error.source()
                                            );
                                            // At this point it is uncertain in which state the busswitches are. Therefore we try to disconnect all affected switches, so any remaining operations are not influenced by this error.
                                            // If disconnecting fails the testrack hardware is in an undefined and unrecoverable state, therefore the application panics as such errors need manual power reset and are likely caused by faulty hardware
                                            tss.inner.borrow_mut().disconnect_all().expect("Failed to disconnect tss successfully, this error cannot be recovered, as further operation in such a state may influence other testchannels.\n This is likely caused by a hardware issue in the I2C communication, please verify that your hardware is working correctly.");
                                        },
                                        retry::Error::Internal(string) => panic!("Internal library error in retry crate: {}", string),
                                    },
                                }
                            }
                        }
                    }
                    drop(tss);
                    unprocessed_tss_queue.remove(0);
                }
                Err(std::sync::TryLockError::WouldBlock) => {
                    // If the lock is currently held by another testchannel (eg. the tss is currently connected to another testchannel), it is skipped and reinserted at the end of the queue
                    let removed = unprocessed_tss_queue.remove(0);
                    unprocessed_tss_queue.push(removed);
                }
                Err(std::sync::TryLockError::Poisoned(err)) => {
                    panic!("Mutex is poisoned! \n{}", err)
                }
            }
        }
    }
pub fn connect_all_available_and_execute < F > ( & mut self , tss : & [ Mutex < TargetStackShield > ] , mut function : F ) where F : FnMut ( & mut Self , & TargetInfo , u8 ) { let mut unprocessed_tss_queue : Vec < & Mutex < TargetStackShield > > = tss . iter ( ) . collect ( ) ; while ! unprocessed_tss_queue . is_empty ( ) { match unprocessed_tss_queue [ 0 ] . try_lock ( ) { Ok ( tss ) => { log :: trace ! ( " " self get_channel ( ) tss get_position ( ) ) ; if let Some ( targets ) = tss . get_targets ( ) { for ( pos , target ) in targets . iter ( ) . enumerate ( ) { if let TargetState :: Known ( ref target_info ) = target { match retry ( Fixed :: from_millis ( FIXED_RETRY_DELAY_MS ) . take ( CONNECT_RETRY_LIMIT ) , | | { tss . inner . borrow_mut ( ) . connect_test_channel_to_target ( self . channel , Target :: try_from ( pos as u8 ) . unwrap ( ) , ) } , ) { Ok ( _ ) => function ( self , target_info , tss . get_position ( ) ) , Err ( err ) => match err { retry :: Error :: Operation { error , .. } => { log :: error ! ( " \n " self channel Target try_from ( pos as u8 ) unwrap ( ) error error source ( ) ) ; // At this point it is uncertain in which state the busswitches are. Therefore we try to disconnect all affected switches, so any remaining operations are not influenced by this error. // If disconnecting fails the testrack hardware is in an undefined and unrecoverable state, therefore the application panics as such errors need manual power reset and are likely caused by faulty hardware tss . inner . borrow_mut ( ) . disconnect_all ( ) . expect ( " \n " ) ; } , retry :: Error :: Internal ( string ) => panic ! ( " " string ) , } , } } } } drop ( tss ) ; unprocessed_tss_queue . remove ( 0 ) ; } Err ( std :: sync :: TryLockError :: WouldBlock ) => { // If the lock is currently held by another testchannel (eg. the tss is currently connected to another testchannel), it is skipped and reinserted at the end of the queue let removed = unprocessed_tss_queue . remove ( 0 ) ; unprocessed_tss_queue . push ( removed ) ; } Err ( std :: sync :: TryLockError :: Poisoned ( err ) ) => { panic ! ( " \n " err ) } } } }
Loops through all available TSS and connects the testchannel to each available target, while executing the provided function on each connection.
Loops through all available TSS and connects the testchannel to each available target while executing the provided function on each connection .
&mut self
tss
&[Mutex<TargetStackShield>]
function
F