diff --git a/src/cas/example/directoryService/directoryServer.cc b/src/cas/example/directoryService/directoryServer.cc index b6282326a..984a0a7d3 100644 --- a/src/cas/example/directoryService/directoryServer.cc +++ b/src/cas/example/directoryService/directoryServer.cc @@ -81,11 +81,22 @@ void directoryServer::installAliasName(const pvInfo &info, const char *pAliasNam info.getName(), pAliasName); } +// +// More advanced pvExistTest() isnt needed so we forward to +// original version. This avoids sun pro warnings and speeds +// up execution. +// +pvExistReturn directoryServer::pvExistTest + ( const casCtx & ctx, const caNetAddr &, const char * pPVName ) +{ + return this->pvExistTest ( ctx, pPVName ); +} + // // directoryServer::pvExistTest() // pvExistReturn directoryServer::pvExistTest - ( const casCtx &, const caNetAddr &, const char * pPVName ) + ( const casCtx & ctx, const char * pPVName ) { // // lifetime of id is shorter than lifetime of pName @@ -138,15 +149,6 @@ pvExistReturn directoryServer::pvExistTest return pvExistReturn (caNetAddr(pPVE->getInfo().getAddr())); } -// -// Override fallback for pvExistTest() -// -pvExistReturn directoryServer::pvExistTest - ( const casCtx & ctx, const char * pPVName ) -{ - caNetAddr addr; - return pvExistTest (ctx, addr, pPVName); -} // // directoryServer::show() diff --git a/src/cas/generic/casChannel.cc b/src/cas/generic/casChannel.cc index 07b77f98a..3e16e243d 100644 --- a/src/cas/generic/casChannel.cc +++ b/src/cas/generic/casChannel.cc @@ -27,7 +27,7 @@ casChannel::casChannel ( const casCtx & /* ctx */ ) : casChannel::~casChannel () { if ( this->pChanI ) { - this->pChanI->casChannelDestroyFromInterfaceNotify ( true ); + this->pChanI->casChannelDestroyFromInterfaceNotify (); } } diff --git a/src/cas/generic/casChannelI.cc b/src/cas/generic/casChannelI.cc index 5104ae2a6..1c28a3874 100644 --- a/src/cas/generic/casChannelI.cc +++ b/src/cas/generic/casChannelI.cc @@ -19,17 +19,14 @@ #include "casChannelI.h" #include "casAsyncIOI.h" -casChannelI::casChannelI ( - casCoreClient & clientIn, - casChannel & chanIn, - casPVI & pvIn, - ca_uint32_t cidIn ) : - chanIntfForPV ( clientIn ), - pv ( pvIn ), - chan ( chanIn ), - cid ( cidIn ), - serverDeletePending ( false ), - accessRightsEvPending ( false ) +casChannelI::casChannelI ( casCoreClient & clientIn, + casChannel & chanIn, casPVI & pvIn, ca_uint32_t cidIn ) : + privateForPV ( clientIn, *this ), + pv ( pvIn ), + chan ( chanIn ), + cid ( cidIn ), + serverDeletePending ( false ), + accessRightsEvPending ( false ) { } @@ -47,7 +44,7 @@ casChannelI::~casChannelI () void casChannelI::uninstallFromPV ( casEventSys & eventSys ) { tsDLList < casMonitor > dest; - this->removeSelfFromPV ( this->pv, dest ); + this->privateForPV.removeSelfFromPV ( this->pv, dest ); while ( casMonitor * pMon = dest.get () ) { eventSys.prepareMonitorForDestroy ( *pMon ); } @@ -58,7 +55,7 @@ void casChannelI::show ( unsigned level ) const printf ( "casChannelI: client id %u PV %s\n", this->cid, this->pv.getName() ); if ( level > 0 ) { - this->chanIntfForPV::show ( level - 1 ); + this->privateForPV.show ( level - 1 ); this->chan.show ( level - 1 ); } } @@ -70,7 +67,7 @@ caStatus casChannelI::cbFunc ( { caStatus stat = S_cas_success; { - stat = this->client().accessRightsResponse ( + stat = this->privateForPV.client().accessRightsResponse ( clientGuard, this ); } if ( stat == S_cas_success ) { @@ -100,3 +97,11 @@ caStatus casChannelI::write ( const casCtx & ctx, const gdd & value ) this->chan.endTransaction (); return status; } + +void casChannelI::postDestroyEvent () +{ + if ( ! this->serverDeletePending ) { + this->privateForPV.client().casChannelDestroyFromInterfaceNotify ( + *this, false ); + } +} diff --git a/src/cas/generic/casChannelI.h b/src/cas/generic/casChannelI.h index 8bde7ec48..e26eec8f9 100644 --- a/src/cas/generic/casChannelI.h +++ b/src/cas/generic/casChannelI.h @@ -29,12 +29,12 @@ class casAsyncIOI; class casChannelI : public tsDLNode < casChannelI >, public chronIntIdRes < casChannelI >, public casEvent, - private chanIntfForPV { + private casChannelDestroyFromPV { public: casChannelI ( casCoreClient & clientIn, casChannel & chanIn, casPVI & pvIn, ca_uint32_t cidIn ); ~casChannelI (); - void casChannelDestroyFromInterfaceNotify ( bool immediateUninstall ); + void casChannelDestroyFromInterfaceNotify (); const caResId getCID (); const caResId getSID (); void uninstallFromPV ( casEventSys & eventSys ); @@ -56,6 +56,7 @@ public: caStatus write ( const casCtx & ctx, const gdd & value ); void show ( unsigned level ) const; private: + chanIntfForPV privateForPV; tsDLList < casAsyncIOI > ioList; casPVI & pv; casChannel & chan; @@ -67,6 +68,7 @@ private: casCoreClient &, epicsGuard < casClientMutex > &, epicsGuard < evSysMutex > & ); + void postDestroyEvent (); casChannelI ( const casChannelI & ); casChannelI & operator = ( const casChannelI & ); }; @@ -88,7 +90,7 @@ inline const caResId casChannelI::getSID () inline void casChannelI::postAccessRightsEvent () { - this->client().addToEventQueue ( *this, this->accessRightsEvPending ); + this->privateForPV.client().addToEventQueue ( *this, this->accessRightsEvPending ); } inline const gddEnumStringTable & casChannelI::enumStringTable () const @@ -98,7 +100,7 @@ inline const gddEnumStringTable & casChannelI::enumStringTable () const inline void casChannelI::installIntoPV () { - this->pv.installChannel ( *this ); + this->pv.installChannel ( this->privateForPV ); } inline void casChannelI::clearOutstandingReads () @@ -137,24 +139,23 @@ inline void casChannelI::uninstallIO ( casAsyncIOI & io ) this->pv.uninstallIO ( this->ioList, io ); } -inline void casChannelI::casChannelDestroyFromInterfaceNotify ( - bool immediateUninstall ) +inline void casChannelI::casChannelDestroyFromInterfaceNotify () { if ( ! this->serverDeletePending ) { - this->client().casChannelDestroyFromInterfaceNotify ( - *this, immediateUninstall ); + this->privateForPV.client().casChannelDestroyFromInterfaceNotify ( + *this, true ); } } inline void casChannelI::installMonitor ( casMonitor & mon ) { - this->chanIntfForPV::installMonitor ( this->pv, mon ); + this->privateForPV.installMonitor ( this->pv, mon ); } inline casMonitor * casChannelI::removeMonitor ( ca_uint32_t clientIdIn ) { - return this->chanIntfForPV::removeMonitor ( this->pv, clientIdIn ); + return this->privateForPV.removeMonitor ( this->pv, clientIdIn ); } #endif // casChannelIh diff --git a/src/cas/generic/casMonitor.cc b/src/cas/generic/casMonitor.cc index cc1a2bc9a..0db4c5542 100644 --- a/src/cas/generic/casMonitor.cc +++ b/src/cas/generic/casMonitor.cc @@ -131,9 +131,9 @@ caStatus casMonitor::executeEvent ( casCoreClient & client, if ( ! this->pChannel && this->nPend == 0 ) { // we carefully avoid inverting the lock hierarchy here - epicsGuardRelease < evSysMutex > unguard ( evGuard ); + epicsGuardRelease < evSysMutex > unGuardEv ( evGuard ); { - epicsGuardRelease < casClientMutex > unguard ( clientGuard ); + epicsGuardRelease < casClientMutex > unGuardClient ( clientGuard ); client.destroyMonitor ( *this ); } } diff --git a/src/cas/generic/casPVI.cc b/src/cas/generic/casPVI.cc index c8f9b9ea2..aa756ae4b 100644 --- a/src/cas/generic/casPVI.cc +++ b/src/cas/generic/casPVI.cc @@ -70,9 +70,10 @@ void casPVI::casPVDestroyNotify () epicsGuard < epicsMutex > guard ( this->mutex ); this->pPV = 0; if ( ! this->deletePending ) { + // last channel to be destroyed destroys the casPVI tsDLIter < chanIntfForPV > iter = this->chanList.firstIter (); while ( iter.valid() ) { - iter->casChannelDestroyFromInterfaceNotify ( false ); + iter->postDestroyEvent (); iter++; } } diff --git a/src/cas/generic/chanIntfForPV.cc b/src/cas/generic/chanIntfForPV.cc index 8044fc642..4fd64fc60 100644 --- a/src/cas/generic/chanIntfForPV.cc +++ b/src/cas/generic/chanIntfForPV.cc @@ -21,8 +21,9 @@ #include "casCoreClient.h" #include "casPVI.h" -chanIntfForPV::chanIntfForPV ( class casCoreClient & clientIn ) : - clientRef ( clientIn ) +chanIntfForPV::chanIntfForPV ( class casCoreClient & clientIn, + casChannelDestroyFromPV & destroyRefIn ) : + clientRef ( clientIn ), destroyRef ( destroyRefIn ) { } diff --git a/src/cas/generic/chanIntfForPV.h b/src/cas/generic/chanIntfForPV.h index d1f2b0c0f..808f3f186 100644 --- a/src/cas/generic/chanIntfForPV.h +++ b/src/cas/generic/chanIntfForPV.h @@ -41,21 +41,27 @@ class casPVI; class casEventMask; class gdd; +class casChannelDestroyFromPV { +public: + virtual void postDestroyEvent () = 0; +}; + class chanIntfForPV : public tsDLNode < chanIntfForPV > { public: - chanIntfForPV ( class casCoreClient & ); - virtual ~chanIntfForPV (); + chanIntfForPV ( class casCoreClient &, casChannelDestroyFromPV & ); + ~chanIntfForPV (); class casCoreClient & client () const; - virtual void casChannelDestroyFromInterfaceNotify ( bool immediateUninstall ) = 0; void installMonitor ( casPVI & pv, casMonitor & mon ); casMonitor * removeMonitor ( casPVI &, ca_uint32_t monId ); void removeSelfFromPV ( casPVI &, tsDLList < casMonitor > & dest ); void postEvent ( const casEventMask &, const gdd & ); void show ( unsigned level ) const; + void postDestroyEvent (); private: tsDLList < casMonitor > monitorList; class casCoreClient & clientRef; + casChannelDestroyFromPV & destroyRef; chanIntfForPV ( const chanIntfForPV & ); chanIntfForPV & operator = ( const chanIntfForPV & ); }; @@ -78,4 +84,9 @@ inline void chanIntfForPV::removeSelfFromPV ( pv.removeChannel ( *this, this->monitorList, dest ); } +inline void chanIntfForPV::postDestroyEvent () +{ + this->destroyRef.postDestroyEvent (); +} + #endif // chanIntfForPVh diff --git a/src/makeBaseApp/top/caServerApp/exServer.cc b/src/makeBaseApp/top/caServerApp/exServer.cc index a3df1a342..4cd221444 100644 --- a/src/makeBaseApp/top/caServerApp/exServer.cc +++ b/src/makeBaseApp/top/caServerApp/exServer.cc @@ -148,11 +148,22 @@ void exServer::installAliasName(pvInfo &info, const char *pAliasName) info.getName(), pAliasName ); } +// +// More advanced pvExistTest() isnt needed so we forward to +// original version. This avoids sun pro warnings and speeds +// up execution. +// +pvExistReturn exServer::pvExistTest + ( const casCtx & ctx, const caNetAddr &, const char * pPVName ) +{ + return this->pvExistTest ( ctx, pPVName ); +} + // // exServer::pvExistTest() // pvExistReturn exServer::pvExistTest // X aCC 361 - ( const casCtx& ctxIn, const caNetAddr &, const char * pPVName ) + ( const casCtx& ctxIn, const char * pPVName ) { // // lifetime of id is shorter than lifetime of pName diff --git a/src/makeBaseApp/top/caServerApp/exServer.h b/src/makeBaseApp/top/caServerApp/exServer.h index 00fee3df1..3513a2749 100644 --- a/src/makeBaseApp/top/caServerApp/exServer.h +++ b/src/makeBaseApp/top/caServerApp/exServer.h @@ -285,7 +285,10 @@ private: void installAliasName ( pvInfo & info, const char * pAliasName ); pvExistReturn pvExistTest ( const casCtx &, const caNetAddr &, const char * pPVName ); - pvAttachReturn pvAttach ( const casCtx &, const char * pPVName ); + pvExistReturn pvExistTest ( const casCtx &, + const char * pPVName ); + pvAttachReturn pvAttach ( const casCtx &, + const char * pPVName ); // // list of pre-created PVs