You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@directory.apache.org by tr...@apache.org on 2006/03/11 09:53:06 UTC

svn commit: r385042 - in /directory/trunks/mina/core/src: main/java/org/apache/mina/common/PooledByteBufferAllocator.java test/java/org/apache/mina/common/ByteBufferTest.java

Author: trustin
Date: Sat Mar 11 00:53:04 2006
New Revision: 385042

URL: http://svn.apache.org/viewcvs?rev=385042&view=rev
Log:
* Added PooledByteBufferAllocator.dispose() for users who want to destroy an expirer thread
* Made sure the allocation cannot happen since the allocator is disposed.

Modified:
    directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java
    directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java

Modified: directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java?rev=385042&r1=385041&r2=385042&view=diff
==============================================================================
--- directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java (original)
+++ directory/trunks/mina/core/src/main/java/org/apache/mina/common/PooledByteBufferAllocator.java Sat Mar 11 00:53:04 2006
@@ -46,11 +46,11 @@
  */
 public class PooledByteBufferAllocator implements ByteBufferAllocator
 {
-    private final int MINIMUM_CAPACITY = 1;
+    private static final int MINIMUM_CAPACITY = 1;
+    private static int threadId = 0;
 
+    private final Expirer expirer;
     private final ExpiringStack containerStack = new ExpiringStack();
-    private int timeout;
-
     private final ExpiringStack[] heapBufferStacks = new ExpiringStack[] {
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
@@ -63,7 +63,6 @@
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
             new ExpiringStack(), new ExpiringStack(), };
-    
     private final ExpiringStack[] directBufferStacks = new ExpiringStack[] {
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
@@ -76,7 +75,9 @@
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
             new ExpiringStack(), new ExpiringStack(), new ExpiringStack(),
             new ExpiringStack(), new ExpiringStack(), };
-    
+    private int timeout;
+    private boolean disposed;
+
     public PooledByteBufferAllocator()
     {
         this( 60 );
@@ -85,7 +86,40 @@
     public PooledByteBufferAllocator( int timeout )
     {
         setTimeout( timeout );
-        new Expirer().start();
+        expirer = new Expirer();
+        expirer.start();
+    }
+    
+    public void dispose()
+    {
+        if( this == ByteBuffer.getAllocator() )
+        {
+            throw new IllegalStateException( "This allocator is in use." );
+        }
+
+        expirer.shutdown();
+        synchronized( containerStack )
+        {
+            containerStack.clear();
+        }
+        
+        for( int i = directBufferStacks.length - 1; i >= 0; i -- )
+        {
+            ExpiringStack stack = directBufferStacks[i];
+            synchronized( stack )
+            {
+                stack.clear();
+            }
+        }
+        for( int i = heapBufferStacks.length - 1; i >= 0; i -- )
+        {
+            ExpiringStack stack = heapBufferStacks[i];
+            synchronized( stack )
+            {
+                stack.clear();
+            }
+        }
+        disposed = true;
     }
     
     public int getTimeout()
@@ -115,6 +149,7 @@
     
     public ByteBuffer allocate( int capacity, boolean direct )
     {
+        ensureNotDisposed();
         java.nio.ByteBuffer nioBuffer = allocate0( capacity, direct );
         PooledByteBuffer buf = allocateContainer();
         buf.init( nioBuffer, true );
@@ -170,6 +205,7 @@
     
     public ByteBuffer wrap( java.nio.ByteBuffer nioBuffer )
     {
+        ensureNotDisposed();
         PooledByteBuffer buf = allocateContainer();
         buf.init( nioBuffer, false );
         buf.setPooled( false );
@@ -193,19 +229,45 @@
 
         return stackIdx;
     }
+    
+    private void ensureNotDisposed()
+    {
+        if( disposed )
+        {
+            throw new IllegalStateException( "This allocator is disposed already." );
+        }
+    }
 
     private class Expirer extends Thread
     {
+        private boolean timeToStop;
+
         public Expirer()
         {
-            super( "PooledByteBufferExpirer" );
+            super( "PooledByteBufferExpirer-" + threadId++ );
             setDaemon( true );
         }
         
+        public void shutdown()
+        {
+            timeToStop = true;
+            interrupt();
+            while( isAlive() )
+            {
+                try
+                {
+                    join();
+                }
+                catch ( InterruptedException e )
+                {
+                }
+            }
+        }
+        
         public void run()
         {
             // Expire unused buffers every seconds
-            for( ;; )
+            while( !timeToStop )
             {
                 try
                 {
@@ -301,6 +363,12 @@
                 {
                     return;
                 }
+            }
+
+            // No need to return buffers to the pool if it is disposed already.
+            if( disposed )
+            {
+                return;
             }
 
             if( pooled )

Modified: directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java
URL: http://svn.apache.org/viewcvs/directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java?rev=385042&r1=385041&r2=385042&view=diff
==============================================================================
--- directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java (original)
+++ directory/trunks/mina/core/src/test/java/org/apache/mina/common/ByteBufferTest.java Sat Mar 11 00:53:04 2006
@@ -547,6 +547,42 @@
         buf.release();
         Thread.sleep( 2000 );
         Assert.assertSame( buf, ByteBuffer.allocate( 16 ) );
-
+        
+        // Return to the default settings
+        allocator.setTimeout( 60 );
+    }
+    
+    public void testAllocatorDisposal() throws Exception
+    {
+        PooledByteBufferAllocator allocator =
+            ( PooledByteBufferAllocator ) ByteBuffer.getAllocator();
+        
+        // dispose() should fail because the allocator is in use. 
+        try
+        {
+            allocator.dispose();
+            Assert.fail();
+        }
+        catch( IllegalStateException e )
+        {
+            // OK
+        }
+        
+        // Change the allocator.
+        ByteBuffer.setAllocator( new PooledByteBufferAllocator() );
+        
+        // Dispose the old allocator. 
+        allocator.dispose();
+        
+        // Allocation request to the disposed allocator should fail.
+        try
+        {
+            allocator.allocate( 16, true );
+            Assert.fail();
+        }
+        catch( IllegalStateException e )
+        {
+            // OK
+        }
     }
 }