Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferPool.java')
-rw-r--r--plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferPool.java154
1 files changed, 132 insertions, 22 deletions
diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferPool.java b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferPool.java
index 748284dc92..d744c3e313 100644
--- a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferPool.java
+++ b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferPool.java
@@ -13,10 +13,13 @@ package org.eclipse.internal.net4j.transport;
import org.eclipse.net4j.transport.IBuffer;
import org.eclipse.net4j.transport.IBufferPool;
import org.eclipse.net4j.transport.IBufferProvider;
+import org.eclipse.net4j.util.ReflectUtil.ExcludeFromDump;
import org.eclipse.net4j.util.om.trace.ContextTracer;
import org.eclipse.internal.net4j.bundle.Net4j;
+import java.lang.ref.ReferenceQueue;
+import java.lang.ref.SoftReference;
import java.util.Queue;
import java.util.concurrent.ConcurrentLinkedQueue;
@@ -27,16 +30,33 @@ public class BufferPool extends BufferProvider implements IBufferPool, IBufferPo
{
private static final ContextTracer TRACER = new ContextTracer(Net4j.DEBUG_BUFFER, BufferPool.class);
- private final IBufferProvider factory;
-
- private final Queue<IBuffer> queue = new ConcurrentLinkedQueue<IBuffer>();
+ private final IBufferProvider provider;
private int pooledBuffers;
- public BufferPool(IBufferProvider factory)
+ @ExcludeFromDump
+ private final Queue<BufferRef> buffers = new ConcurrentLinkedQueue();
+
+ @ExcludeFromDump
+ private final ReferenceQueue<BufferRef> referenceQueue = new ReferenceQueue();
+
+ @ExcludeFromDump
+ private Monitor monitor;
+
+ public BufferPool(IBufferProvider provider)
+ {
+ super(provider.getBufferCapacity());
+ this.provider = provider;
+ }
+
+ public IBufferProvider getProvider()
{
- super(factory.getBufferCapacity());
- this.factory = factory;
+ return provider;
+ }
+
+ public ReferenceQueue<BufferRef> getReferenceQueue()
+ {
+ return referenceQueue;
}
public int getPooledBuffers()
@@ -46,20 +66,27 @@ public class BufferPool extends BufferProvider implements IBufferPool, IBufferPo
public boolean evictOne()
{
- IBuffer buffer = queue.poll();
- if (buffer == null)
+ for (;;)
{
- return false;
- }
+ BufferRef bufferRef = buffers.poll();
+ if (bufferRef == null)
+ {
+ return false;
+ }
- if (TRACER.isEnabled())
- {
- TRACER.trace("Evicting " + buffer); //$NON-NLS-1$
+ IBuffer buffer = bufferRef.get();
+ if (buffer != null)
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Evicting " + buffer); //$NON-NLS-1$
+ }
+
+ provider.retainBuffer(buffer);
+ --pooledBuffers;
+ return true;
+ }
}
-
- factory.retainBuffer(buffer);
- --pooledBuffers;
- return true;
}
public int evict(int survivors)
@@ -81,14 +108,30 @@ public class BufferPool extends BufferProvider implements IBufferPool, IBufferPo
}
@Override
+ public String toString()
+ {
+ return "BufferPool[" + pooledBuffers + ", " + provider + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ }
+
+ @Override
protected IBuffer doProvideBuffer()
{
- IBuffer buffer = queue.poll();
+ IBuffer buffer = null;
+ BufferRef bufferRef = buffers.poll();
+ if (bufferRef != null)
+ {
+ buffer = bufferRef.get();
+ }
+
if (buffer == null)
{
- buffer = factory.provideBuffer();
+ buffer = provider.provideBuffer();
((Buffer)buffer).setBufferProvider(this);
}
+ else
+ {
+ --pooledBuffers;
+ }
buffer.clear();
if (TRACER.isEnabled())
@@ -112,12 +155,79 @@ public class BufferPool extends BufferProvider implements IBufferPool, IBufferPo
TRACER.trace("Retaining " + buffer); //$NON-NLS-1$
}
- queue.add(buffer);
+ buffers.add(new BufferRef(buffer, referenceQueue));
+ ++pooledBuffers;
}
@Override
- public String toString()
+ protected void doActivate() throws Exception
+ {
+ super.doActivate();
+ monitor = new Monitor();
+ monitor.start();
+ }
+
+ @Override
+ protected void doDeactivate() throws Exception
+ {
+ monitor.interrupt();
+ monitor = null;
+ super.doDeactivate();
+ }
+
+ private static final class BufferRef extends SoftReference<IBuffer>
+ {
+ public BufferRef(IBuffer buffer, ReferenceQueue queue)
+ {
+ super(buffer, queue);
+ }
+ }
+
+ private final class Monitor extends Thread
{
- return "BufferPool[size=" + pooledBuffers + ", " + factory + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ public Monitor()
+ {
+ setName("BufferPoolMonitor");
+ setDaemon(true);
+ }
+
+ @Override
+ public void run()
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Start monitoring"); //$NON-NLS-1$
+ }
+
+ try
+ {
+ while (isActive() && !isInterrupted())
+ {
+ BufferRef bufferRef = (BufferRef)referenceQueue.remove(200);
+ if (bufferRef != null)
+ {
+ if (buffers.remove(bufferRef))
+ {
+ --pooledBuffers;
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Collected buffer"); //$NON-NLS-1$
+ }
+ }
+ }
+ }
+ }
+ catch (InterruptedException ex)
+ {
+ return;
+ }
+ finally
+ {
+ if (TRACER.isEnabled())
+ {
+ TRACER.trace("Stop monitoring"); //$NON-NLS-1$
+ }
+ }
+ }
}
}

Back to the top