If a gathering write (i.e., a write that takes an array of buffers) is
given a list of buffers, and the initial buffers have no remaining
elements, then the `write' method *should* skip these buffers, and use
the first buffer that has remaining elements.

Since on some operating systems, gathering writes can only take up to
sixteen input sources, it is important that we advance to some buffer
that has something in it. Otherwise, we'll see nothing in the first
sixteen buffers, and won't write anything.

This reverts my previous change to FileChannelImpl, since `writev' seems
to work OK on files. This should fix the issue I saw with Azureus, and
also clears two Mauve regressions I introduced (I think the tests are
wrong, but this fixes them regardless).

Scattering reads are probably also similarly broken; I'll look at that next.

2006-09-25  Casey Marshall  <[EMAIL PROTECTED]>

        * gnu/java/nio/FileChannelImpl.java (read): revert back to using
        `readScattering.'
        (write): revert back to using `writeGathering.'
        * vm/reference/gnu/java/nio/VMChannel.java (writeGathering): find
        the first buffer that has data remaining, and start at that one.

Committed.
### Eclipse Workspace Patch 1.0
#P classpath
Index: gnu/java/nio/FileChannelImpl.java
===================================================================
RCS file: /cvsroot/classpath/classpath/gnu/java/nio/FileChannelImpl.java,v
retrieving revision 1.18
diff -u -r1.18 FileChannelImpl.java
--- gnu/java/nio/FileChannelImpl.java   25 Sep 2006 06:49:18 -0000      1.18
+++ gnu/java/nio/FileChannelImpl.java   25 Sep 2006 21:44:16 -0000
@@ -253,18 +253,7 @@
   public long read (ByteBuffer[] dsts, int offset, int length)
     throws IOException
   {
-    int n = offset + length;
-    long read = 0;
-    if (offset < 0 || length < 0 || n > dsts.length)
-      throw new ArrayIndexOutOfBoundsException();
-    for (int i = offset; i < n; i++)
-      {
-        int ret = read(dsts[i]);
-        if (ret == -1)
-          break;
-        read += ret;
-      }
-    return read;
+    return ch.readScattering(dsts, offset, length);
   }
 
   public int write (ByteBuffer src) throws IOException
@@ -303,13 +292,7 @@
   public long write(ByteBuffer[] srcs, int offset, int length)
     throws IOException
   {
-    int n = offset + length;
-    long written = 0;
-    if (offset < 0 || length < 0 || n > srcs.length)
-      throw new ArrayIndexOutOfBoundsException();
-    for (int i = offset; i < n; i++)
-      written += write(srcs[i]);
-    return written;
+    return ch.writeGathering(srcs, offset, length);
   }
 
   public MappedByteBuffer map (FileChannel.MapMode mode,
Index: vm/reference/gnu/java/nio/VMChannel.java
===================================================================
RCS file: 
/cvsroot/classpath/classpath/vm/reference/gnu/java/nio/VMChannel.java,v
retrieving revision 1.2
diff -u -r1.2 VMChannel.java
--- vm/reference/gnu/java/nio/VMChannel.java    17 Sep 2006 07:31:43 -0000      
1.2
+++ vm/reference/gnu/java/nio/VMChannel.java    25 Sep 2006 21:44:16 -0000
@@ -196,7 +196,7 @@
   {
     if (offset + length > dsts.length)
       throw new IndexOutOfBoundsException("offset + length > dsts.length");
-    
+
     return readScattering(nfd.getNativeFD(), dsts, offset, length);
   }
   
@@ -275,6 +275,21 @@
     if (offset + length > srcs.length)
       throw new IndexOutOfBoundsException("offset + length > srcs.length");
     
+    // A gathering write is limited to 16 buffers; when writing, ensure
+    // that we have at least one buffer with something in it in the 16
+    // buffer window starting at offset.
+    while (!srcs[offset].hasRemaining() && offset < srcs.length)
+      offset++;
+    
+    // There are no buffers with anything to write.
+    if (offset == srcs.length)
+      return 0;
+
+    // If we advanced `offset' so far that we don't have `length'
+    // buffers left, reset length to only the remaining buffers.
+    if (length > srcs.length - offset)
+      length = srcs.length - offset;
+
     return writeGathering(nfd.getNativeFD(), srcs, offset, length);
   }
   
@@ -673,10 +688,10 @@
     
     public String toString()
     {
-      if (!valid)
-        return "<<invalid>>";
       if (closed)
         return "<<closed>>";
+      if (!valid)
+        return "<<invalid>>";
       return String.valueOf(native_fd);
     }
     

Reply via email to