public void closeConversation ( OutboundConnection connectionHostingConversation ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) SibTr . entry ( this , tc , "closeConversation" , connectionHostingConversation ) ; // To avoid deadlock - keep a list of pending closes and only allow one thread // to process this list. boolean closeOnThisThread = false ; synchronized ( closeList ) { closeOnThisThread = closeList . isEmpty ( ) ; closeList . addLast ( connectionHostingConversation ) ; if ( closeOnThisThread ) connectionHostingConversation = closeList . getFirst ( ) ; } while ( closeOnThisThread ) { ConnectionData connectionData = connectionHostingConversation . getConnectionData ( ) ; if ( connectionData != null ) { EndPointDescriptor endPointDescriptior = connectionData . getEndPointDescriptor ( ) ; ConnectionDataGroup group ; // Take the endpoint to group map's monitor to prevent anyone else from getting // ahold of and using this group whilst we perform an update. synchronized ( endPointToGroupMap ) { // Find the group. group = endPointToGroupMap . get ( endPointDescriptior ) ; if ( ( group == null ) || ( group != connectionData . getConnectionDataGroup ( ) ) ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) { if ( group == null ) SibTr . debug ( this , tc , "group == nul" ) ; else SibTr . debug ( this , tc , "group != connectionData.getConnectionDataGroup()" ) ; } // Record an FFDC, but then ignore this close request (and continue with the next one) // NOTE: If we don't continue NO close will ever be processed Exception e = new SIErrorException ( nls . getFormattedMessage ( "OUTCONNTRACKER_INTERNAL_SICJ0064" , null , "OUTCONNTRACKER_INTERNAL_SICJ0064" ) ) ; // D226223 FFDCFilter . processException ( e , "com.ibm.ws.sib.jfapchannel.impl.octracker.OutboundConnectionTracker" , JFapChannelConstants . OUTBOUNDCONNTRACKER_CLOSECONV_01 , connectionData ) ; } else { // Notify the group that a conversation using the specified connection // has closed. group . close ( connectionHostingConversation ) ; // If the connection group has become empty, remove it from out map. if ( group . isEmpty ( ) ) { if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) SibTr . debug ( this , tc , "group: " + group + " has become empty" ) ; endPointToGroupMap . remove ( group . getEndPointDescriptor ( ) ) ; } } } } synchronized ( closeList ) { closeList . removeFirst ( ) ; closeOnThisThread = ! closeList . isEmpty ( ) ; if ( closeOnThisThread ) { connectionHostingConversation = closeList . getFirst ( ) ; if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isDebugEnabled ( ) ) SibTr . debug ( this , tc , "close list has an entry: " + connectionHostingConversation ) ; } } } if ( TraceComponent . isAnyTracingEnabled ( ) && tc . isEntryEnabled ( ) ) SibTr . exit ( this , tc , "closeConversation" ) ; }
Closes a conversation for the specified connection . It is unnecessary to require a reference to the conversation being closed as by the time this method is invoked the conversation has been marked closed and all that remains is the book keeping . This method notifies the appropriate connection group that a conversation has closed and if necessary removes the group from the map of those tracked .