diff options
8 files changed, 239 insertions, 27 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$ + } + } + } } } diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferProvider.java b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferProvider.java index 191bd4cbd5..801a1bef4a 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferProvider.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferProvider.java @@ -13,10 +13,12 @@ package org.eclipse.internal.net4j.transport; import org.eclipse.net4j.transport.IBuffer; import org.eclipse.net4j.transport.IBufferProvider; +import org.eclipse.internal.net4j.util.lifecycle.Lifecycle; + /** * @author Eike Stepper */ -public abstract class BufferProvider implements IBufferProvider, IBufferProvider.Introspection +public abstract class BufferProvider extends Lifecycle implements IBufferProvider, IBufferProvider.Introspection { private short bufferCapacity; diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferUtil.java b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferUtil.java index ed4dde3e03..456a11fadc 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferUtil.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/internal/net4j/transport/BufferUtil.java @@ -29,8 +29,6 @@ public final class BufferUtil private static final byte TRUE = (byte)1; - public static final short DEFAULT_BUFFER_CAPACITY = 4096; - public static final String UTF8_CHAR_SET_NAME = "UTF-8"; //$NON-NLS-1$ private BufferUtil() diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferPool.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferPool.java index a5765cfcb6..1347a55632 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferPool.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferPool.java @@ -22,7 +22,7 @@ public interface IBufferPool extends IBufferProvider /** * @author Eike Stepper */ - public interface Introspection extends IBufferProvider.Introspection + public interface Introspection extends IBufferPool, IBufferProvider.Introspection { public int getPooledBuffers(); } diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferProvider.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferProvider.java index e3d9b209c2..5fa89e6099 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferProvider.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/IBufferProvider.java @@ -24,7 +24,7 @@ public interface IBufferProvider /** * @author Eike Stepper */ - public interface Introspection + public interface Introspection extends IBufferProvider { public long getProvidedBuffers(); diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/TransportUtil.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/TransportUtil.java new file mode 100644 index 0000000000..69e381b4e6 --- /dev/null +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/transport/TransportUtil.java @@ -0,0 +1,51 @@ +/*************************************************************************** + * Copyright (c) 2004-2007 Eike Stepper, Germany. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Eike Stepper - initial API and implementation + **************************************************************************/ +package org.eclipse.net4j.transport; + +import org.eclipse.internal.net4j.transport.BufferFactory; +import org.eclipse.internal.net4j.transport.BufferPool; + +/** + * @author Eike Stepper + */ +public final class TransportUtil +{ + public static final short DEFAULT_BUFFER_CAPACITY = 4096; + + private TransportUtil() + { + } + + public static IBufferProvider.Introspection createBufferFactory(short bufferCapacity) + { + return new BufferFactory(bufferCapacity); + } + + public static IBufferProvider.Introspection createBufferFactory() + { + return new BufferFactory(DEFAULT_BUFFER_CAPACITY); + } + + public static IBufferPool.Introspection createBufferPool(IBufferProvider factory) + { + return new BufferPool(factory); + } + + public static IBufferPool.Introspection createBufferPool(short bufferCapacity) + { + return createBufferPool(createBufferFactory(bufferCapacity)); + } + + public static IBufferPool.Introspection createBufferPool() + { + return createBufferPool(createBufferFactory()); + } +} diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/ReflectUtil.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/ReflectUtil.java index fdc7ab2c30..8488783487 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/ReflectUtil.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/ReflectUtil.java @@ -13,6 +13,10 @@ package org.eclipse.net4j.util; import org.eclipse.internal.net4j.util.lifecycle.Lifecycle; import java.io.PrintStream; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; @@ -196,6 +200,11 @@ public final class ReflectUtil continue; } + if (field.getAnnotation(ExcludeFromDump.class) != null) + { + continue; + } + builder.append(prefix); builder.append(segmentPrefix); builder.append(field.getName()); @@ -246,4 +255,13 @@ public final class ReflectUtil return method; } + + /** + * @author Eike Stepper + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.FIELD) + public @interface ExcludeFromDump + { + } } diff --git a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/lifecycle/LifecycleUtil.java b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/lifecycle/LifecycleUtil.java index c55c8216b0..43d724ec31 100644 --- a/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/lifecycle/LifecycleUtil.java +++ b/plugins/org.eclipse.net4j/src/org/eclipse/net4j/util/lifecycle/LifecycleUtil.java @@ -13,8 +13,13 @@ package org.eclipse.net4j.util.lifecycle; import org.eclipse.net4j.util.om.trace.ContextTracer; import org.eclipse.internal.net4j.bundle.Net4j; +import org.eclipse.internal.net4j.util.lifecycle.Lifecycle; import java.lang.annotation.Annotation; +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; import java.lang.reflect.Method; /** @@ -128,6 +133,14 @@ public final class LifecycleUtil } } + public static void dump(Object object) + { + if (object instanceof Lifecycle) + { + ((Lifecycle)object).dump(); + } + } + private static void invokeAnnotation(Object object, Class annotationClass) { Class c = object.getClass(); @@ -187,4 +200,24 @@ public final class LifecycleUtil return null; } + + /** + * @author Eike Stepper + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface Activator + { + boolean propagate() default true; + } + + /** + * @author Eike Stepper + */ + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface Deactivator + { + boolean propagate() default true; + } } |