Infinite Loop in KeepAliveStream
Chris Hegarty
chris.hegarty at oracle.com
Thu Dec 13 07:26:25 PST 2012
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.hegarty at oracle.com
> <mailto:chris.hegarty at 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.
>
More information about the net-dev
mailing list