Infinite Loop in KeepAliveStream
Martin Buchholz
martinrb at google.com
Fri Dec 14 17:56:29 PST 2012
On Thu, Dec 13, 2012 at 7:26 AM, Chris Hegarty <chris.hegarty at oracle.com>wrote:
> 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;
> }
>
>
I was trying to avoid ever calling skip with a larger argument than
available(), trying to obey the comment
// Do this ONLY if the skip won't block.
So my version feels safer, although again I don't have the full context.
>
> -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 <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.
>>
>>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/net-dev/attachments/20121214/b0c52947/attachment.html
More information about the net-dev
mailing list