Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8157932

PipedInputStream read() gets in infinite loop

    XMLWordPrintable

    Details

    • Subcomponent:
    • CPU:
      generic
    • OS:
      generic

      Description

      FULL PRODUCT VERSION :
      java version "1.8.0_74"
      Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
      Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)


      ADDITIONAL OS VERSION INFORMATION :
      SunOS shopbench01_jms01 5.10 Generic_150400-13 sun4us sparc FJSV,GPUZC-M


      A DESCRIPTION OF THE PROBLEM :
      When no input is left from the writer (and the writer does not close) then when read is called it is possible to get into an infinite loop when expecting the -1 return code. This appears to be due to the following line with in the while loop (inside "public synchronized int read()"
                  if ((writeSide != null) && (!writeSide.isAlive()) && (--trials < 0)) {

      The trials variable was introduced to keep this from occuring, however the if statement should have used the OR operator instead of the and operator like so:

                  if ((writeSide != null && !writeSide.isAlive()) || (--trials < 0)) {

      As it stands if the writeSide.isAlive is always true, then it will loop indefinetly as long as nothing else is read into stream.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Create a pipedInputStream, write to it and read from it. (Note that I receive this mostly when combined with JSCH's OutputStream as it does not close the writer)


      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      -1 is returned from read().
      ACTUAL -
      Infinite loop in while of read()

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      private final PipedInputStream pipedShellOutputStream = new PipedInputStream();
      private final byte[] inbuf = new byte[MAX_RECORD_SIZE];

      channel=Jsch().getSession(username, host, port).openChannel("shell");

      channel.setOutputStream(new PipedOutputStream(pipedShellOutputStream));


      if (pipedShellOutputStream.available() > 0) {
        int num;
        while (num = pipedShellOutputStream.read(this.inbuf)) != -1){
           process(inbuf);
        }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      Switch to a different InputStream or check before reading.

        Attachments

          Activity

            People

            Assignee:
            bpb Brian Burkhalter
            Reporter:
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            4 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved: