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
+ }
}
}