From 77dae99fc8a34af8d4aabd97e5f80e503a261810 Mon Sep 17 00:00:00 2001 From: Jacqueline Deans Date: Wed, 10 Aug 2022 13:10:18 -0500 Subject: [PATCH] Race condition patch (#1329) * Add patch for an uncommon bug where some data recording threads hang forever --- include/trick/DataRecordDispatcher.hh | 2 ++ .../sim_services/DataRecord/DataRecordDispatcher.cpp | 10 +++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/trick/DataRecordDispatcher.hh b/include/trick/DataRecordDispatcher.hh index 7a8bc3b8..55d58932 100644 --- a/include/trick/DataRecordDispatcher.hh +++ b/include/trick/DataRecordDispatcher.hh @@ -28,6 +28,8 @@ namespace Trick { pthread_cond_t init_complete_cv; /**< trick_io(**) */ /** Data writer initialized mutex. */ pthread_mutex_t init_complete_mutex; /**< trick_io(**) */ + /** Flag to exit (instead of pthread_cancel) */ + bool cancelled; } ; class DRDWriterThread : public Trick::ThreadBase { diff --git a/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp b/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp index ea8849f9..df5533d7 100644 --- a/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp +++ b/trick_source/sim_services/DataRecord/DataRecordDispatcher.cpp @@ -29,6 +29,7 @@ Trick::DRDMutexes::DRDMutexes() { pthread_mutex_init(&dr_go_mutex, NULL); pthread_cond_init(&init_complete_cv, NULL); pthread_mutex_init(&init_complete_mutex, NULL); + cancelled = false; } Trick::DRDWriterThread::DRDWriterThread(DRDMutexes & in_mutexes, std::vector & in_groups) : @@ -48,6 +49,10 @@ void * Trick::DRDWriterThread::thread_body() { then call the write_data method for all of the groups */ while(1) { pthread_cond_wait(&(drd_mutexes.dr_go_cv), &(drd_mutexes.dr_go_mutex)); + if (drd_mutexes.cancelled) { + pthread_mutex_unlock(&(drd_mutexes.dr_go_mutex)); + pthread_exit(0); + } for ( unsigned int ii = 0 ; ii < groups.size() ; ii++ ) { if ( groups[ii]->buffer_type == Trick::DR_Buffer ) { groups[ii]->write_data(true) ; @@ -90,6 +95,7 @@ int Trick::DataRecordDispatcher::init() { pthread_mutex_lock(&drd_mutexes.init_complete_mutex); drd_writer_thread.create_thread() ; pthread_cond_wait(&drd_mutexes.init_complete_cv, &drd_mutexes.init_complete_mutex); + pthread_mutex_unlock(&drd_mutexes.init_complete_mutex); return(0) ; } @@ -239,7 +245,9 @@ int Trick::DataRecordDispatcher::shutdown() { if ( drd_writer_thread.get_pthread_id() != 0 ) { pthread_mutex_lock( &drd_mutexes.dr_go_mutex); - pthread_cancel( drd_writer_thread.get_pthread_id()) ; + // pthread_cancel( drd_writer_thread.get_pthread_id()) ; + drd_mutexes.cancelled = true; + pthread_cond_signal(&drd_mutexes.dr_go_cv); pthread_mutex_unlock( &drd_mutexes.dr_go_mutex); }