From d0e047f78fff909e4351fc9dcd8ccc9f52cf5bba Mon Sep 17 00:00:00 2001 From: Jeff Hill Date: Fri, 13 Jul 2001 16:06:39 +0000 Subject: [PATCH] correct fix for thread switch problem on Linux --- src/ca/cac.cpp | 30 +++++++++++++++++++++++++----- src/ca/cac.h | 2 ++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/ca/cac.cpp b/src/ca/cac.cpp index 05d74a6c0..1f0b3f61e 100644 --- a/src/ca/cac.cpp +++ b/src/ca/cac.cpp @@ -119,6 +119,7 @@ cac::cac ( cacNotify ¬ifyIn, bool enablePreemptiveCallbackIn ) : recvProcessEnableRefCount ( 0u ), pndRecvCnt ( 0u ), readSeq ( 0u ), + recvProcessCompletionSignalRequestCount ( 0u ), enablePreemptiveCallback ( enablePreemptiveCallbackIn ), ioInProgress ( false ), recvProcessThreadExitRequest ( false ), @@ -589,6 +590,15 @@ int cac::pendEvent ( const double &timeout ) this->flushRequestPrivate (); + bool waitForSignal; + if ( this->recvProcessPending ) { + this->recvProcessCompletionSignalRequestCount++; + waitForSignal = true; + } + else { + waitForSignal = false; + } + this->enableCallbackPreemption (); { @@ -601,14 +611,19 @@ int cac::pendEvent ( const double &timeout ) else if ( timeout >= CAC_SIGNIFICANT_DELAY ) { epicsThreadSleep ( timeout ); } - while ( this->recvProcessPending ) { - // give up the processor while - // there is recv processing to be done - epicsThreadSleep ( 0.1 ); + if ( waitForSignal ) { + this->recvProcessCompleted.wait (); } } this->disableCallbackPreemption (); + + if ( waitForSignal ) { + this->recvProcessCompletionSignalRequestCount--; + if ( this->recvProcessCompletionSignalRequestCount ) { + this->recvProcessCompleted.signal (); + } + } } return ECA_TIMEOUT; @@ -689,12 +704,17 @@ void cac::run () { this->attachToClientCtx (); while ( ! this->recvProcessThreadExitRequest ) { + bool wakeupNeeded; { this->recvProcessPending = true; epicsAutoMutex autoMutexPCB ( this->preemptiveCallbackLock ); epicsAutoMutex autoMutex ( this->mutex ); this->processRecvBacklog (); this->recvProcessPending = false; + wakeupNeeded = this->recvProcessCompletionSignalRequestCount > 0u; + } + if ( wakeupNeeded ) { + this->recvProcessCompleted.signal (); } this->recvProcessActivityEvent.wait (); } @@ -874,7 +894,7 @@ bool cac::lookupChannelAndTransferToTCP ( unsigned cid, unsigned sid, } catch ( ... ) { - this->printf ( "CAC: Exception caught during virtual circuit creation\n" ); + this->printf ( "CAC: Exception during virtual circuit creation\n" ); return true; } } diff --git a/src/ca/cac.h b/src/ca/cac.h index 2acc15afa..41e956613 100644 --- a/src/ca/cac.h +++ b/src/ca/cac.h @@ -163,6 +163,7 @@ private: epicsEvent notifyCompletionEvent; epicsEvent recvProcessActivityEvent; epicsEvent recvProcessThreadExit; + epicsEvent recvProcessCompleted; epicsEvent ioDone; epicsTimerQueueActive *pTimerQueue; char *pUserName; @@ -181,6 +182,7 @@ private: unsigned recvProcessEnableRefCount; unsigned pndRecvCnt; unsigned readSeq; + unsigned recvProcessCompletionSignalRequestCount; bool enablePreemptiveCallback; bool ioInProgress; bool recvProcessThreadExitRequest;