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/14 11:52:27 UTC
svn commit: r1231478 -
/river/jtsk/trunk/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java
Author: peter_firmstone
Date: Sat Jan 14 10:52:27 2012
New Revision: 1231478
URL: http://svn.apache.org/viewvc?rev=1231478&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/trunk/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java
Modified: river/jtsk/trunk/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java
URL: http://svn.apache.org/viewvc/river/jtsk/trunk/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java?rev=1231478&r1=1231477&r2=1231478&view=diff
==============================================================================
--- river/jtsk/trunk/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java (original)
+++ river/jtsk/trunk/src/com/sun/jini/jeri/internal/runtime/ObjectTable.java Sat Jan 14 10:52:27 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;
}
}
}