harmony-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tim Ellison <t.p.elli...@gmail.com>
Subject Re: [classlib] java.io.DataOutputStream behaviour doesn't match RI
Date Sun, 13 Sep 2009 19:34:10 GMT
On 13/Sep/2009 14:28, Mark Hindess wrote:
> In message <200909130807.n8D87VgB001493@d12av01.megacenter.de.ibm.com>, Mark Hi
> ndess writes:
>>
>> In message <200909112249.n8BMnnZB016878@d06av04.portsmouth.uk.ibm.com>,
>> Mark Hindess writes:
>>> In message <4AAACFCE.5090809@gmail.com>, Tim Ellison writes:
>>>> On 11/Sep/2009 23:13, Mark Hindess wrote:
>>>>> I am trying to work through the JDWP java6 branch test failures
>>>>> (so is Oliver).  I see quite a lot of intermittent failures on
>>>>> Linux[0].  I think they are mostly caused by failures at the time
>>>>> when the socket used for synchronising the debuggee/debugger
>>>>> is being closed.  The sychronisation is simply one end calling
>>>>> "DataOutputStream.writeUTF("continue"); DataOutputStream.flush();" and
>>>>> the other end trying to do DataInputStream.readUTF().
>>>>>
>>>>> When running on the RI, the tests pass consistently.  Strace of the RI
>>>>> shows the writeUTF making syscalls like:
>>>>>
>>>>>   send(10, "\0\10continue", 10, 0) = 10
>>>>>   close(10)                        = 0
>>>>>
>>>>> where as our implementation does:
>>>>>
>>>>>   send(58, "\0\10", 2, 0)    = 2
>>>>>   send(58, "continue", 8, 0) = 8
>>>>>   close(58)                  = 0
>>>>>
>>>>> Examining the packet dump for the socket shows a packet containing the
>>>>> length ('\0\10') followed by a RST packet as the socket is closed but
n
>> o
>>>>> packet containing the "continue" text.  So, the "continue" is lost with
>>>>> the result that the other end reads the length then loops waiting for
>>>>> the message until the test timeout is reached.[1]
>>>>>
>>>>> I think it would probably be useful if we fixed our implementation to
>>>>> have the same behaviour as the RI.
>>>> +1
>>>>
>>>> I'm happy to take a look at that if you want.
>>> Well, just doing the obvious thing of re-writing writeUTF by moving
>>> the code from writeUTFBytes (and making utfBytes two bytes larger to
>>> insert the length) into writeUTF seems to fix at least some of the
>>> intermittent failures for me.  (I've appended the patch but it doesn't
>>> really show what I did particularly well.) But I've not run the luni
>>> tests on this change yet and I need sleep now.
>> I've done a few jdwp test runs now and this approach definitely improves
>> stability quite a bit.  Unfortunately ObjectOutputStream uses the
>> writeUTFBytes method that my patch removes so it needs more work.  I
>> wonder whether the ObjectOutputStream implementation suffers from the
>> same issue.
> 
> Also why does writeUTFBytes(String, long) take a long argument when the
> implementation is restricted to int (by the int-sized utfBytes output
> buffer)?

Beats me.  Reading the code, it is a shame we have to traverse the
string twice, once to count the bytes required for UTF-8, and again to
perform the encoding.  I bet it would be worth speculatively optimizing
for ascii (if this ever showed up on a performance benchmark).

Regards,
Tim

>>> And I still want to figure out why the test framework missed the close.
>>>
>>> Regards,
>>>  Mark.
>>>
>>>>> Regards,
>>>>>  Mark.
>>>>>
>>>>> [0] I'm using org.apache.harmony.jpda.tests.jdwp.MultiSession.RefTypeID
>> Te
>>> st
>>>>>     for testing but there are plenty of intermittently failing tests
to
>>>>>     choose from.
>>>>>
>>>>> [1] I wonder why doesn't it see the socket close and bail out?  This
is
>>>>>     probably another bug (perhaps with the framework).
>>> Index: modules/luni/src/main/java/java/io/DataOutputStream.java
>>> ===================================================================
>>> --- modules/luni/src/main/java/java/io/DataOutputStream.java	(revisi
>> on 81373
>>> 9)
>>> +++ modules/luni/src/main/java/java/io/DataOutputStream.java	(workin
>> g copy)
>>> @@ -314,30 +314,12 @@
>>>          if (utfCount > 65535) {
>>>              throw new UTFDataFormatException(Msg.getString("K0068")); //$N
>> ON
>>> -NLS-1$
>>>          }
>>> -        writeShort((int) utfCount);
>>> -        writeUTFBytes(str, utfCount);
>>> -    }
>>> -
>>> -    long countUTFBytes(String str) {
>>> -        int utfCount = 0, length = str.length();
>>> -        for (int i = 0; i < length; i++) {
>>> -            int charValue = str.charAt(i);
>>> -            if (charValue > 0 && charValue <= 127) {
>>> -                utfCount++;
>>> -            } else if (charValue <= 2047) {
>>> -                utfCount += 2;
>>> -            } else {
>>> -                utfCount += 3;
>>> -            }
>>> -        }
>>> -        return utfCount;
>>> -    }
>>> -
>>> -    void writeUTFBytes(String str, long count) throws IOException {
>>> -        int size = (int) count;
>>> +        int size = (int) utfCount;
>>>          int length = str.length();
>>> -        byte[] utfBytes = new byte[size];
>>> +        byte[] utfBytes = new byte[size+2];
>>>          int utfIndex = 0;
>>> +        utfBytes[utfIndex++] = (byte) (size >> 8);
>>> +        utfBytes[utfIndex++] = (byte) size;
>>>          for (int i = 0; i < length; i++) {
>>>              int charValue = str.charAt(i);
>>>              if (charValue > 0 && charValue <= 127) {
>>> @@ -353,4 +335,19 @@
>>>          }
>>>          write(utfBytes, 0, utfIndex);
>>>      }
>>> +
>>> +    long countUTFBytes(String str) {
>>> +        int utfCount = 0, length = str.length();
>>> +        for (int i = 0; i < length; i++) {
>>> +            int charValue = str.charAt(i);
>>> +            if (charValue > 0 && charValue <= 127) {
>>> +                utfCount++;
>>> +            } else if (charValue <= 2047) {
>>> +                utfCount += 2;
>>> +            } else {
>>> +                utfCount += 3;
>>> +            }
>>> +        }
>>> +        return utfCount;
>>> +    }
>>>  }
>>>
> 
> 
> 

Mime
View raw message