First check is to make sure that the original Consumer
hasn't been closed.  Then check that this bifurcated consumer
session is not closed.

@throws SIObjectClosedException
491396
private void checkNotClosed() throws SISessionUnavailableException 
  {
    if (tc.isEntryEnabled())
      SibTr.entry(tc, "checkNotClosed");

    // Check that the consumer session isn't closed
    _consumerSession.checkNotClosed();
    
    // Now check that this consumer hasn't closed.
    synchronized (this)
    {
      if(_closed)
      {
        SISessionUnavailableException e =
          new SISessionUnavailableException(
            nls.getFormattedMessage(
              "CONSUMER_CLOSED_ERROR_CWSIP0177",
              new Object[] { _localConsumerPoint.getConsumerManager().getDestination().getName(),
                             _localConsumerPoint.getConsumerManager().getMessageProcessor().getMessagingEngineName()},                
              null));

        if (tc.isEntryEnabled())
          SibTr.exit(tc, "checkNotClosed", "consumer closed");

        throw e;
      }
    }
      
    if (tc.isEntryEnabled())
      SibTr.exit(tc, "checkNotClosed");
  }
1267049
public void afterConnectionClosed(WebSocketSession session, CloseStatus status) {
        logger.debug("WebSocket closed: {}, Close Status: {}", session, status.toString());
    }
129025
@Override
    public void eventUnlocked() throws SevereMessageStoreException
    {
        super.eventUnlocked();

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(tc, "eventUnlocked");

        if (failedInitInRestore)
        {
            //we can only register the listeners if we are fully initialized
            if (stream instanceof DurableSubscriptionItemStream)
            {
                stream.registerListeners(this);
            }
            failedInitInRestore = false;
        }

        reavailable = true;

        try
        {
            // 541867
            // When a message is unlocked, a registered ConsumerDispatcher will try to deliver
            // it to a ready consumer. When this happens the consumer will register for the UNLOCK
            // event. If that is added to a later slot (e.g. UNLOCKED_3) than the one that's currently
            // being processed (the ConsumerDispatcher) it is possible for us to drive the new consumer's
            // unlock event straight away (even though the message has just been locked).

            // This can also result in two (or more) consumers (or multiple instances of the same consumer)
            // being registered on the same message as we may not have deregistered the initial consumer
            // at the time that the ConsumerDispatcher delivers the to the second (or the same) consumer
            // after the unlock.

            // The solution is to proccess all the non-ConsumerDispatchers registered before going back
            // and driving the ConsumerDispatcher.
            for (int pass = 0; pass < 2; pass++)
            {
                if ((UNLOCKED_1 != null) &&
                    (((pass == 0) && !(UNLOCKED_1 instanceof ConsumerDispatcher)) ||
                    ((pass == 1) && (UNLOCKED_1 instanceof ConsumerDispatcher))))
                {
                    UNLOCKED_1.messageEventOccurred(MessageEvents.UNLOCKED, this, null);
                }
                if ((UNLOCKED_2 != null) &&
                    (((pass == 0) && !(UNLOCKED_2 instanceof ConsumerDispatcher)) ||
                    ((pass == 1) && (UNLOCKED_2 instanceof ConsumerDispatcher))))
                {
                    UNLOCKED_2.messageEventOccurred(MessageEvents.UNLOCKED, this, null);
                }
                if ((UNLOCKED_3 != null) &&
                    (((pass == 0) && !(UNLOCKED_3 instanceof ConsumerDispatcher)) ||
                    ((pass == 1) && (UNLOCKED_3 instanceof ConsumerDispatcher))))
                {
                    UNLOCKED_3.messageEventOccurred(MessageEvents.UNLOCKED, this, null);
                }
            }
        } catch (SIException e)
        {
            FFDCFilter.processException(
                                        e,
                                        "com.ibm.ws.sib.processor.impl.store.items.MessageItemReference.eventUnlocked",
                                        "1:574:1.106",
                                        this);

            SibTr.exception(tc, e);

            if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                SibTr.exit(tc, "eventUnlocked", e);

            throw new SIErrorException(e);
        }
        reavailable = false;

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(tc, "eventUnlocked");
    }
432129
private boolean isClientChannelClosed(Throwable cause) {
        if (cause instanceof ClosedChannelException ||
                cause instanceof Errors.NativeIoException) {
            LOG.error("ZuulFilterChainHandler::isClientChannelClosed - IO Exception");
            return true;
        }
        return false;
    }
46273
private void onConnectionClosed()
   {
      ConnectionEvent evt = new ConnectionEvent(this, ConnectionEvent.CONNECTION_CLOSED);
      for (ConnectionEventListener listener : listeners)
      {
         try
         {
            listener.connectionClosed(evt);
         }
         catch (Exception e1)
         {
            LOG.warn("An error occurs while notifying the listener " + listener, e1);
         }
      }
   }
1139184
protected void removeBifurcatedConsumer(BifurcatedConsumerSessionImpl consumer) throws SIResourceException, SISessionDroppedException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(tc, "removeBifurcatedConsumer", consumer);

        synchronized (_bifurcatedConsumers)
        {
            _bifurcatedConsumers.remove(consumer);
        }

        // Cleanup after the bifurcated consumer (unlock any messages it owns)
        _localConsumerPoint.cleanupBifurcatedConsumer(consumer);

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(tc, "removeBifurcatedConsumer");
    }
1323323
void closeSocket(boolean tryReconnectIfConnected) throws InterruptedException {
        boolean wasConnected = false;

        statusLock.lock();
        try {
            if (isDisconnectingOrClosed()) {
                waitForDisconnectOrClose(this.options.getConnectionTimeout());
                return;
            } else {
                this.disconnecting = true;
                this.exceptionDuringConnectChange = null;
                wasConnected = (this.status == Status.CONNECTED);
                statusChanged.signalAll();
            }
        } finally {
            statusLock.unlock();
        }

        closeSocketImpl();

        statusLock.lock();
        try {
            updateStatus(Status.DISCONNECTED);
            this.exceptionDuringConnectChange = null; // Ignore IOExceptions during closeSocketImpl()
            this.disconnecting = false;
            statusChanged.signalAll();
        } finally {
            statusLock.unlock();
        }

        if (isClosing()) { // Bit of a misname, but closing means we are in the close method or were asked
                           // to be
            close();
        } else if (wasConnected && tryReconnectIfConnected) {
            reconnect();
        }
    }
1368056
private void objectManagerStopped()
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "objectManagerStopped");

        // Stop any new work coming in as we do not have a working
        // ObjectManager to service any requests.
        _available = false;

        // Only treat this shutdown as an error if we haven't
        // asked for it. In the case of a normal ME stop we
        // will still get the callback but don't have to worry
        // about it.
        if (!_shutdownRequested)
        {
            // Report a local error so that we can begin failover to a
            // new ME instance. This will allow the new instance to
            // enter it's startup retry loop and try to re-connect to
            // a working ObjectManager.
            _ms.reportLocalError();

            SibTr.error(tc, "FILE_STORE_STOP_UNEXPECTED_SIMS1590");
        }
        else
        {
            SibTr.info(tc, "FILE_STORE_STOP_EXPECTED_SIMS1589");
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "objectManagerStopped");
    }
1214243
public void close() {
    if (consumer != null) {
      try {
        consumer.close();
      } catch (Throwable t) {
        warn(t.getMessage());
      }
    }

    conn.close();
  }
264423
public boolean isConsumerSetSuspended()
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.entry(tc, "isConsumerSetSuspended");

    boolean consumerSetSuspended = false;
    if(classifyingMessages)
      consumerSetSuspended = consumerSet.isConsumerSetSuspended();
    
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.exit(tc, "isConsumerSetSuspended", Boolean.valueOf(consumerSetSuspended));  
    return consumerSetSuspended;
  }
1335021
public void checkCloseOnCompletion(ResultSet resultSet) throws SQLException {
    if (mustCloseOnCompletion
        && !closed
        && results != null
        && resultSet.equals(results.getResultSet())) {
      close();
    }
  }
519648
public void sessionClosed(IoSession session) throws Exception {
        SingleSessionIoHandler handler = (SingleSessionIoHandler) session
                .getAttribute(HANDLER);
        handler.sessionClosed();
    }
1052511
void checkNotClosed() throws SISessionUnavailableException
    {
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.entry(tc, "checkNotClosed");

        try
        {
            synchronized (_localConsumerPoint)
            {
                _localConsumerPoint.checkNotClosed();
            }
        } catch (SISessionUnavailableException e)
        {
            // No FFDC code needed
            SibTr.exception(tc, e);

            if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
                SibTr.exit(tc, "checkNotClosed", e);

            throw e;
        }

        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
            SibTr.exit(tc, "checkNotClosed");
    }
539024
@Override
    public void afterConnectionClosed(final WebSocketSession webSocketSession, final CloseStatus status) {
        logger.debug("[afterConnectionClosed] id = ", webSocketSession.getId());
        this.session = null;

        if (connectionListener != null) {
            connectionListener.onConnectionClosed();
        }
    }
241645
public void setAsynchConsumer(AsynchConsumerCallback consumer,
                                 int maxActiveMessages,
                                 long messageLockExpiry,
                                 int maxBatchSize,
                                 OrderingContext orderContext,
                                 int maxSequentialFailures,                                             //SIB0115d.comms
                                 long hiddenMessageDelay,
                                 boolean stoppable)                                                             //472879
      throws SISessionUnavailableException, SISessionDroppedException,
             SIConnectionUnavailableException, SIConnectionDroppedException,
             SIErrorException,
             SIIncorrectCallException
   {
      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.entry(this, tc, "setAsynchConsumer",
                                           new Object[]
                                           {
                                              consumer,
                                              maxActiveMessages,
                                              messageLockExpiry,
                                              maxBatchSize,
                                              orderContext,
                                              maxSequentialFailures,                                    //SIB0115d.comms
                                              hiddenMessageDelay,
                                              stoppable                                                         //472879
                                           });

      if (sessionId == 0)
      {
         // If the session Id = 0, then no one called setSessionId(). As such we are unable to flow
         // to the server as we do not know which session to instruct the server to use.
         SIErrorException e = new SIErrorException(
            nls.getFormattedMessage("SESSION_ID_HAS_NOT_BEEN_SET_SICO1043", null, null)
         );

         FFDCFilter.processException(e, CLASS_NAME + ".setAsyncConsumer",
                                     CommsConstants.CONVERSATIONHELPERIMPL_02, this);

         if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Session Id was 0", e);

         throw e;
      }

      CommsByteBuffer request = getCommsByteBuffer();
      // Connection object id
      request.putShort(connectionObjectId);
      // Consumer session id
      request.putShort(sessionId);
      // Now put the message order context id if we have one
      if (orderContext != null)
      {
         request.putShort(((OrderingContextProxy)orderContext).getId());
      }
      else
      {
         request.putShort(CommsConstants.NO_ORDER_CONTEXT);
      }
      // Client session id - this is the proxy queue ID
      request.putShort(proxyQueueId);
      // Max active messages
      request.putInt(maxActiveMessages);
      // Message lock expiry
      request.putLong(messageLockExpiry);
      // Max batch size
      request.putInt(maxBatchSize);

      // If callback is Stoppable then send maxSequentialFailures & hiddenMessageDelay then change the
      // Segment Id to Stoppable  SIB0115d.comms
      int JFapSegmentId = JFapChannelConstants.SEG_REGISTER_ASYNC_CONSUMER;                             //SIB0115d.comms

      if (stoppable) {                                                                           //SIB0115d.comms,472879
        request.putInt(maxSequentialFailures);                                                          //SIB0115d.comms
        request.putLong(hiddenMessageDelay);
        JFapSegmentId = JFapChannelConstants.SEG_REGISTER_STOPPABLE_ASYNC_CONSUMER;                     //SIB0115d.comms
      }                                                                                                 //SIB0115d.comms

      CommsByteBuffer reply = null;
      try
      {
         // Pass on call to server
         reply = jfapExchange(request,
                              JFapSegmentId,                                                            //SIB0115d.comms
                              JFapChannelConstants.PRIORITY_MEDIUM,
                              true);
      }
      catch (SIConnectionLostException e)
      {
         // No FFDC Code needed
         // Converting this to a connection dropped as that is all we can throw
         if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled()) SibTr.debug(this, tc, "Connection was lost", e);

         throw new SIConnectionDroppedException(e.getMessage(), e);
      }

      // Confirm appropriate data returned
      try
      {
         short err = reply.getCommandCompletionCode(JFapChannelConstants.SEG_REGISTER_ASYNC_CONSUMER_R);
         if (err != CommsConstants.SI_NO_EXCEPTION)
         {
            checkFor_SISessionUnavailableException(reply, err);
            checkFor_SISessionDroppedException(reply, err);
            checkFor_SIConnectionUnavailableException(reply, err);
            checkFor_SIConnectionDroppedException(reply, err);
            checkFor_SIIncorrectCallException(reply, err);
            checkFor_SIErrorException(reply, err);
            defaultChecker(reply, err);
         }
      }
      finally
      {
         if (reply != null) reply.release();
      }

      if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) SibTr.exit(this, tc, "setAsynchConsumer");
   }
794700
void connectionClosed(final SibRaConnection connection) {

        if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
            SibTr.entry(this, TRACE, "connectionClosed", connection);
        }

        final ConnectionEvent event = new ConnectionEvent(this,
                ConnectionEvent.CONNECTION_CLOSED);
        event.setConnectionHandle(connection);

        for (Iterator iterator = _eventListeners.iterator(); iterator.hasNext();) {

            final ConnectionEventListener listener = (ConnectionEventListener) iterator
                    .next();
            listener.connectionClosed(event);

        }

        _connections.remove(connection);

        if (TraceComponent.isAnyTracingEnabled() && TRACE.isEntryEnabled()) {
            SibTr.exit(this, TRACE, "connectionClosed");
        }

    }
34400
void consumerSessionStopped()
  {
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.entry(tc, "consumerSessionStopped");      

    try
    {
      if (asynchConsumerCallback instanceof StoppableAsynchConsumerCallback)
      {
        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
          SibTr.debug(tc, "Entering asynchConsumerCallback.consumerSessionStopped",
                       asynchConsumerCallback);      

        ((StoppableAsynchConsumerCallback)asynchConsumerCallback).consumerSessionStopped();

        if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
          SibTr.debug(tc, "Exiting asynchConsumerCallback.consumerSessionStopped");      
      }
    }
    catch (Throwable e)
    {
      //Catch any exceptions thrown by consumeMessages.
      FFDCFilter.processException(
       e,
       "com.ibm.ws.sib.processor.impl.AsynchConsumer.consumerSessionStopped",
       "1:264:1.37",
       this);

      //Trace the exception but otherwise swallow it since it was not
      //a failure in MP code or code upon which the MP is critically
      //dependent.
      if (e instanceof Exception)
        SibTr.exception(tc, (Exception)e);
      
      if (TraceComponent.isAnyTracingEnabled() && tc.isDebugEnabled())
        SibTr.debug(tc, "Exception occurred in consumerSessionStopped " + e);
         
      // We're not allowed to swallow this exception - let it work its way back to
      // the threadpool
      if(e instanceof ThreadDeath)
      {     
        if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled()) 
          SibTr.exit(tc, "consumerSessionStopped", e); 
        throw (ThreadDeath)e;
      }
    }
    
    if (TraceComponent.isAnyTracingEnabled() && tc.isEntryEnabled())
      SibTr.exit(tc, "consumerSessionStopped");
  }