X-Git-Url: https://code.wpia.club/?p=gigi.git;a=blobdiff_plain;f=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2FLeakDetector.java;fp=lib%2Fjetty%2Forg%2Feclipse%2Fjetty%2Futil%2FLeakDetector.java;h=11b3b31a83a153480e2ac4546d708cd6afeea7bd;hp=b0ac94e9b4d0f5cb2cbf2b6b8dc71bafd23c74b0;hb=aa5723dbb64ec8efa63909d39ff72364f0a5ee96;hpb=e443f19911df6a30ab07ef70d23970bda671b194 diff --git a/lib/jetty/org/eclipse/jetty/util/LeakDetector.java b/lib/jetty/org/eclipse/jetty/util/LeakDetector.java index b0ac94e9..11b3b31a 100644 --- a/lib/jetty/org/eclipse/jetty/util/LeakDetector.java +++ b/lib/jetty/org/eclipse/jetty/util/LeakDetector.java @@ -1,6 +1,6 @@ // // ======================================================================== -// Copyright (c) 1995-2014 Mort Bay Consulting Pty. Ltd. +// Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd. // ------------------------------------------------------------------------ // All rights reserved. This program and the accompanying materials // are made available under the terms of the Eclipse Public License v1.0 @@ -31,40 +31,29 @@ import org.eclipse.jetty.util.log.Logger; /** * A facility to detect improper usage of resource pools. *

- * Resource pools usually have a method to acquire a pooled resource - * and a method to released it back to the pool. + * Resource pools usually have a method to acquire a pooled resource and a method to released it back to the pool. *

- * To detect if client code acquires a resource but never releases it, - * the resource pool can be modified to use a {@link LeakDetector}. - * The modified resource pool should call {@link #acquired(Object)} every time - * the method to acquire a resource is called, and {@link #released(Object)} - * every time the method to release the resource is called. + * To detect if client code acquires a resource but never releases it, the resource pool can be modified to use a + * {@link LeakDetector}. The modified resource pool should call {@link #acquired(Object)} every time the method to + * acquire a resource is called, and {@link #released(Object)} every time the method to release the resource is called. * {@link LeakDetector} keeps track of these resources and invokes method - * {@link #leaked(org.eclipse.jetty.util.LeakDetector.LeakInfo)} when it detects that a resource - * has been leaked (that is, acquired but never released). + * {@link #leaked(org.eclipse.jetty.util.LeakDetector.LeakInfo)} when it detects that a resource has been leaked (that + * is, acquired but never released). *

- * To detect whether client code releases a resource without having - * acquired it, the resource pool can be modified to check the return value - * of {@link #released(Object)}: if false, it means that the resource was - * not acquired. + * To detect whether client code releases a resource without having acquired it, the resource pool can be modified to + * check the return value of {@link #released(Object)}: if false, it means that the resource was not acquired. *

* IMPLEMENTATION NOTES *

- * This class relies on {@link System#identityHashCode(Object)} to create - * a unique id for each resource passed to {@link #acquired(Object)} and - * {@link #released(Object)}. {@link System#identityHashCode(Object)} does - * not guarantee that it will not generate the same number for different - * objects, but in practice the chance of collision is rare. + * This class relies on {@link System#identityHashCode(Object)} to create a unique id for each resource passed to + * {@link #acquired(Object)} and {@link #released(Object)}. {@link System#identityHashCode(Object)} does not guarantee + * that it will not generate the same number for different objects, but in practice the chance of collision is rare. *

- * {@link LeakDetector} uses {@link PhantomReference}s to detect leaks. - * {@link PhantomReference}s are enqueued in their {@link ReferenceQueue} - * after they have been garbage collected (differently from - * {@link WeakReference}s that are enqueued before). - * Since the resource is now garbage collected, {@link LeakDetector} checks - * whether it has been released and if not, it reports a leak. - * Using {@link PhantomReference}s is better than overriding {@link #finalize()} - * and works also in those cases where {@link #finalize()} is not - * overridable. + * {@link LeakDetector} uses {@link PhantomReference}s to detect leaks. {@link PhantomReference}s are enqueued in their + * {@link ReferenceQueue} after they have been garbage collected (differently from {@link WeakReference}s that + * are enqueued before). Since the resource is now garbage collected, {@link LeakDetector} checks whether it + * has been released and if not, it reports a leak. Using {@link PhantomReference}s is better than overriding + * {@link #finalize()} and works also in those cases where {@link #finalize()} is not overridable. * * @param the resource type. */ @@ -80,26 +69,43 @@ public class LeakDetector extends AbstractLifeCycle implements Runnable * Tracks the resource as been acquired. * * @param resource the resource that has been acquired - * @return whether the resource has been tracked + * @return true whether the resource has been acquired normally, false if the resource has detected a leak (meaning + * that another acquire occurred before a release of the same resource) * @see #released(Object) */ public boolean acquired(T resource) { String id = id(resource); - return resources.putIfAbsent(id, new LeakInfo(resource, id)) == null; + LeakInfo info = resources.putIfAbsent(id, new LeakInfo(resource,id)); + if (info != null) + { + // Leak detected, prior acquire exists (not released) or id clash. + return false; + } + // Normal behavior. + return true; } /** * Tracks the resource as been released. * * @param resource the resource that has been released - * @return whether the resource has been acquired + * @return true whether the resource has been released normally (based on a previous acquire). false if the resource + * has been released without a prior acquire (such as a double release scenario) * @see #acquired(Object) */ public boolean released(T resource) { String id = id(resource); - return resources.remove(id) != null; + LeakInfo info = resources.remove(id); + if (info != null) + { + // Normal behavior. + return true; + } + + // Leak detected (released without acquire). + return false; } /** @@ -108,7 +114,7 @@ public class LeakDetector extends AbstractLifeCycle implements Runnable * @param resource the resource to generate the unique ID for * @return the unique ID of the given resource */ - protected String id(T resource) + public String id(T resource) { return String.valueOf(System.identityHashCode(resource)); } @@ -117,7 +123,7 @@ public class LeakDetector extends AbstractLifeCycle implements Runnable protected void doStart() throws Exception { super.doStart(); - thread = new Thread(this, getClass().getSimpleName()); + thread = new Thread(this,getClass().getSimpleName()); thread.setDaemon(true); thread.start(); } @@ -125,8 +131,8 @@ public class LeakDetector extends AbstractLifeCycle implements Runnable @Override protected void doStop() throws Exception { - thread.interrupt(); super.doStop(); + thread.interrupt(); } @Override @@ -138,7 +144,8 @@ public class LeakDetector extends AbstractLifeCycle implements Runnable { @SuppressWarnings("unchecked") LeakInfo leakInfo = (LeakInfo)queue.remove(); - LOG.debug("Resource GC'ed: {}", leakInfo); + if (LOG.isDebugEnabled()) + LOG.debug("Resource GC'ed: {}",leakInfo); if (resources.remove(leakInfo.id) != null) leaked(leakInfo); } @@ -156,7 +163,7 @@ public class LeakDetector extends AbstractLifeCycle implements Runnable */ protected void leaked(LeakInfo leakInfo) { - LOG.warn("Resource leaked: " + leakInfo.description, leakInfo.stackFrames); + LOG.warn("Resource leaked: " + leakInfo.description,leakInfo.stackFrames); } /** @@ -170,7 +177,7 @@ public class LeakDetector extends AbstractLifeCycle implements Runnable private LeakInfo(T referent, String id) { - super(referent, queue); + super(referent,queue); this.id = id; this.description = referent.toString(); this.stackFrames = new Throwable();