From 6ce8dfec01cdfc2b3ebd9f2a506cf92312bede47 Mon Sep 17 00:00:00 2001 From: Michael Davidsaver Date: Wed, 8 Nov 2017 10:07:55 -0600 Subject: [PATCH] libCom: timerQueueActive atomic exitFlag quiet false positive data race --- modules/libcom/src/timer/timerPrivate.h | 2 +- modules/libcom/src/timer/timerQueueActive.cpp | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/libcom/src/timer/timerPrivate.h b/modules/libcom/src/timer/timerPrivate.h index 55291309c..259afaee6 100644 --- a/modules/libcom/src/timer/timerPrivate.h +++ b/modules/libcom/src/timer/timerPrivate.h @@ -147,7 +147,7 @@ private: epicsThread thread; const double sleepQuantum; bool okToShare; - bool exitFlag; + int exitFlag; // use atomic ops bool terminateFlag; void run (); void reschedule (); diff --git a/modules/libcom/src/timer/timerQueueActive.cpp b/modules/libcom/src/timer/timerQueueActive.cpp index 5d8b72951..4db68c00c 100644 --- a/modules/libcom/src/timer/timerQueueActive.cpp +++ b/modules/libcom/src/timer/timerQueueActive.cpp @@ -15,6 +15,7 @@ #include #define epicsExportSharedSymbols +#include "epicsAtomic.h" #include "timerPrivate.h" #include "errlog.h" @@ -46,7 +47,7 @@ timerQueueActive :: _refMgr ( refMgr ), queue ( *this ), thread ( *this, "timerQueue", epicsThreadGetStackSize ( epicsThreadStackMedium ), priority ), sleepQuantum ( epicsThreadSleepQuantum() ), okToShare ( okToShareIn ), - exitFlag ( false ), terminateFlag ( false ) + exitFlag ( 0 ), terminateFlag ( false ) { } @@ -59,7 +60,7 @@ timerQueueActive::~timerQueueActive () { this->terminateFlag = true; this->rescheduleEvent.signal (); - while ( ! this->exitFlag ) { + while ( ! epics::atomic::get(this->exitFlag) ) { this->exitEvent.wait ( 1.0 ); } // in case other threads are waiting here also @@ -87,7 +88,7 @@ void timerQueueActive :: _printLastChanceExceptionMessage ( void timerQueueActive :: run () { - this->exitFlag = false; + epics::atomic::set(this->exitFlag, 0); while ( ! this->terminateFlag ) { try { double delay = this->queue.process ( epicsTime::getCurrent() ); @@ -105,7 +106,7 @@ void timerQueueActive :: run () epicsThreadSleep ( 10.0 ); } } - this->exitFlag = true; + epics::atomic::set(this->exitFlag, 1); this->exitEvent.signal (); // no access to queue after exitEvent signal } @@ -143,7 +144,7 @@ void timerQueueActive::show ( unsigned int level ) const printf ( "exit event\n" ); this->exitEvent.show ( level - 1u ); printf ( "exitFlag = %c, terminateFlag = %c\n", - this->exitFlag ? 'T' : 'F', + epics::atomic::get(this->exitFlag) ? 'T' : 'F', this->terminateFlag ? 'T' : 'F' ); } }