cxf-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dk...@apache.org
Subject svn commit: r997963 - in /cxf/trunk: api/src/main/java/org/apache/cxf/BusFactory.java rt/core/src/main/java/org/apache/cxf/bus/CXFBusImpl.java rt/core/src/main/resources/META-INF/cxf/cxf.xml
Date Fri, 17 Sep 2010 02:34:48 GMT
Author: dkulp
Date: Fri Sep 17 02:34:48 2010
New Revision: 997963

URL: http://svn.apache.org/viewvc?rev=997963&view=rev
Log:
[CXF-2985] Better method of mapping a Bus to a thread to prevent memory
leaks.
Patch from Mauro Molinari applied

Modified:
    cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java
    cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/CXFBusImpl.java
    cxf/trunk/rt/core/src/main/resources/META-INF/cxf/cxf.xml

Modified: cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java
URL: http://svn.apache.org/viewvc/cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java?rev=997963&r1=997962&r2=997963&view=diff
==============================================================================
--- cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java (original)
+++ cxf/trunk/api/src/main/java/org/apache/cxf/BusFactory.java Fri Sep 17 02:34:48 2010
@@ -22,6 +22,9 @@ package org.apache.cxf;
 import java.io.BufferedReader;
 import java.io.InputStream;
 import java.io.InputStreamReader;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.WeakHashMap;
 import java.util.logging.Level;
 import java.util.logging.Logger;
 
@@ -34,7 +37,7 @@ public abstract class BusFactory {
     public static final String DEFAULT_BUS_FACTORY = "org.apache.cxf.bus.CXFBusFactory";
 
     protected static Bus defaultBus;
-    protected static ThreadLocal<Bus> localBus = new ThreadLocal<Bus>();
+    protected static Map<Thread, Bus> threadBusses = new WeakHashMap<Thread, Bus>();
 
     private static final Logger LOG = LogUtils.getL7dLogger(BusFactory.class, "APIMessages");
     
@@ -86,7 +89,9 @@ public abstract class BusFactory {
      * @param bus the default bus.
      */
     public static void setThreadDefaultBus(Bus bus) {
-        localBus.set(bus);
+        synchronized (threadBusses) {
+            threadBusses.put(Thread.currentThread(), bus);
+        }
     }
     
     /**
@@ -102,11 +107,40 @@ public abstract class BusFactory {
      * @return the default bus.
      */
     public static Bus getThreadDefaultBus(boolean createIfNeeded) {
-        if (createIfNeeded && localBus.get() == null) {
-            Bus b = getDefaultBus(createIfNeeded);
-            localBus.set(b);
+        Bus threadBus;
+        synchronized (threadBusses) {
+            if (createIfNeeded) {
+                threadBus = threadBusses.get(Thread.currentThread());
+                if (createIfNeeded && threadBus == null) {
+                    threadBus = getDefaultBus(createIfNeeded);
+                    threadBusses.put(Thread.currentThread(), threadBus);
+                }
+            } else {
+                threadBus = threadBusses.get(Thread.currentThread());
+            }
+        }
+        return threadBus;
+    }
+
+    /**
+     * Removes a bus from being a thread default bus for any thread.
+     * <p>
+     * This is tipically done when a bus has ended its lifecycle (i.e.: a call
+     * to {@link Bus#shutdown(boolean)} was invoked) and it wants to remove any
+     * reference to itself for any thread.
+     * 
+     * @param bus
+     *            the bus to remove
+     */
+    public static void clearDefaultBusForAnyThread(final Bus bus) {
+        synchronized (threadBusses) {
+            for (final Iterator<Bus> iterator = threadBusses.values().iterator(); 
+                iterator.hasNext();) {
+                if (bus == null || bus.equals(iterator.next())) {
+                    iterator.remove();
+                }
+            }
         }
-        return localBus.get();
     }
 
     /**
@@ -115,8 +149,10 @@ public abstract class BusFactory {
      * @return true if the bus was not set and is now set
      */
     public static synchronized boolean possiblySetDefaultBus(Bus bus) {
-        if (localBus.get() == null) {
-            localBus.set(bus);
+        synchronized (threadBusses) {
+            if (threadBusses.get(Thread.currentThread()) == null) {
+                threadBusses.put(Thread.currentThread(), bus);
+            }
         }
         
         if (defaultBus == null) {

Modified: cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/CXFBusImpl.java
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/CXFBusImpl.java?rev=997963&r1=997962&r2=997963&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/CXFBusImpl.java (original)
+++ cxf/trunk/rt/core/src/main/java/org/apache/cxf/bus/CXFBusImpl.java Fri Sep 17 02:34:48
2010
@@ -146,6 +146,10 @@ public class CXFBusImpl extends Abstract
         }
     }
 
+    public void shutdown() {
+        shutdown(true);
+    }
+
     public void shutdown(boolean wait) {
         BusLifeCycleManager lifeCycleManager = this.getExtension(BusLifeCycleManager.class);
         if (null != lifeCycleManager) {
@@ -158,9 +162,11 @@ public class CXFBusImpl extends Abstract
         if (null != lifeCycleManager) {
             lifeCycleManager.postShutdown();
         }
-        if (BusFactory.getDefaultBus(false) == this) { 
+
+        if (BusFactory.getDefaultBus(false) == this) {
             BusFactory.setDefaultBus(null);
         }
+        BusFactory.clearDefaultBusForAnyThread(this);
     }
 
     protected BusState getState() {

Modified: cxf/trunk/rt/core/src/main/resources/META-INF/cxf/cxf.xml
URL: http://svn.apache.org/viewvc/cxf/trunk/rt/core/src/main/resources/META-INF/cxf/cxf.xml?rev=997963&r1=997962&r2=997963&view=diff
==============================================================================
--- cxf/trunk/rt/core/src/main/resources/META-INF/cxf/cxf.xml (original)
+++ cxf/trunk/rt/core/src/main/resources/META-INF/cxf/cxf.xml Fri Sep 17 02:34:48 2010
@@ -29,7 +29,7 @@ http://www.springframework.org/schema/co
 		<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
 		<context:annotation-config/>
 	-->
-    <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl"/>
+    <bean id="cxf" class="org.apache.cxf.bus.CXFBusImpl" destroy-method="shutdown"/>
     <bean id="org.apache.cxf.bus.spring.BusApplicationListener" 
     	class="org.apache.cxf.bus.spring.BusApplicationListener"/>
     <bean id="org.apache.cxf.bus.spring.BusWiringBeanFactoryPostProcessor" 



Mime
View raw message