@@ -96,6 +96,9 @@ unsigned char _pgm_command = NUL;
96
96
97
97
bool _last_sent_was_cmd = false;
98
98
99
+ static pthread_mutex_t _pgm_command_mutex = PTHREAD_MUTEX_INITIALIZER ;
100
+ static pthread_cond_t _pgm_command_sent_cond = PTHREAD_COND_INITIALIZER ;
101
+
99
102
// External view of adding to queue
100
103
void aq_send_cmd (unsigned char cmd ) {
101
104
push_aq_cmd (cmd );
@@ -146,9 +149,12 @@ unsigned char pop_aq_cmd(struct aqualinkdata *aq_data)
146
149
if (in_programming_mode (aq_data ) && ( in_ot_programming_mode (aq_data ) == false && in_iaqt_programming_mode (aq_data ) == false )) {
147
150
//if (aq_data->active_thread.thread_id != 0) {
148
151
if ( _pgm_command != NUL && aq_data -> last_packet_type == CMD_STATUS ) {
152
+ pthread_mutex_lock (& _pgm_command_mutex );
149
153
cmd = _pgm_command ;
150
154
_pgm_command = NUL ;
151
155
LOG (PROG_LOG , LOG_DEBUG_SERIAL , "RS SEND cmd '0x%02hhx' (programming)\n" , cmd );
156
+ pthread_cond_signal (& _pgm_command_sent_cond );
157
+ pthread_mutex_unlock (& _pgm_command_mutex );
152
158
} else if (_pgm_command != NUL ) {
153
159
LOG (PROG_LOG , LOG_DEBUG_SERIAL , "RS Waiting to send cmd '0x%02hhx' (programming)\n" , _pgm_command );
154
160
} else {
@@ -900,39 +906,33 @@ void aq_programmer(program_type r_type, char *args, struct aqualinkdata *aq_data
900
906
901
907
void waitForSingleThreadOrTerminate (struct programmingThreadCtrl * threadCtrl , program_type type )
902
908
{
903
- //static int tries = 120;
904
- int tries = 120 ;
905
- static int waitTime = 1 ;
906
- int i = 0 ;
907
-
908
- i = 0 ;
909
- while (get_aq_cmd_length () > 0 && ( i ++ <= tries ) ) {
910
- LOG (PROG_LOG , LOG_DEBUG , "Thread %p (%s) sleeping, waiting command queue to empty\n" , & threadCtrl -> thread_id , ptypeName (type ));
911
- sleep (waitTime );
912
- }
913
- if (i >= tries ) {
914
- LOG (PROG_LOG , LOG_ERR , "Thread %p (%s) timeout waiting, ending\n" ,& threadCtrl -> thread_id ,ptypeName (type ));
915
- free (threadCtrl );
916
- pthread_exit (0 );
917
- }
909
+ int ret = 0 ;
910
+ struct timespec max_wait ;
911
+ clock_gettime (CLOCK_REALTIME , & max_wait );
912
+ max_wait .tv_sec += 30 ;
918
913
919
- while ( (threadCtrl -> aq_data -> active_thread .thread_id != 0 ) && ( i ++ <= tries ) ) {
920
- //LOG(PROG_LOG, LOG_DEBUG, "Thread %d sleeping, waiting for thread %d to finish\n", threadCtrl->thread_id, threadCtrl->aq_data->active_thread.thread_id);
921
- LOG (PROG_LOG , LOG_DEBUG , "Thread %p (%s) sleeping, waiting for thread %p (%s) to finish\n" ,
922
- & threadCtrl -> thread_id , ptypeName (type ),
923
- threadCtrl -> aq_data -> active_thread .thread_id , ptypeName (threadCtrl -> aq_data -> active_thread .ptype ));
924
- sleep (waitTime );
925
- }
926
-
927
- if (i >= tries ) {
928
- //LOG(PROG_LOG, LOG_ERR, "Thread %d timeout waiting, ending\n",threadCtrl->thread_id);
929
- LOG (PROG_LOG , LOG_ERR , "Thread %d,%p timeout waiting for thread %d,%p to finish\n" ,
930
- type , & threadCtrl -> thread_id , threadCtrl -> aq_data -> active_thread .ptype ,
931
- threadCtrl -> aq_data -> active_thread .thread_id );
932
- free (threadCtrl );
933
- pthread_exit (0 );
934
- }
935
-
914
+ pthread_mutex_lock (& threadCtrl -> aq_data -> mutex );
915
+ while (threadCtrl -> aq_data -> active_thread .thread_id != 0 )
916
+ {
917
+ LOG (PROG_LOG , LOG_DEBUG , "Thread %d,%p (%s) sleeping, waiting for thread %d,%p (%s) to finish\n" ,
918
+ type , & threadCtrl -> thread_id , ptypeName (type ),
919
+ threadCtrl -> aq_data -> active_thread .ptype , threadCtrl -> aq_data -> active_thread .thread_id , ptypeName (threadCtrl -> aq_data -> active_thread .ptype ));
920
+ if ((ret = pthread_cond_timedwait (& threadCtrl -> aq_data -> thread_finished_cond ,
921
+ & threadCtrl -> aq_data -> mutex , & max_wait )))
922
+ {
923
+ LOG (PROG_LOG , LOG_ERR , "Thread %d,%p err %s waiting for thread %d,%p to finish\n" ,
924
+ type , & threadCtrl -> thread_id , strerror (ret ),
925
+ threadCtrl -> aq_data -> active_thread .ptype ,
926
+ threadCtrl -> aq_data -> active_thread .thread_id );
927
+
928
+ if ((ret = pthread_mutex_unlock (& threadCtrl -> aq_data -> mutex )))
929
+ {
930
+ LOG (PROG_LOG , LOG_ERR , "waitForSingleThreadOrTerminate mutex unlock ret %s\n" , strerror (ret ));
931
+ }
932
+ free (threadCtrl );
933
+ pthread_exit (0 );
934
+ }
935
+ }
936
936
// Clear out any messages to the UI.
937
937
threadCtrl -> aq_data -> last_display_message [0 ] = '\0' ;
938
938
threadCtrl -> aq_data -> active_thread .thread_id = & threadCtrl -> thread_id ;
@@ -948,10 +948,12 @@ void waitForSingleThreadOrTerminate(struct programmingThreadCtrl *threadCtrl, pr
948
948
threadCtrl -> aq_data -> active_thread .ptype ,
949
949
threadCtrl -> aq_data -> active_thread .thread_id ,
950
950
ptypeName (threadCtrl -> aq_data -> active_thread .ptype ));
951
+ pthread_mutex_unlock (& threadCtrl -> aq_data -> mutex );
951
952
}
952
953
953
954
void cleanAndTerminateThread (struct programmingThreadCtrl * threadCtrl )
954
955
{
956
+ pthread_mutex_lock (& threadCtrl -> aq_data -> mutex );
955
957
#ifndef AQ_DEBUG
956
958
LOG (PROG_LOG , LOG_DEBUG , "Thread %d,%p (%s) finished\n" ,threadCtrl -> aq_data -> active_thread .ptype , threadCtrl -> thread_id ,ptypeName (threadCtrl -> aq_data -> active_thread .ptype ));
957
959
#else
@@ -965,10 +967,11 @@ void cleanAndTerminateThread(struct programmingThreadCtrl *threadCtrl)
965
967
elapsed .tv_sec , elapsed .tv_nsec / 1000000L );
966
968
#endif
967
969
968
- // Quick delay to allow for last message to be sent.
969
- delay (500 );
970
970
threadCtrl -> aq_data -> active_thread .thread_id = 0 ;
971
971
threadCtrl -> aq_data -> active_thread .ptype = AQP_NULL ;
972
+ pthread_cond_signal (& threadCtrl -> aq_data -> thread_finished_cond );
973
+ pthread_mutex_unlock (& threadCtrl -> aq_data -> mutex );
974
+
972
975
threadCtrl -> thread_id = 0 ;
973
976
// Force update, change display message
974
977
threadCtrl -> aq_data -> updated = true;
@@ -1996,14 +1999,34 @@ void longwaitfor_queue2empty()
1996
1999
_waitfor_queue2empty (true);
1997
2000
}
1998
2001
1999
- void send_cmd (unsigned char cmd )
2002
+ bool send_cmd (unsigned char cmd )
2000
2003
{
2001
- waitfor_queue2empty ();
2002
-
2003
- _pgm_command = cmd ;
2004
- //delay(200);
2004
+ bool ret = true;
2005
+ int pret = 0 ;
2006
+ struct timespec max_wait ;
2007
+
2008
+ clock_gettime (CLOCK_REALTIME , & max_wait );
2009
+ max_wait .tv_sec += 5 ;
2005
2010
2011
+ pthread_mutex_lock (& _pgm_command_mutex );
2012
+ _pgm_command = cmd ;
2006
2013
LOG (PROG_LOG , LOG_INFO , "Queue send '0x%02hhx' to controller (programming)\n" , _pgm_command );
2014
+ while (_pgm_command != NUL )
2015
+ {
2016
+ if ((pret = pthread_cond_timedwait (& _pgm_command_sent_cond ,
2017
+ & _pgm_command_mutex , & max_wait )))
2018
+ {
2019
+ LOG (PROG_LOG , LOG_ERR , "send_cmd 0x%02hhx err %s\n" ,
2020
+ cmd , strerror (pret ));
2021
+ ret = false;
2022
+ break ;
2023
+ }
2024
+ }
2025
+ if (ret ) {
2026
+ LOG (PROG_LOG , LOG_INFO , "sent '0x%02hhx' to controller\n" , _pgm_command );
2027
+ }
2028
+ pthread_mutex_unlock (& _pgm_command_mutex );
2029
+ return ret ;
2007
2030
}
2008
2031
2009
2032
/*
0 commit comments