auto mutex release now requires an auto mutex
This commit is contained in:
113
src/ca/cac.h
113
src/ca/cac.h
@@ -74,16 +74,19 @@ public:
|
||||
void flushRequest ();
|
||||
int pendIO ( const double &timeout );
|
||||
int pendEvent ( const double &timeout );
|
||||
bool executeResponse ( tcpiiu &, caHdrLargeArray &, char *pMsgBody );
|
||||
bool executeResponse ( class callbackAutoMutex &, tcpiiu &,
|
||||
caHdrLargeArray &, char *pMsgBody );
|
||||
void ioCancel ( nciu &chan, const cacChannel::ioid &id );
|
||||
void ioShow ( const cacChannel::ioid &id, unsigned level ) const;
|
||||
|
||||
// channel routines
|
||||
void installNetworkChannel ( nciu &, netiiu *&piiu );
|
||||
bool lookupChannelAndTransferToTCP ( unsigned cid, unsigned sid,
|
||||
ca_uint16_t typeCode, arrayElementCount count,
|
||||
unsigned minorVersionNumber, const osiSockAddr &,
|
||||
const epicsTime & currentTime );
|
||||
bool lookupChannelAndTransferToTCP (
|
||||
class callbackAutoMutex & cbMutex,
|
||||
unsigned cid, unsigned sid,
|
||||
ca_uint16_t typeCode, arrayElementCount count,
|
||||
unsigned minorVersionNumber, const osiSockAddr &,
|
||||
const epicsTime & currentTime );
|
||||
void uninstallChannel ( nciu & );
|
||||
cacChannel & createChannel ( const char *name_str,
|
||||
cacChannelNotify &chan, cacChannel::priLev pri );
|
||||
@@ -135,14 +138,14 @@ public:
|
||||
epicsMutex & mutexRef ();
|
||||
void attachToClientCtx ();
|
||||
void selfTest () const;
|
||||
void notifyNewFD ( SOCKET ) const;
|
||||
void notifyDestroyFD ( SOCKET ) const;
|
||||
void notifyNewFD ( class callbackAutoMutex &, SOCKET ) const;
|
||||
void notifyDestroyFD ( class callbackAutoMutex &, SOCKET ) const;
|
||||
void uninstallIIU ( tcpiiu &iiu );
|
||||
bool preemptiveCallbakIsEnabled () const;
|
||||
double beaconPeriod ( const nciu & chan ) const;
|
||||
void udpWakeup ();
|
||||
static unsigned lowestPriorityLevelAbove ( unsigned priority );
|
||||
static unsigned highestPriorityLevelBelow ( unsigned priority );
|
||||
void tcpCircuitShutdown ( tcpiiu &, bool discardMessages );
|
||||
|
||||
private:
|
||||
ipAddrToAsciiEngine ipToAEngine;
|
||||
@@ -168,6 +171,9 @@ private:
|
||||
freeListSubscription;
|
||||
epicsTime programBeginTime;
|
||||
double connTMO;
|
||||
// **** lock hierarchy ****
|
||||
// callback lock must always be acquired before
|
||||
// the primary mutex if both locks are needed
|
||||
mutable epicsMutex mutex;
|
||||
epicsMutex callbackMutex;
|
||||
epicsEvent ioDone;
|
||||
@@ -190,21 +196,24 @@ private:
|
||||
unsigned readSeq;
|
||||
unsigned recvThreadsPendingCount;
|
||||
|
||||
void privateUninstallIIU ( tcpiiu &iiu );
|
||||
void privateUninstallIIU ( class callbackAutoMutex &, tcpiiu &iiu );
|
||||
void flushRequestPrivate ();
|
||||
void run ();
|
||||
bool setupUDP ();
|
||||
void connectAllIO ( nciu &chan );
|
||||
void disconnectAllIO ( nciu &chan, bool enableCallbacks );
|
||||
void ioCancelPrivate ( nciu &chan, const cacChannel::ioid &id );
|
||||
void disconnectAllIO ( epicsAutoMutex &locker, nciu &chan, bool enableCallbacks );
|
||||
void flushIfRequired ( netiiu & );
|
||||
void recycleReadNotifyIO ( netReadNotifyIO &io );
|
||||
void recycleWriteNotifyIO ( netWriteNotifyIO &io );
|
||||
void recycleSubscription ( netSubscription &io );
|
||||
void preemptiveCallbackLock ();
|
||||
void preemptiveCallbackUnlock ();
|
||||
void removeAllChan ( netiiu & srcIIU, netiiu * pDstIIU = 0 );
|
||||
void disconnectChannelPrivate ( nciu & chan, netiiu *pDstIIU );
|
||||
void removeAllChan (
|
||||
callbackAutoMutex & cbLocker, epicsAutoMutex &locker,
|
||||
netiiu & srcIIU, netiiu & dstIIU );
|
||||
void disconnectChannelPrivate (
|
||||
class callbackAutoMutex &, epicsAutoMutex &,
|
||||
nciu & chan, netiiu & dstIIU );
|
||||
|
||||
void ioCompletionNotify ( unsigned id, unsigned type,
|
||||
arrayElementCount count, const void *pData );
|
||||
@@ -222,42 +231,56 @@ private:
|
||||
int status, const char *pContext, unsigned type, arrayElementCount count );
|
||||
|
||||
// recv protocol stubs
|
||||
bool noopAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool echoRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool writeNotifyRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool readNotifyRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool eventRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool readRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool clearChannelRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool exceptionRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool accessRightsRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool claimCIURespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool verifyAndDisconnectChan ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool badTCPRespAction ( tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool noopAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool echoRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool writeNotifyRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool readNotifyRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool eventRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool readRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool clearChannelRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool exceptionRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool accessRightsRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool claimCIURespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool verifyAndDisconnectChan ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
bool badTCPRespAction ( callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
typedef bool ( cac::*pProtoStubTCP ) (
|
||||
tcpiiu &, const caHdrLargeArray &, void *pMsgBdy );
|
||||
callbackAutoMutex &, tcpiiu &,
|
||||
const caHdrLargeArray &, void *pMsgBdy );
|
||||
static const pProtoStubTCP tcpJumpTableCAC [];
|
||||
|
||||
bool defaultExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool defaultExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool eventAddExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool eventAddExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool readExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool readExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool writeExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool writeExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool clearChanExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool clearChanExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool readNotifyExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool readNotifyExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
bool writeNotifyExcep ( tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
bool writeNotifyExcep ( callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
typedef bool ( cac::*pExcepProtoStubTCP ) (
|
||||
tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
callbackAutoMutex &, tcpiiu &iiu, const caHdrLargeArray &hdr,
|
||||
const char *pCtx, unsigned status );
|
||||
static const pExcepProtoStubTCP tcpExcepJumpTableCAC [];
|
||||
|
||||
friend class callbackAutoMutex;
|
||||
friend class callbackAutoMutexRelease;
|
||||
|
||||
cac ( const cac & );
|
||||
cac & operator = ( const cac & );
|
||||
@@ -271,6 +294,17 @@ private:
|
||||
cac & ctx;
|
||||
callbackAutoMutex ( const callbackAutoMutex & );
|
||||
callbackAutoMutex & operator = ( const callbackAutoMutex & );
|
||||
friend class callbackAutoMutexRelease;
|
||||
};
|
||||
|
||||
class callbackAutoMutexRelease {
|
||||
public:
|
||||
callbackAutoMutexRelease ( callbackAutoMutex & autoMutexIn );
|
||||
~callbackAutoMutexRelease ();
|
||||
private:
|
||||
callbackAutoMutex & autoMutex;
|
||||
callbackAutoMutexRelease ( const callbackAutoMutexRelease & );
|
||||
callbackAutoMutexRelease & operator = ( const callbackAutoMutexRelease & );
|
||||
};
|
||||
|
||||
inline const char * cac::userNamePointer () const
|
||||
@@ -364,5 +398,16 @@ inline callbackAutoMutex::~callbackAutoMutex ()
|
||||
this->ctx.preemptiveCallbackUnlock ();
|
||||
}
|
||||
|
||||
inline callbackAutoMutexRelease::callbackAutoMutexRelease ( callbackAutoMutex & autoMutexIn ) :
|
||||
autoMutex ( autoMutexIn )
|
||||
{
|
||||
this->autoMutex.ctx.preemptiveCallbackUnlock ();
|
||||
}
|
||||
|
||||
inline callbackAutoMutexRelease::~callbackAutoMutexRelease ()
|
||||
{
|
||||
this->autoMutex.ctx.preemptiveCallbackLock ();
|
||||
}
|
||||
|
||||
#endif // ifdef cach
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ bool netiiu::isVirtualCircuit ( const char *, const osiSockAddr & ) const
|
||||
return false;
|
||||
}
|
||||
|
||||
void netiiu::lastChannelDetachNotify ()
|
||||
void netiiu::lastChannelDetachNotify ( class callbackAutoMutex & /* cbLocker */ )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ public:
|
||||
bool searchMsg ( unsigned short retrySeqNumber, unsigned &retryNoForThisChannel );
|
||||
void resetChannelRetryCounts ();
|
||||
void attachChannel ( nciu &chan );
|
||||
void detachChannel ( nciu &chan );
|
||||
void detachChannel ( class callbackAutoMutex & cbLocker, nciu &chan );
|
||||
nciu * firstChannel ();
|
||||
int printf ( const char *pformat, ... );
|
||||
virtual void hostName (char *pBuf, unsigned bufLength) const;
|
||||
@@ -64,7 +64,7 @@ protected:
|
||||
private:
|
||||
tsDLList < nciu > channelList;
|
||||
cac *pClientCtx;
|
||||
virtual void lastChannelDetachNotify ();
|
||||
virtual void lastChannelDetachNotify ( class callbackAutoMutex & cbLocker );
|
||||
netiiu ( const netiiu & );
|
||||
netiiu & operator = ( const netiiu & );
|
||||
};
|
||||
@@ -96,11 +96,12 @@ inline void netiiu::attachChannel ( class nciu &chan )
|
||||
}
|
||||
|
||||
// cac lock must also be applied when calling this
|
||||
inline void netiiu::detachChannel ( class nciu & chan )
|
||||
inline void netiiu::detachChannel (
|
||||
class callbackAutoMutex & cbLocker, class nciu & chan )
|
||||
{
|
||||
this->channelList.remove ( chan );
|
||||
if ( this->channelList.count () == 0u ) {
|
||||
this->lastChannelDetachNotify ();
|
||||
this->lastChannelDetachNotify ( cbLocker );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,31 +67,38 @@ void searchTimer::resetPeriod ( double delayToNextTry )
|
||||
{
|
||||
bool start;
|
||||
|
||||
// upper bound
|
||||
double newPeriod = this->roundTripDelayEstimate * 2.0;
|
||||
if ( newPeriod > initialRoundTripEstimate * 2.0 ) {
|
||||
newPeriod = initialRoundTripEstimate * 2.0;
|
||||
}
|
||||
// lower bound
|
||||
if ( newPeriod < minSearchPeriod ) {
|
||||
newPeriod = minSearchPeriod;
|
||||
}
|
||||
|
||||
this->retry = 0;
|
||||
if ( this->iiu.channelCount() > 0 ) {
|
||||
if ( ! this->active ) {
|
||||
this->active = true;
|
||||
this->noDelay = ( delayToNextTry == 0.0 );
|
||||
start = true;
|
||||
{
|
||||
epicsAutoMutex locker ( this->mutex );
|
||||
|
||||
// upper bound
|
||||
double newPeriod = this->roundTripDelayEstimate * 2.0;
|
||||
if ( newPeriod > initialRoundTripEstimate * 2.0 ) {
|
||||
newPeriod = initialRoundTripEstimate * 2.0;
|
||||
}
|
||||
else if ( this->period > newPeriod ) {
|
||||
double delay = this->timer.getExpireDelay();
|
||||
if ( delay > newPeriod ) {
|
||||
// lower bound
|
||||
if ( newPeriod < minSearchPeriod ) {
|
||||
newPeriod = minSearchPeriod;
|
||||
}
|
||||
|
||||
this->retry = 0;
|
||||
if ( this->iiu.channelCount() > 0 ) {
|
||||
if ( ! this->active ) {
|
||||
this->active = true;
|
||||
this->noDelay = ( delayToNextTry == 0.0 );
|
||||
delayToNextTry = newPeriod;
|
||||
start = true;
|
||||
}
|
||||
else if ( this->period > newPeriod ) {
|
||||
double delay = this->timer.getExpireDelay();
|
||||
if ( delay > newPeriod ) {
|
||||
this->active = true;
|
||||
this->noDelay = ( delayToNextTry == 0.0 );
|
||||
delayToNextTry = newPeriod;
|
||||
start = true;
|
||||
}
|
||||
else {
|
||||
start = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
start = false;
|
||||
}
|
||||
@@ -99,15 +106,11 @@ void searchTimer::resetPeriod ( double delayToNextTry )
|
||||
else {
|
||||
start = false;
|
||||
}
|
||||
}
|
||||
else {
|
||||
start = false;
|
||||
}
|
||||
|
||||
this->period = newPeriod;
|
||||
this->period = newPeriod;
|
||||
}
|
||||
|
||||
if ( start ) {
|
||||
epicsAutoMutexRelease autoRelease ( this->mutex );
|
||||
this->timer.start ( *this, delayToNextTry );
|
||||
// debugPrintf ( ("rescheduled search timer for completion in %f sec\n", delayToNextTry) );
|
||||
}
|
||||
@@ -115,6 +118,7 @@ void searchTimer::resetPeriod ( double delayToNextTry )
|
||||
|
||||
/*
|
||||
* searchTimer::setRetryInterval ()
|
||||
* (lock must be applied)
|
||||
*/
|
||||
void searchTimer::setRetryInterval ( unsigned retryNo )
|
||||
{
|
||||
@@ -152,35 +156,38 @@ void searchTimer::notifySearchResponse ( unsigned short retrySeqNoIn,
|
||||
{
|
||||
bool reschedualNeeded;
|
||||
|
||||
if ( this->retrySeqAtPassBegin <= retrySeqNoIn ) {
|
||||
if ( this->searchResponses < UINT_MAX ) {
|
||||
this->searchResponses++;
|
||||
{
|
||||
epicsAutoMutex locker ( this->mutex );
|
||||
|
||||
if ( this->retrySeqAtPassBegin <= retrySeqNoIn ) {
|
||||
if ( this->searchResponses < UINT_MAX ) {
|
||||
this->searchResponses++;
|
||||
}
|
||||
}
|
||||
|
||||
if ( retrySeqNoIn == this->retrySeqNo && ! this->noDelay ) {
|
||||
double curRTT = currentTime - this->timeAtLastRetry;
|
||||
this->roundTripDelayEstimate =
|
||||
( this->roundTripDelayEstimate + curRTT ) / 2.0;
|
||||
this->period = this->roundTripDelayEstimate * 2.0;
|
||||
this->period = tsMin ( maxSearchPeriod, this->period );
|
||||
this->period = tsMax ( minSearchPeriod, this->period );
|
||||
reschedualNeeded = true;
|
||||
this->active = true;
|
||||
this->noDelay = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( retrySeqNoIn == this->retrySeqNo && ! this->noDelay ) {
|
||||
double curRTT = currentTime - this->timeAtLastRetry;
|
||||
this->roundTripDelayEstimate =
|
||||
( this->roundTripDelayEstimate + curRTT ) / 2.0;
|
||||
this->period = this->roundTripDelayEstimate * 2.0;
|
||||
this->period = tsMin ( maxSearchPeriod, this->period );
|
||||
this->period = tsMax ( minSearchPeriod, this->period );
|
||||
reschedualNeeded = true;
|
||||
this->active = true;
|
||||
this->noDelay = true;
|
||||
}
|
||||
|
||||
if ( this->searchResponses == this->searchAttempts ) {
|
||||
reschedualNeeded = true;
|
||||
this->active = true;
|
||||
this->noDelay = true;
|
||||
}
|
||||
else {
|
||||
reschedualNeeded = false;
|
||||
if ( this->searchResponses == this->searchAttempts ) {
|
||||
reschedualNeeded = true;
|
||||
this->active = true;
|
||||
this->noDelay = true;
|
||||
}
|
||||
else {
|
||||
reschedualNeeded = false;
|
||||
}
|
||||
}
|
||||
|
||||
if ( reschedualNeeded ) {
|
||||
epicsAutoMutexRelease autoRelease (this->mutex );
|
||||
# if defined(DEBUG) && 0
|
||||
char buf[64];
|
||||
epicsTime ts = epicsTime::getCurrent();
|
||||
|
||||
@@ -52,7 +52,7 @@ const udpiiu::pProtoStubUDP udpiiu::udpJumpTableCAC [] =
|
||||
//
|
||||
// udpiiu::udpiiu ()
|
||||
//
|
||||
udpiiu::udpiiu ( cac &cac ) :
|
||||
udpiiu::udpiiu ( callbackAutoMutex &cbLocker, cac & cac ) :
|
||||
netiiu ( &cac ), shutdownCmd ( false ),
|
||||
sockCloseCompleted ( false )
|
||||
{
|
||||
@@ -173,13 +173,7 @@ udpiiu::udpiiu ( cac &cac ) :
|
||||
|
||||
caStartRepeaterIfNotInstalled ( this->repeaterPort );
|
||||
|
||||
// no callback lock required since this is
|
||||
// always called by the user thread - its
|
||||
// better to call this here from the user
|
||||
// thread so the udp recv thread does not
|
||||
// block to do this when there is data in
|
||||
// the udp input queue
|
||||
this->pCAC()->notifyNewFD ( this->sock );
|
||||
this->pCAC ()->notifyNewFD ( cbLocker, this->sock );
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -263,8 +257,8 @@ void udpiiu::recvMsg ()
|
||||
SOCKERRSTR (errnoCpy) );
|
||||
}
|
||||
else if ( status > 0 ) {
|
||||
this->postMsg ( src, this->recvBuf, (arrayElementCount) status,
|
||||
epicsTime::getCurrent() );
|
||||
this->postMsg ( autoMutex, src, this->recvBuf,
|
||||
(arrayElementCount) status, epicsTime::getCurrent() );
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -280,10 +274,6 @@ extern "C" void cacRecvThreadUDP ( void *pParam )
|
||||
do {
|
||||
piiu->recvMsg ();
|
||||
} while ( ! piiu->shutdownCmd );
|
||||
{
|
||||
callbackAutoMutex autoMutex ( *piiu->pCAC() );
|
||||
piiu->pCAC()->notifyDestroyFD ( piiu->sock );
|
||||
}
|
||||
epicsEventSignal ( piiu->recvThreadExitSignal );
|
||||
}
|
||||
|
||||
@@ -502,7 +492,7 @@ void udpiiu::shutdown ()
|
||||
epicsEventMustWait ( this->recvThreadExitSignal );
|
||||
}
|
||||
|
||||
bool udpiiu::badUDPRespAction ( const caHdr &msg,
|
||||
bool udpiiu::badUDPRespAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &netAddr, const epicsTime ¤tTime )
|
||||
{
|
||||
char buf[64];
|
||||
@@ -514,12 +504,14 @@ bool udpiiu::badUDPRespAction ( const caHdr &msg,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool udpiiu::noopAction ( const caHdr &, const osiSockAddr &, const epicsTime & )
|
||||
bool udpiiu::noopAction ( callbackAutoMutex &,
|
||||
const caHdr &, const osiSockAddr &, const epicsTime & )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpiiu::searchRespAction ( const caHdr &msg, // X aCC 361
|
||||
bool udpiiu::searchRespAction ( callbackAutoMutex & cbLocker,
|
||||
const caHdr &msg, // X aCC 361
|
||||
const osiSockAddr &addr, const epicsTime ¤tTime )
|
||||
{
|
||||
osiSockAddr serverAddr;
|
||||
@@ -572,17 +564,17 @@ bool udpiiu::searchRespAction ( const caHdr &msg, // X aCC 361
|
||||
|
||||
if ( CA_V42 ( minorVersion ) ) {
|
||||
return this->pCAC ()->lookupChannelAndTransferToTCP
|
||||
( msg.m_available, msg.m_cid, 0xffff,
|
||||
( cbLocker, msg.m_available, msg.m_cid, 0xffff,
|
||||
0, minorVersion, serverAddr, currentTime );
|
||||
}
|
||||
else {
|
||||
return this->pCAC ()->lookupChannelAndTransferToTCP
|
||||
( msg.m_available, msg.m_cid, msg.m_dataType,
|
||||
( cbLocker, msg.m_available, msg.m_cid, msg.m_dataType,
|
||||
msg.m_count, minorVersion, serverAddr, currentTime );
|
||||
}
|
||||
}
|
||||
|
||||
bool udpiiu::beaconAction ( const caHdr &msg,
|
||||
bool udpiiu::beaconAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &net_addr, const epicsTime ¤tTime )
|
||||
{
|
||||
struct sockaddr_in ina;
|
||||
@@ -626,20 +618,20 @@ bool udpiiu::beaconAction ( const caHdr &msg,
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpiiu::repeaterAckAction ( const caHdr &,
|
||||
bool udpiiu::repeaterAckAction ( callbackAutoMutex &, const caHdr &,
|
||||
const osiSockAddr &, const epicsTime &)
|
||||
{
|
||||
this->pCAC ()->repeaterSubscribeConfirmNotify ();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpiiu::notHereRespAction ( const caHdr &,
|
||||
bool udpiiu::notHereRespAction ( callbackAutoMutex &, const caHdr &,
|
||||
const osiSockAddr &, const epicsTime & )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool udpiiu::exceptionRespAction ( const caHdr &msg,
|
||||
bool udpiiu::exceptionRespAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &net_addr, const epicsTime ¤tTime )
|
||||
{
|
||||
const caHdr &reqMsg = * ( &msg + 1 );
|
||||
@@ -661,7 +653,8 @@ bool udpiiu::exceptionRespAction ( const caHdr &msg,
|
||||
return true;
|
||||
}
|
||||
|
||||
void udpiiu::postMsg ( const osiSockAddr & net_addr,
|
||||
void udpiiu::postMsg ( callbackAutoMutex & cbLocker,
|
||||
const osiSockAddr & net_addr,
|
||||
char * pInBuf, arrayElementCount blockSize,
|
||||
const epicsTime & currentTime )
|
||||
{
|
||||
@@ -724,7 +717,7 @@ void udpiiu::postMsg ( const osiSockAddr & net_addr,
|
||||
else {
|
||||
pStub = &udpiiu::badUDPRespAction;
|
||||
}
|
||||
bool success = ( this->*pStub ) ( *pCurMsg, net_addr, currentTime );
|
||||
bool success = ( this->*pStub ) ( cbLocker, *pCurMsg, net_addr, currentTime );
|
||||
if ( ! success ) {
|
||||
char buf[256];
|
||||
sockAddrToDottedIP ( &net_addr.sa, buf, sizeof ( buf ) );
|
||||
|
||||
@@ -43,11 +43,11 @@ class epicsTime;
|
||||
|
||||
class udpiiu : public netiiu {
|
||||
public:
|
||||
udpiiu ( class cac & );
|
||||
udpiiu ( callbackAutoMutex &, class cac & );
|
||||
virtual ~udpiiu ();
|
||||
void shutdown ();
|
||||
void recvMsg ();
|
||||
void postMsg ( const osiSockAddr & net_addr,
|
||||
void postMsg ( callbackAutoMutex &, const osiSockAddr & net_addr,
|
||||
char *pInBuf, arrayElementCount blockSize,
|
||||
const epicsTime ¤Time );
|
||||
void repeaterRegistrationMessage ( unsigned attemptNumber );
|
||||
@@ -76,26 +76,27 @@ private:
|
||||
|
||||
bool pushDatagramMsg ( const caHdr &msg, const void *pExt, ca_uint16_t extsize );
|
||||
|
||||
typedef bool ( udpiiu::*pProtoStubUDP ) ( const caHdr &,
|
||||
typedef bool ( udpiiu::*pProtoStubUDP ) (
|
||||
callbackAutoMutex &, const caHdr &,
|
||||
const osiSockAddr &, const epicsTime & );
|
||||
|
||||
// UDP protocol dispatch table
|
||||
static const pProtoStubUDP udpJumpTableCAC[];
|
||||
|
||||
// UDP protocol stubs
|
||||
bool noopAction ( const caHdr &,
|
||||
bool noopAction ( callbackAutoMutex &, const caHdr &,
|
||||
const osiSockAddr &, const epicsTime & );
|
||||
bool badUDPRespAction ( const caHdr &msg,
|
||||
bool badUDPRespAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &netAddr, const epicsTime & );
|
||||
bool searchRespAction ( const caHdr &msg,
|
||||
bool searchRespAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &net_addr, const epicsTime & );
|
||||
bool exceptionRespAction ( const caHdr &msg,
|
||||
bool exceptionRespAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &net_addr, const epicsTime & );
|
||||
bool beaconAction ( const caHdr &msg,
|
||||
bool beaconAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &net_addr, const epicsTime & );
|
||||
bool notHereRespAction ( const caHdr &msg,
|
||||
bool notHereRespAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &net_addr, const epicsTime & );
|
||||
bool repeaterAckAction ( const caHdr &msg,
|
||||
bool repeaterAckAction ( callbackAutoMutex &, const caHdr &msg,
|
||||
const osiSockAddr &net_addr, const epicsTime & );
|
||||
|
||||
friend void cacRecvThreadUDP ( void *pParam );
|
||||
|
||||
@@ -57,17 +57,18 @@ public:
|
||||
unsigned minorVersion, ipAddrToAsciiEngine & engineIn,
|
||||
const cacChannel::priLev & priorityIn );
|
||||
~tcpiiu ();
|
||||
bool start ();
|
||||
bool start ( class callbackAutoMutex & );
|
||||
void cleanShutdown ();
|
||||
void forcedShutdown ();
|
||||
void shutdown ( class callbackAutoMutex & cbLocker, bool discardPendingMessages );
|
||||
void beaconAnomalyNotify ();
|
||||
void beaconArrivalNotify ();
|
||||
void forcedShutdown ();
|
||||
|
||||
void flushRequest ();
|
||||
bool flushBlockThreshold () const;
|
||||
void flushRequestIfAboveEarlyThreshold ();
|
||||
void blockUntilSendBacklogIsReasonable
|
||||
( epicsMutex * pCallBack, epicsMutex & primary );
|
||||
( epicsAutoMutex * pCallBackLocker, epicsAutoMutex & primaryLocker );
|
||||
virtual void show ( unsigned level ) const;
|
||||
bool setEchoRequestPending ();
|
||||
void requestRecvProcessPostponedFlush ();
|
||||
@@ -113,12 +114,11 @@ private:
|
||||
bool earlyFlush;
|
||||
bool recvProcessPostponedFlush;
|
||||
|
||||
void shutdown ( bool discardPendingMessages );
|
||||
void stopThreads ();
|
||||
bool processIncoming ();
|
||||
bool processIncoming ( callbackAutoMutex & );
|
||||
unsigned sendBytes ( const void *pBuf, unsigned nBytesInBuf );
|
||||
unsigned recvBytes ( void *pBuf, unsigned nBytesInBuf );
|
||||
void lastChannelDetachNotify ();
|
||||
void lastChannelDetachNotify ( class callbackAutoMutex & cbLocker );
|
||||
void connect ();
|
||||
|
||||
// send protocol stubs
|
||||
|
||||
@@ -107,7 +107,7 @@ extern "C" void putNotifyCompletion ( putNotify *ppn )
|
||||
pBlocker->block.signal ();
|
||||
}
|
||||
|
||||
void dbPutNotifyBlocker::initiatePutNotify ( epicsMutex &mutex, cacWriteNotify & notify,
|
||||
void dbPutNotifyBlocker::initiatePutNotify ( epicsAutoMutex &locker, cacWriteNotify & notify,
|
||||
struct dbAddr & addr, unsigned type, unsigned long count, const void * pValue )
|
||||
{
|
||||
int status;
|
||||
@@ -129,7 +129,7 @@ void dbPutNotifyBlocker::initiatePutNotify ( epicsMutex &mutex, cacWriteNotify &
|
||||
beginTimeInit = true;
|
||||
}
|
||||
{
|
||||
epicsAutoMutexRelease autoRelease ( mutex );
|
||||
epicsAutoMutexRelease autoRelease ( locker );
|
||||
this->block.wait ( 1.0 );
|
||||
}
|
||||
}
|
||||
@@ -161,7 +161,7 @@ void dbPutNotifyBlocker::initiatePutNotify ( epicsMutex &mutex, cacWriteNotify &
|
||||
memset ( &this->pn, '\0', sizeof ( this->pn ) );
|
||||
this->pNotify = 0;
|
||||
{
|
||||
epicsAutoMutexRelease autoRelease ( mutex );
|
||||
epicsAutoMutexRelease autoRelease ( locker );
|
||||
notify.exception (
|
||||
ECA_PUTFAIL, "dbPutNotify() returned failure",
|
||||
static_cast <unsigned> (this->pn.dbrType),
|
||||
|
||||
Reference in New Issue
Block a user