You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2012/01/13 12:54:29 UTC

svn commit: r1231027 - /river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java

Author: peter_firmstone
Date: Fri Jan 13 11:54:29 2012
New Revision: 1231027

URL: http://svn.apache.org/viewvc?rev=1231027&view=rev
Log:
River-142

Affects only River 2.2.0, this bug causes a memory leak by creating new threads unnecessarily.

Modified:
    river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java

Modified: river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java?rev=1231027&r1=1231026&r2=1231027&view=diff
==============================================================================
--- river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java (original)
+++ river/jtsk/skunk/peterConcurrentPolicy/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java Fri Jan 13 11:54:29 2012
@@ -64,8 +64,11 @@ final class ObjectTable {
     /** thread to check for expired leases */
     private Thread leaseChecker;
     
-    /** thread guard */
-    private Boolean running;
+    /** expired lease thread guard */
+    private final Object runLock;
+    
+    /** flag to indicate expired lease thread started */
+    private volatile boolean running;
 
     ObjectTable() { 
         requestDispatchersLock = new Object();
@@ -73,7 +76,8 @@ final class ObjectTable {
         keepAliveCount = new JvmLifeSupport();
         leaseTable = new ConcurrentHashMap<Uuid,Lease>(256);//Plenty of capacity to reduce resizing.
         leaseChecker = null;
-        running = Boolean.FALSE;
+        running = false;
+        runLock = new Object();
     }
 
     RequestDispatcher createRequestDispatcher(Unreferenced unrefCallback) {
@@ -289,13 +293,17 @@ final class ObjectTable {
              * Then because the late clean call sequence number is less than the 
              * second dirty call and exists, it is correctly recognised.
              */
-            synchronized (running){
-                if (!running) {
-                    leaseChecker =
-                        (Thread) AccessController.doPrivileged(
-                            new NewThreadAction(new LeaseChecker(),
-                                "DGC Lease Checker", true));
-                    leaseChecker.start();
+            // This must be performed after changing the leaseTable
+            if (!running){ // double checked
+                synchronized (runLock){
+                    if (!running) {
+                        leaseChecker =
+                            (Thread) AccessController.doPrivileged(
+                                new NewThreadAction(new LeaseChecker(),
+                                    "DGC Lease Checker", true));
+                        leaseChecker.start();
+                        running = true;
+                    }
                 }
             }
             for (int i = 0; i < ids.length; i++) {
@@ -359,9 +367,9 @@ final class ObjectTable {
                 // This is always executed and returns the lease checker
                 // to the non running state, such that if the application
                 // has not exited, another thread will be started eventually.
-                synchronized (running){
+                synchronized (runLock){
                     leaseChecker = null;
-                    running = Boolean.FALSE;               
+                    running = false;               
                 }
             }
 	}