[jboss-remoting-commits] JBoss Remoting SVN: r4434 - remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi.

jboss-remoting-commits at lists.jboss.org jboss-remoting-commits at lists.jboss.org
Mon Jul 28 18:04:33 EDT 2008


Author: david.lloyd at jboss.com
Date: 2008-07-28 18:04:33 -0400 (Mon, 28 Jul 2008)
New Revision: 4434

Modified:
   remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java
Log:
Add leak tracking

Modified: remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java
===================================================================
--- remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java	2008-07-28 21:11:10 UTC (rev 4433)
+++ remoting3/trunk/api/src/main/java/org/jboss/cx/remoting/spi/AbstractCloseable.java	2008-07-28 22:04:33 UTC (rev 4434)
@@ -31,6 +31,7 @@
 import java.util.HashSet;
 import java.util.Set;
 import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
 import java.util.concurrent.atomic.AtomicBoolean;
 
 /**
@@ -46,6 +47,19 @@
     private final AtomicBoolean closed = new AtomicBoolean();
     private Set<CloseHandler<? super T>> closeHandlers;
 
+    private static final boolean LEAK_DEBUGGING;
+    private final StackTraceElement[] backtrace;
+
+    static {
+        boolean b = false;
+        try {
+            b = Boolean.parseBoolean(System.getProperty("jboss.remoting.leakdebugging", "false"));
+        } catch (SecurityException se) {
+            b = false;
+        }
+        LEAK_DEBUGGING = b;
+    }
+
     /**
      * Basic constructor.
      *
@@ -56,6 +70,7 @@
             throw new NullPointerException("executor is null");
         }
         this.executor = executor;
+        backtrace = LEAK_DEBUGGING ? new Throwable().getStackTrace() : null;
     }
 
     /**
@@ -84,12 +99,16 @@
             synchronized (closeLock) {
                 if (closeHandlers != null) {
                     for (final CloseHandler<? super T> handler : closeHandlers) {
-                        executor.execute(new Runnable() {
-                            @SuppressWarnings({ "unchecked" })
-                            public void run() {
-                                SpiUtils.safeHandleClose(handler, (T) AbstractCloseable.this);
-                            }
-                        });
+                        try {
+                            executor.execute(new Runnable() {
+                                @SuppressWarnings({ "unchecked" })
+                                public void run() {
+                                    SpiUtils.safeHandleClose(handler, (T) AbstractCloseable.this);
+                                }
+                            });
+                        } catch (RejectedExecutionException ree) {
+                            log.warn("Unable to execute close handler (execution rejected) for %s (%s)", this, ree.getMessage());
+                        }
                     }
                     closeHandlers = null;
                 }
@@ -127,9 +146,26 @@
             super.finalize();
         } finally {
             if (isOpen()) {
-                log.warn("Leaked a %s instance!", getClass().getName());
+                if (LEAK_DEBUGGING) {
+                    final Throwable t = new LeakThrowable();
+                    t.setStackTrace(backtrace);
+                    log.warn(t, "Leaked a %s instance: %s", getClass().getName(), this);
+                } else {
+                    log.warn("Leaked a %s instance: %s", getClass().getName(), this);
+                }
                 IoUtils.safeClose(this);
             }
         }
     }
+
+    @SuppressWarnings({ "serial" })
+    private static final class LeakThrowable extends Throwable {
+
+        public LeakThrowable() {
+        }
+
+        public String toString() {
+            return "a leaked reference";
+        }
+    }
 }




More information about the jboss-remoting-commits mailing list