diff --git a/src/rsrv/camessage.c b/src/rsrv/camessage.c index e6c4330ab..800d90810 100644 --- a/src/rsrv/camessage.c +++ b/src/rsrv/camessage.c @@ -1072,7 +1072,7 @@ unsigned cid * casAccessRightsCB() * * If access right state changes then inform the client. - * + * asLock is held */ static void casAccessRightsCB(ASCLIENTPVT ascpvt, asClientStatus type) { @@ -1521,6 +1521,9 @@ static void sendAllUpdateAS ( struct client *client ) else if ( pciu->state == rsrvCS_inServiceUpdatePendAR ) { access_rights_reply ( pciu ); } + else if ( pciu->state == rsrvCS_shutdown ) { + /* no-op */ + } else { errlogPrintf ( "%s at %d: corrupt channel state detected durring AR update\n", @@ -2003,10 +2006,15 @@ static int clear_channel_reply ( caHdrLargeArray *mp, if ( pciu->state == rsrvCS_inService || pciu->state == rsrvCS_pendConnectResp ) { ellDelete ( &client->chanList, &pciu->node ); + pciu->state = rsrvCS_shutdown; } else if ( pciu->state == rsrvCS_inServiceUpdatePendAR || pciu->state == rsrvCS_pendConnectRespUpdatePendAR ) { ellDelete ( &client->chanPendingUpdateARList, &pciu->node ); + pciu->state = rsrvCS_shutdown; + } + else if ( pciu->state == rsrvCS_shutdown ) { + /* no-op */ } else { epicsMutexUnlock( client->chanListLock ); diff --git a/src/rsrv/caservertask.c b/src/rsrv/caservertask.c index 7c911d64b..7eef1d200 100644 --- a/src/rsrv/caservertask.c +++ b/src/rsrv/caservertask.c @@ -622,6 +622,7 @@ static void destroyAllChannels ( epicsMutexMustLock ( client->chanListLock ); pciu = (struct channel_in_use *) ellGet ( pList ); + if(pciu) pciu->state = rsrvCS_shutdown; epicsMutexUnlock ( client->chanListLock ); if ( ! pciu ) { diff --git a/src/rsrv/server.h b/src/rsrv/server.h index 9c222d09b..fc7627f80 100644 --- a/src/rsrv/server.h +++ b/src/rsrv/server.h @@ -98,12 +98,25 @@ typedef struct client { char disconnect; /* disconnect detected */ } client; +/* Channel state shows which struct client list a + * channel_in_us::node is in. + * + * client::chanList + * rsrvCS_pendConnectResp, rsrvCS_inService + * client::chanPendingUpdateARList + * rsrvCS_pendConnectRespUpdatePendAR, rsrvCS_inServiceUpdatePendAR + * Not in any list + * rsrvCS_shutdown + * + * rsrvCS_invalid is not used + */ enum rsrvChanState { rsrvCS_invalid, rsrvCS_pendConnectResp, rsrvCS_inService, rsrvCS_pendConnectRespUpdatePendAR, - rsrvCS_inServiceUpdatePendAR + rsrvCS_inServiceUpdatePendAR, + rsrvCS_shutdown }; /*