2004-11-24 Jeroen Frijters <address@bogus.example.com>
authorJeroen Frijters <jeroen@frijters.net>
Wed, 24 Nov 2004 11:11:46 +0000 (11:11 +0000)
committerMichael Koch <mkoch@gcc.gnu.org>
Wed, 24 Nov 2004 11:11:46 +0000 (11:11 +0000)
* java/nio/DirectByteBufferImpl.java
(ReadOnly): New inner subclass.
(ReadWrite): New inner subclass.
(owner): Made final and private.
(address): Made final.
(DirectByteBufferImpl(int)): New constructor.
(DirectByteBufferImpl(Object,RawData,int,int,int)): New constructor.
(DirectByteBufferImpl(Object,RawData,int,int,int,boolean)): Removed.
(allocate): Modified to instantiate ReadWrite subclass.
(finalize): Fixed to only free the buffer, if we own it.
(put): Removed read-only check.
(slice, duplicate): Modified to instantiate appropriate subclass.
(isReadOnly): Removed.
* java/nio/MappedByteBufferImpl.java
(slice, duplicate): Modified to instantiate appropriate
DirectByteBufferImpl subclass.

From-SVN: r91147

libjava/ChangeLog
libjava/java/nio/DirectByteBufferImpl.java
libjava/java/nio/MappedByteBufferImpl.java

index 1c60098..b4fe15d 100644 (file)
@@ -1,3 +1,22 @@
+2004-11-24  Jeroen Frijters  <address@bogus.example.com>
+
+       * java/nio/DirectByteBufferImpl.java
+       (ReadOnly): New inner subclass.
+       (ReadWrite): New inner subclass.
+       (owner): Made final and private.
+       (address): Made final.
+       (DirectByteBufferImpl(int)): New constructor.
+       (DirectByteBufferImpl(Object,RawData,int,int,int)): New constructor.
+       (DirectByteBufferImpl(Object,RawData,int,int,int,boolean)): Removed.
+       (allocate): Modified to instantiate ReadWrite subclass.
+       (finalize): Fixed to only free the buffer, if we own it.
+       (put): Removed read-only check.
+       (slice, duplicate): Modified to instantiate appropriate subclass.
+       (isReadOnly): Removed.
+       * java/nio/MappedByteBufferImpl.java
+       (slice, duplicate): Modified to instantiate appropriate
+       DirectByteBufferImpl subclass.
+
 2004-11-24  Michael Koch  <konqueror@gmx.de>
 
        * gnu/java/nio/NIOServerSocket.java: Added email to @author tag.
index a92515d..ab8cd6f 100644 (file)
@@ -40,27 +40,82 @@ package java.nio;
 
 import gnu.gcj.RawData;
 
-final class DirectByteBufferImpl extends ByteBuffer
+abstract class DirectByteBufferImpl extends ByteBuffer
 {
-  /** Used by MappedByteBufferImpl and when slicing to prevent premature GC. */
-  protected Object owner;
-
-  RawData address;
-  private boolean readOnly;
-
-  public DirectByteBufferImpl(RawData address, long len)
-  {
-    this(null, address, (int) len, (int) len, 0, false);
-  }
-  
-  public DirectByteBufferImpl(Object owner, RawData address,
-                             int capacity, int limit,
-                             int position, boolean readOnly)
+  /** The owner is used to keep alive the object that actually owns the
+    * memory. There are three possibilities:
+    *  1) owner == this: We allocated the memory and we should free it,
+    *                    but *only* in finalize (if we've been sliced
+    *                    other objects will also have access to the
+    *                    memory).
+    *  2) owner == null: The byte buffer was created thru
+    *                    JNI.NewDirectByteBuffer. The JNI code is
+    *                    responsible for freeing the memory.
+    *  3) owner == some other object: The other object allocated the
+    *                                 memory and should free it.
+    */
+  private final Object owner;
+  final RawData address;
+
+  final static class ReadOnly extends DirectByteBufferImpl
+  {
+    ReadOnly(Object owner, RawData address,
+            int capacity, int limit,
+            int position)
+    {
+      super(owner, address, capacity, limit, position);
+    }
+
+    public ByteBuffer put(byte value)
+    {
+      throw new ReadOnlyBufferException ();
+    }
+
+    public ByteBuffer put(int index, byte value)
+    {
+      throw new ReadOnlyBufferException ();
+    }
+
+    public boolean isReadOnly()
+    {
+      return true;
+    }
+  }
+
+  final static class ReadWrite extends DirectByteBufferImpl
+  {
+    ReadWrite(int capacity)
+    {
+      super(capacity);
+    }
+
+    ReadWrite(Object owner, RawData address,
+             int capacity, int limit,
+             int position)
+    {
+      super(owner, address, capacity, limit, position);
+    }
+
+    public boolean isReadOnly()
+    {
+      return false;
+    }
+  }
+
+  DirectByteBufferImpl(int capacity)
+  {
+    super(capacity, capacity, 0, -1);
+    this.owner = this;
+    this.address = VMDirectByteBuffer.allocate(capacity);
+  }
+
+  DirectByteBufferImpl(Object owner, RawData address,
+                      int capacity, int limit,
+                      int position)
   {
     super(capacity, limit, position, -1);
-    this.address = address;
-    this.readOnly = readOnly;
     this.owner = owner;
+    this.address = address;
   }
 
   /**
@@ -68,13 +123,13 @@ final class DirectByteBufferImpl extends ByteBuffer
    */ 
   public static ByteBuffer allocate(int capacity)
   {
-    return new DirectByteBufferImpl(VMDirectByteBuffer.allocate(capacity),
-                                   capacity);
+    return new DirectByteBufferImpl.ReadWrite(capacity);
   }
 
   protected void finalize() throws Throwable
   {
-    VMDirectByteBuffer.free(address);
+    if (owner == this)
+        VMDirectByteBuffer.free(address);
   }
   
   public byte get()
@@ -108,7 +163,6 @@ final class DirectByteBufferImpl extends ByteBuffer
 
   public ByteBuffer put(byte value)
   {
-    checkIfReadOnly();
     checkForOverflow();
 
     int pos = position();
@@ -119,7 +173,6 @@ final class DirectByteBufferImpl extends ByteBuffer
   
   public ByteBuffer put(int index, byte value)
   {
-    checkIfReadOnly();
     checkIndex(index);
 
     VMDirectByteBuffer.put(address, index, value);
@@ -147,9 +200,14 @@ final class DirectByteBufferImpl extends ByteBuffer
   public ByteBuffer slice()
   {
     int rem = remaining();
-    return new DirectByteBufferImpl
+    if (isReadOnly())
+        return new DirectByteBufferImpl.ReadOnly
+      (owner, VMDirectByteBuffer.adjustAddress(address, position()),
+       rem, rem, 0);
+    else
+        return new DirectByteBufferImpl.ReadWrite
       (owner, VMDirectByteBuffer.adjustAddress(address, position()),
-       rem, rem, 0, isReadOnly());
+       rem, rem, 0);
   }
 
   private ByteBuffer duplicate(boolean readOnly)
@@ -158,9 +216,14 @@ final class DirectByteBufferImpl extends ByteBuffer
     reset();
     int mark = position();
     position(pos);
-    DirectByteBufferImpl result
-      = new DirectByteBufferImpl(owner, address, capacity(), limit(),
-                                pos, readOnly);
+    DirectByteBufferImpl result;
+    if (readOnly)
+        result = new DirectByteBufferImpl.ReadOnly(owner, address, capacity(),
+                                                   limit(), pos);
+    else
+        result = new DirectByteBufferImpl.ReadWrite(owner, address, capacity(),
+                                                    limit(), pos);
+
     if (mark != pos)
       {
        result.position(mark);
@@ -180,11 +243,6 @@ final class DirectByteBufferImpl extends ByteBuffer
     return duplicate(true);
   }
 
-  public boolean isReadOnly()
-  {
-    return readOnly;
-  }
-
   public boolean isDirect()
   {
     return true;
index c5cf355..bc8ee80 100644 (file)
@@ -138,9 +138,14 @@ final class MappedByteBufferImpl extends MappedByteBuffer
   public ByteBuffer slice()
   {
     int rem = remaining();
-    return new DirectByteBufferImpl
+    if (isReadOnly())
+        return new DirectByteBufferImpl.ReadOnly
       (this, VMDirectByteBuffer.adjustAddress(address, position()),
-       rem, rem, 0, isReadOnly());
+       rem, rem, 0);
+    else
+        return new DirectByteBufferImpl.ReadWrite
+      (this, VMDirectByteBuffer.adjustAddress(address, position()),
+       rem, rem, 0);
   }
 
   private ByteBuffer duplicate(boolean readOnly)
@@ -149,9 +154,14 @@ final class MappedByteBufferImpl extends MappedByteBuffer
     reset();
     int mark = position();
     position(pos);
-    DirectByteBufferImpl result
-      = new DirectByteBufferImpl(this, address, capacity(), limit(),
-                                pos, readOnly);
+    DirectByteBufferImpl result;
+    if (readOnly)
+        result = new DirectByteBufferImpl.ReadOnly(this, address, capacity(),
+                                                   limit(), pos);
+    else
+        result = new DirectByteBufferImpl.ReadWrite(this, address, capacity(),
+                                                    limit(), pos);
+
     if (mark != pos)
       {
        result.position(mark);