further bullet proof the server tool initiated PV destroy
This commit is contained in:
@@ -122,11 +122,10 @@ caStatus casCoreClient::channelCreateFailedResp (
|
||||
{
|
||||
return S_casApp_noSupport;
|
||||
}
|
||||
caStatus casCoreClient::channelDestroyNotify (
|
||||
caStatus casCoreClient::channelDestroyEvent (
|
||||
epicsGuard < casClientMutex > &,
|
||||
casChannelI &, bool )
|
||||
casChannelI * const, ca_uint32_t )
|
||||
{
|
||||
assert ( 0 );
|
||||
return S_casApp_noSupport;
|
||||
}
|
||||
|
||||
|
||||
@@ -85,10 +85,10 @@ public:
|
||||
virtual caStatus channelCreateFailedResp (
|
||||
epicsGuard < casClientMutex > &,
|
||||
const caHdrLargeArray &, const caStatus createStatus );
|
||||
virtual caStatus channelDestroyNotify (
|
||||
epicsGuard < casClientMutex > &,
|
||||
casChannelI &, bool uninstallNeeded );
|
||||
virtual void casChannelDestroyNotify (
|
||||
virtual caStatus channelDestroyEvent (
|
||||
epicsGuard < casClientMutex > & guard,
|
||||
casChannelI * const pChan, ca_uint32_t sid );
|
||||
virtual void casChannelDestroyNotify (
|
||||
casChannelI & chan, bool immediateDestroyNeeded );
|
||||
|
||||
virtual ca_uint16_t protocolRevision () const = 0;
|
||||
|
||||
@@ -68,6 +68,7 @@ casPVI::~casPVI ()
|
||||
void casPVI::casPVDestroyNotify ()
|
||||
{
|
||||
epicsGuard < epicsMutex > guard ( this->mutex );
|
||||
this->pPV = 0;
|
||||
if ( ! this->deletePending ) {
|
||||
tsDLIter < chanIntfForPV > iter = this->chanList.firstIter ();
|
||||
while ( iter.valid() ) {
|
||||
|
||||
@@ -1629,6 +1629,61 @@ caStatus casStrmClient::clearChannelAction (
|
||||
return status;
|
||||
}
|
||||
|
||||
//
|
||||
// If the channel pointer is nill this indicates that
|
||||
// the existence of the channel isnt certain because
|
||||
// it is still installed and the client or the server
|
||||
// tool might have destroyed it. Therefore, we must
|
||||
// locate it using the supplied server id.
|
||||
//
|
||||
// If the channel pointer isnt nill this indicates
|
||||
// that the channel has already been uninstalled.
|
||||
//
|
||||
// In both situations we need to send a channel
|
||||
// disconnect message to the client and destroy the
|
||||
// channel.
|
||||
//
|
||||
caStatus casStrmClient::channelDestroyEvent (
|
||||
epicsGuard < casClientMutex > & guard,
|
||||
casChannelI * const pChan, ca_uint32_t sid )
|
||||
{
|
||||
casChannelI * pChanFound;
|
||||
if ( pChan ) {
|
||||
pChanFound = pChan;
|
||||
}
|
||||
else {
|
||||
chronIntId tmpId ( sid );
|
||||
pChanFound =
|
||||
this->chanTable.lookup ( tmpId );
|
||||
if ( ! pChanFound ) {
|
||||
return S_cas_success;
|
||||
}
|
||||
}
|
||||
|
||||
if ( CA_V47 ( this->minor_version_number ) ) {
|
||||
caStatus status = this->out.copyInHeader (
|
||||
CA_PROTO_SERVER_DISCONN, 0,
|
||||
0, 0, pChanFound->getCID(), 0, 0 );
|
||||
if ( status == S_cas_sendBlocked ) {
|
||||
return status;
|
||||
}
|
||||
this->out.commitMsg ();
|
||||
}
|
||||
else {
|
||||
this->forceDisconnect ();
|
||||
}
|
||||
|
||||
if ( ! pChan ) {
|
||||
this->chanTable.remove ( * pChanFound );
|
||||
this->chanList.remove ( * pChanFound );
|
||||
pChanFound->uninstallFromPV ( this->eventSys );
|
||||
}
|
||||
|
||||
delete pChanFound;
|
||||
|
||||
return S_cas_success;
|
||||
}
|
||||
|
||||
// casStrmClient::casChannelDestroyNotify()
|
||||
// immediateUninstallNeeded is false when we must avoid
|
||||
// taking the lock insituations where we would compromise
|
||||
@@ -1644,9 +1699,10 @@ void casStrmClient::casChannelDestroyNotify (
|
||||
chan.uninstallFromPV ( this->eventSys );
|
||||
}
|
||||
|
||||
channelDestroyEvent * pEvent =
|
||||
new ( std::nothrow ) channelDestroyEvent (
|
||||
chan, !immediateUninstallNeeded );
|
||||
class channelDestroyEvent * pEvent =
|
||||
new ( std::nothrow ) class channelDestroyEvent (
|
||||
immediateUninstallNeeded ? & chan : 0,
|
||||
chan.getSID() );
|
||||
if ( pEvent ) {
|
||||
this->eventSys.addToEventQueue ( *pEvent );
|
||||
}
|
||||
@@ -1658,34 +1714,6 @@ void casStrmClient::casChannelDestroyNotify (
|
||||
}
|
||||
}
|
||||
|
||||
// casStrmClient::channelDestroyNotify()
|
||||
caStatus casStrmClient::channelDestroyNotify (
|
||||
epicsGuard < casClientMutex > & guard,
|
||||
casChannelI & chan, bool uninstallNeeded )
|
||||
{
|
||||
caStatus status = S_cas_success;
|
||||
if ( CA_V47 ( this->minor_version_number ) ) {
|
||||
caStatus status = this->out.copyInHeader (
|
||||
CA_PROTO_SERVER_DISCONN, 0,
|
||||
0, 0, chan.getCID(), 0, 0 );
|
||||
if ( status == S_cas_success ) {
|
||||
this->out.commitMsg ();
|
||||
}
|
||||
}
|
||||
else {
|
||||
this->forceDisconnect ();
|
||||
}
|
||||
if ( status != S_cas_sendBlocked ) {
|
||||
if ( uninstallNeeded ) {
|
||||
this->chanTable.remove ( chan );
|
||||
this->chanList.remove ( chan );
|
||||
chan.uninstallFromPV ( this->eventSys );
|
||||
}
|
||||
delete & chan;
|
||||
}
|
||||
return status;
|
||||
}
|
||||
|
||||
// casStrmClient::eventCancelAction()
|
||||
caStatus casStrmClient::eventCancelAction (
|
||||
epicsGuard < casClientMutex > & guard )
|
||||
|
||||
@@ -127,10 +127,9 @@ private:
|
||||
casChannelI & chan, const caHdrLargeArray & hdr, unsigned dbrType );
|
||||
caStatus channelCreateFailedResp ( epicsGuard < casClientMutex > &,
|
||||
const caHdrLargeArray &, const caStatus createStatus );
|
||||
caStatus channelDestroyNotify (
|
||||
caStatus channelDestroyEvent (
|
||||
epicsGuard < casClientMutex > & guard,
|
||||
casChannelI &, bool uninstallNeeded );
|
||||
|
||||
casChannelI * const pChan, ca_uint32_t sid );
|
||||
caStatus accessRightsResponse (
|
||||
casChannelI * pciu );
|
||||
caStatus accessRightsResponse (
|
||||
|
||||
@@ -25,8 +25,8 @@ caStatus channelDestroyEvent::cbFunc (
|
||||
epicsGuard < casClientMutex > & clientGuard,
|
||||
epicsGuard < evSysMutex > & )
|
||||
{
|
||||
caStatus status = client.channelDestroyNotify (
|
||||
clientGuard, this->chan, this->uninstallNeeded );
|
||||
caStatus status = client.channelDestroyEvent (
|
||||
clientGuard, this->pChan, this->sid );
|
||||
if ( status != S_cas_sendBlocked ) {
|
||||
delete this;
|
||||
}
|
||||
|
||||
@@ -37,10 +37,11 @@ class casChannelI;
|
||||
|
||||
class channelDestroyEvent : public casEvent {
|
||||
public:
|
||||
channelDestroyEvent ( casChannelI &, bool uninstallNeeded );
|
||||
channelDestroyEvent (
|
||||
casChannelI * pChan, ca_uint32_t sid );
|
||||
private:
|
||||
casChannelI & chan;
|
||||
bool uninstallNeeded;
|
||||
casChannelI * pChan;
|
||||
ca_uint32_t sid;
|
||||
caStatus cbFunc (
|
||||
casCoreClient &,
|
||||
epicsGuard < casClientMutex > &,
|
||||
@@ -48,8 +49,8 @@ private:
|
||||
};
|
||||
|
||||
inline channelDestroyEvent::channelDestroyEvent (
|
||||
casChannelI & chanIn, bool uninstallNeededIn ) :
|
||||
chan ( chanIn ), uninstallNeeded ( uninstallNeededIn )
|
||||
casChannelI * pChanIn, ca_uint32_t sidIn ) :
|
||||
pChan ( pChanIn ), sid ( sidIn )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user