Uploaded image for project: 'HttpComponents HttpCore'
  1. HttpComponents HttpCore
  2. HTTPCORE-753

race condition with CapacityWindow resulting in CancelKeyException

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 5.1.3
    • 5.2.3, 5.3-alpha1
    • HttpCore
    • None

    Description

      We have found a race condition AbstractHttp1StreamDuplexer where the IOSessionImpl is closed off (cancelling it's SelectionKey) first before CapacityWindow (which also has a reference to the IOSession) is closed. This creates a window of opportunity where if a ResponseConsumer (something like AbstractClassicEntityConsumer) holds a reference to the CapacityWindow and tries to call update(), it will result in a CancelledKeyException being thrown. We are running into this issue fairly regularly.

      Here is what I believe the fix is: in AbstractHttp1StreamDuplexer.onInput the following two lines should be swapped:

      dataEnd(contentDecoder.getTrailers());
      capacityWindow.close();

       

      Close the capacityWindow first before calling dataEnd which closes off the connection, thus the capacityWindow will always be safe to use.

       

      In case this is helpful, here is the callstack for when the connection is closed and the SelectionKey becomes invalid:

      close:266, IOSessionImpl (org.apache.hc.core5.reactor)
      close:266, InternalDataChannel (org.apache.hc.core5.reactor)
      close:254, InternalDataChannel (org.apache.hc.core5.reactor)
      shutdownSession:157, AbstractHttp1StreamDuplexer (org.apache.hc.core5.http.impl.nio)
      close:116, ClientHttp1StreamDuplexer$1 (org.apache.hc.core5.http.impl.nio)
      dataEnd:277, ClientHttp1StreamHandler (org.apache.hc.core5.http.impl.nio)
      dataEnd:366, ClientHttp1StreamDuplexer (org.apache.hc.core5.http.impl.nio)
      onInput:333, AbstractHttp1StreamDuplexer (org.apache.hc.core5.http.impl.nio)
      inputReady:64, AbstractHttp1IOEventHandler (org.apache.hc.core5.http.impl.nio)
      inputReady:39, ClientHttp1IOEventHandler (org.apache.hc.core5.http.impl.nio)
      onIOEvent:131, InternalDataChannel (org.apache.hc.core5.reactor)
      handleIOEvent:51, InternalChannel (org.apache.hc.core5.reactor)
      processEvents:178, SingleCoreIOReactor (org.apache.hc.core5.reactor)
      doExecute:127, SingleCoreIOReactor (org.apache.hc.core5.reactor)
      execute:85, AbstractSingleCoreIOReactor (org.apache.hc.core5.reactor)
      run:44, IOReactorWorker (org.apache.hc.core5.reactor)
      run:829, Thread (java.lang)

       

      In the interim, is it safe to catch and discard the CancelledKeyException when calling update on the CapacityChannel?

       

      Attachments

        1. race_condition.txt
          2 kB
          Malay Shah

        Activity

          People

            Unassigned Unassigned
            mns Malay Shah
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: