I think what you suggested should work. But how about a simpler version?


             if (expected > count) {
                 long nskip = expected - count;
                 if (nskip <= available()) {
-                    long n = 0;
-                    while (n < nskip) {
-                        nskip = nskip - n;
-                        n = skip(nskip);
+                    while (nskip > 0 && available() > 0) {
+                        skip(nskip);
+                        nskip = expected - count;
                     }


-Chris

On 12/13/2012 12:49 AM, Martin Buchholz wrote:


On Tue, Dec 11, 2012 at 7:40 AM, Chris Hegarty <chris.hega...@oracle.com
<mailto:chris.hega...@oracle.com>> wrote:

    Hi Martin,

    Thank you for reporting this issue. I filed 8004863: "Infinite Loop
    in KeepAliveStream", to track it.

    I put together a small test to reproduce the problem (inline below).
    It is racey, but shows the problem most of the time on my machine.

    I tried your suggested patch, but found that there were cases where
    not enough data was being read off the stream, when it was being
    closed. This causes a problem for subsequent requests on that
    stream. The suggested patch below resolves this, and should also
    resolve the problem you are seeing ( patch against jdk8 ).

    Is this something that you want to run with, or would you prefer for
    me to get it into jdk8?

    diff -r fda257689786
    src/share/classes/sun/net/www/__http/KeepAliveStream.java
    --- a/src/share/classes/sun/net/__www/http/KeepAliveStream.java
    Mon Dec 10 10:52:11 2012 +0900
    +++ b/src/share/classes/sun/net/__www/http/KeepAliveStream.java
    Tue Dec 11 15:30:50 2012 +0000
    @@ -83,10 +83,9 @@ class KeepAliveStream extends MeteredStr
                  if (expected > count) {
                      long nskip = expected - count;

                      if (nskip <= available()) {
    -                    long n = 0;
    -                    while (n < nskip) {
    -                        nskip = nskip - n;
    -                        n = skip(nskip);
    +                    while (nskip > 0) {
    +                        skip(nskip);
    +                        nskip = expected - count;
                          }


I'm still having a hard time understanding the code.  It looks to me
like the above still has issues if there is an asynchronous close in
this loop.  In that case skip() will make no progress and always return
0, and we will continue to see nskip > 0.

How about (completely untested)

              if (expected > count) {
                  long nskip = (long) (expected - count);
                  if (nskip <= available()) {
-                    long n = 0;
-                    while (n < nskip) {
-                        nskip = nskip - n;
-                        n = skip(nskip);
-                    }
+                    do {} while ((nskip = (long) (expected - count)) > 0L
+                                 && skip(Math.min(nskip, available()))
 > 0L);
                  } else if (expected <=
KeepAliveStreamCleaner.MAX_DATA_REMAINING && !hurried) {
                      //put this KeepAliveStream on the queue so that
the data remaining
                      //on the socket can be cleanup asyncronously.

Reply via email to