river-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From peter_firmst...@apache.org
Subject svn commit: r1482594 - in /river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm: ./ event/ lookup/
Date Tue, 14 May 2013 21:19:39 GMT
Author: peter_firmstone
Date: Tue May 14 21:19:38 2013
New Revision: 1482594

URL: http://svn.apache.org/r1482594
Log:
Fix race conditions found in Norm, more were found than expected or seen in other service implementations, which tends to suggest Norm isn't deployed as often or isn't under as much load.

Norm now utilises com.sun.jini.start.Starter to allow delaying of threads starting until after construction is complete, many fields are now final.

Added:
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerInitializer.java
Modified:
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ActivatableNormServerImpl.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ClientLeaseWrapper.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LRMEventListener.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseExpirationMgr.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseSet.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerBaseImpl.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentNormServerImpl.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/TransientNormServerImpl.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/UIDGenerator.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventType.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventTypeGenerator.java
    river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/lookup/JoinState.java

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ActivatableNormServerImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ActivatableNormServerImpl.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ActivatableNormServerImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ActivatableNormServerImpl.java Tue May 14 21:19:38 2013
@@ -100,47 +100,65 @@ class ActivatableNormServerImpl extends 
     ActivatableNormServerImpl(ActivationID activationID, MarshalledObject data)
 	throws Exception
     {
-	super(true /* persistent */);
-	String[] configOptions = null;
-	try {
+        /* Any Exception thrown happens prior to super being called, so this
+         * isn't susceptible to finalizer attacks.
+         */
+        this(init(getConfigOptions(activationID, data), new Init(true /* persistent */)));
+    }
+    
+    private ActivatableNormServerImpl(NormServerInitializer init){
+        super(init);
+        this.activationSystem = ((Init) init).activationSystem;
+        this.activationID = ((Init) init).activationID;
+    }
+    
+    private static String[] getConfigOptions(ActivationID activationID, MarshalledObject data) throws Exception{
+        try {
 	    if (activationID == null) {
 		throw new NullPointerException("activationID is null");
 	    }
-	    configOptions = (String[]) data.get();
+	    return (String[]) data.get();
 	} catch (Throwable e) {
 	    initFailed(e);
 	}
-	this.activationID = activationID;
-	init(configOptions, null);
+        return new String[0]; // Unreachable, keeps compiler happy.
     }
+    
+    private static class Init extends NormServerInitializer {
+        private ActivationSystem activationSystem;
+        private ActivationID activationID;
+        
+        Init(boolean persistent){
+            super(persistent, null);
+        }
+        void initAsSubject(Configuration config) throws Exception {
+            ProxyPreparer activationSystemPreparer =
+                (ProxyPreparer) Config.getNonNullEntry(
+                    config, NORM, "activationSystemPreparer", ProxyPreparer.class,
+                    new BasicProxyPreparer());
+            activationSystem =
+                (ActivationSystem) activationSystemPreparer.prepareProxy(
+                    ActivationGroup.getSystem());
+            ProxyPreparer activationIdPreparer = (ProxyPreparer)
+                Config.getNonNullEntry(
+                    config, NORM, "activationIdPreparer", ProxyPreparer.class,
+                    new BasicProxyPreparer());
+            activationID = (ActivationID) activationIdPreparer.prepareProxy(
+                activationID);
+            super.initAsSubject(config);
+        }
 
-    void initAsSubject(Configuration config) throws Exception {
-	ProxyPreparer activationSystemPreparer =
-	    (ProxyPreparer) Config.getNonNullEntry(
-		config, NORM, "activationSystemPreparer", ProxyPreparer.class,
-		new BasicProxyPreparer());
-	activationSystem =
-	    (ActivationSystem) activationSystemPreparer.prepareProxy(
-		ActivationGroup.getSystem());
-	ProxyPreparer activationIdPreparer = (ProxyPreparer)
-	    Config.getNonNullEntry(
-		config, NORM, "activationIdPreparer", ProxyPreparer.class,
-		new BasicProxyPreparer());
-	activationID = (ActivationID) activationIdPreparer.prepareProxy(
-	    activationID);
-	super.initAsSubject(config);
-    }
-
-    Exporter getExporter(Configuration config)
-	throws ConfigurationException
-    {
-	Exporter result = (Exporter) Config.getNonNullEntry(
-	    config, NORM, "serverExporter", Exporter.class,
-	    new ActivationExporter(
-		activationID,
-		new BasicJeriExporter(
-		    TcpServerEndpoint.getInstance(0), new BasicILFactory())),
-	    activationID);
-	return result;
+        Exporter getExporter(Configuration config)
+            throws ConfigurationException
+        {
+            Exporter result = (Exporter) Config.getNonNullEntry(
+                config, NORM, "serverExporter", Exporter.class,
+                new ActivationExporter(
+                    activationID,
+                    new BasicJeriExporter(
+                        TcpServerEndpoint.getInstance(0), new BasicILFactory())),
+                activationID);
+            return result;
+        }
     }
 }

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ClientLeaseWrapper.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ClientLeaseWrapper.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ClientLeaseWrapper.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/ClientLeaseWrapper.java Tue May 14 21:19:38 2013
@@ -645,9 +645,9 @@ class ClientLeaseWrapper implements Leas
     // things could happen if the wrapper then changes -- right now
     // the wrapper won't change after this method is called but in the 
     // future who is to say.
-    private class FailureFactory implements EventFactory {
+    private static class FailureFactory implements EventFactory {
 	/** Source for event */
-	private LeaseRenewalSet source;
+	private final LeaseRenewalSet source;
 	
 	/** Client lease that could not be renewed in marshalled form */
 	final private MarshalledInstance marshalledLease;

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LRMEventListener.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LRMEventListener.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LRMEventListener.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LRMEventListener.java Tue May 14 21:19:38 2013
@@ -41,7 +41,7 @@ class LRMEventListener extends Interrupt
     private static final Logger logger = Logger.getLogger("com.sun.jini.norm");
 
     /** Ref to the main server object which has all the top level methods */
-    final private NormServerBaseImpl server;
+    volatile private NormServerBaseImpl server;
 
     /**
      * Queue we use to decouple the reception of events from the lease
@@ -66,6 +66,21 @@ class LRMEventListener extends Interrupt
 	setDaemon(true);
 	this.server = server;	
     }
+    
+    LRMEventListener() {
+        super("LRM Event Listener");
+	setDaemon(true);
+    }
+    
+    /**
+     * Set only once after construction.
+     * @param server 
+     */
+    void setServer(NormServerBaseImpl server){
+        synchronized (this){
+            if (this.server == null) this.server = server;
+        }
+    }
 
     //////////////////////////////////////////////////
     // Methods required by the LeaseListener interface 

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseExpirationMgr.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseExpirationMgr.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseExpirationMgr.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseExpirationMgr.java Tue May 14 21:19:38 2013
@@ -56,16 +56,16 @@ class LeaseExpirationMgr implements Weak
      * there is a small window where a task could remove the ticket
      * for its replacement.
      */
-    private WeakTable		ticketMap = new WeakTable(this); 
+    private final WeakTable ticketMap; 
 
     /** Ref to the main server object has all the top level methods */
-    private NormServerBaseImpl	server;
+    private volatile NormServerBaseImpl	server;
 
     /** Queue of tasks, ordered by time */
-    private WakeupManager	runQueue = new WakeupManager();
+    private final WakeupManager	runQueue = new WakeupManager();
 
     /** Queue of tasks to expire sets */
-    final List expireQueue = new LinkedList();
+    private final List expireQueue = new LinkedList();
 
     /** Thread to expire sets */
     private final Thread expireThread = new ExpirationThread();
@@ -76,7 +76,25 @@ class LeaseExpirationMgr implements Weak
      */
     LeaseExpirationMgr(NormServerBaseImpl server) {
 	this.server = server;
-	expireThread.start();
+        ticketMap = new WeakTable(this); //this escape is safe.
+    }
+    
+    LeaseExpirationMgr(){
+        ticketMap = new WeakTable(this); //this escape is safe.
+    }
+    
+    /**
+     * Can be set once only after construction.
+     * @param server 
+     */
+    void setServer(NormServerBaseImpl server){
+        synchronized (this){
+            if (this.server == null) this.server = server;
+        }
+    }
+    
+    void start(){
+        expireThread.start();
     }
 
     /**
@@ -105,7 +123,7 @@ class LeaseExpirationMgr implements Weak
     /**
      * Notifies the manager of a lease being renewed. <p>
      *
-     * This method assumes the lock on <code>set</code> is owned by the
+     * This method assumes the lock on <code>resource</code> is owned by the
      * current thread.
      *
      * @param resource the set for which tasks have to be rescheduled
@@ -279,7 +297,7 @@ class LeaseExpirationMgr implements Weak
      */
     private class Expiration implements Runnable {
 
-	private LeaseSet set;
+	private final LeaseSet set;
 	/**
 	 * Create a <code>Expiration</code> task for the passed resource.
 	 *

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseSet.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseSet.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseSet.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/LeaseSet.java Tue May 14 21:19:38 2013
@@ -449,7 +449,7 @@ class LeaseSet implements Serializable, 
      * Nested class that implements <code>EventFactory</code> that
      * generates <code>ExpirationWarningEvent</code>s.
      */
-    private class WarningFactory implements EventFactory {
+    private static class WarningFactory implements EventFactory {
 	private static final long serialVersionUID = 1L;
 
 	/** The source for the event */

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerBaseImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerBaseImpl.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerBaseImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerBaseImpl.java Tue May 14 21:19:38 2013
@@ -98,7 +98,10 @@ import com.sun.jini.proxy.ThrowThis;
 import com.sun.jini.start.LifeCycle;
 import com.sun.jini.reliableLog.LogException;
 import com.sun.jini.reliableLog.LogHandler;
+import com.sun.jini.start.Starter;
 import com.sun.jini.thread.InterruptedStatusThread;
+import java.security.AccessControlContext;
+import java.security.AccessController;
 
 /**
  * Base class for implementations of NormServer.  Provides a complete
@@ -107,7 +110,7 @@ import com.sun.jini.thread.InterruptedSt
  * @author Sun Microsystems, Inc.
  */
 abstract class NormServerBaseImpl
-    implements NormServer, LocalLandlord, ServerProxyTrust, ProxyAccessor
+    implements NormServer, LocalLandlord, ServerProxyTrust, ProxyAccessor, Starter
 {
     /** Current version of log format */
     private static final int CURRENT_LOG_VERSION = 2;
@@ -122,121 +125,126 @@ abstract class NormServerBaseImpl
     final boolean persistent;
 
     /** The login context, for logging out */
-    LoginContext loginContext;
+    final LoginContext loginContext;
 
     /** The location of our persistent storage, or null if not persistent. */
-    String persistenceDirectory;
+    final String persistenceDirectory;
 
     /** Proxy preparer for leases supplied through the API */
-    private ProxyPreparer leasePreparer;
+    final private ProxyPreparer leasePreparer;
 
     /**
      * Proxy preparer for leases recovered from persistent storage, or null if
      * not persistent.
      */
-    private ProxyPreparer recoveredLeasePreparer;
+    final private ProxyPreparer recoveredLeasePreparer;
 
     /** Proxy preparer for listeners supplied through the API */
-    private ProxyPreparer listenerPreparer;
+    final private ProxyPreparer listenerPreparer;
 
     /**
      * Proxy preparer for listeners recovered from persistent storage, or null
      * if not persistent.
      */
-    private ProxyPreparer recoveredListenerPreparer;
+    final private ProxyPreparer recoveredListenerPreparer;
 
     /**
      * Proxy preparer for lookup locators supplied through the API, and not
      * including initial lookup locators.
      */
-    private ProxyPreparer locatorPreparer;
+    final private ProxyPreparer locatorPreparer;
 
     /**
      * Proxy preparer for lookup locators recovered from persistent storage, or
      * null if not persistent.
      */
-    private ProxyPreparer recoveredLocatorPreparer;
+    final private ProxyPreparer recoveredLocatorPreparer;
 
     /** The exporter for exporting and unexporting */
-    Exporter exporter;
+    final Exporter exporter;
 
     /** Object to notify when this service is destroyed, or null */
-    private LifeCycle lifeCycle;
+    final private LifeCycle lifeCycle;
 
     /** The unique ID for this server. */
-    private Uuid serverUuid;
+    volatile private Uuid serverUuid;
 
     /** Our JoinManager */
-    private JoinState joinState;
+    volatile private JoinState joinState;
 
     /** Map of Uuids to LeaseSets */
-    private Map setTable = Collections.synchronizedMap(new HashMap());
+    final private Map<Uuid,LeaseSet> setTable = Collections.synchronizedMap(new HashMap<Uuid,LeaseSet>());
 
     /** Lease renewal manager that actually renews the leases */
-    private LeaseRenewalManager lrm;
+    final private LeaseRenewalManager lrm;
 
     /** Object that expires sets and generates expiration warning events */
-    private LeaseExpirationMgr expMgr;
+    final private LeaseExpirationMgr expMgr;
 
     /** Factory for creating leases */
-    private LeaseFactory leaseFactory;
+    volatile private LeaseFactory leaseFactory;
 
     /** Policy we use for granting and renewing renewal set leases */
-    private LeasePeriodPolicy setLeasePolicy;
+    final private LeasePeriodPolicy setLeasePolicy;
 
     /**
      * Whether to isolate leases in their own renewal sets as opposed to
      * batching leases across sets.
      */
-    private boolean isolateSets;
+    final private boolean isolateSets;
 
     /** Our persistant store */
-    private PersistentStore store;
+    volatile private PersistentStore store;
 
     /** Factory we use to create ClientLeaseWrapper IDs */
-    private UIDGenerator idGen = new UIDGenerator() ;
+    final private UIDGenerator idGen = new UIDGenerator() ;
 
     /** List of leases that have been renewed but not persisted */
-    private List renewedList = new LinkedList();
+    final private List renewedList;
 
     /**
      * Thread that pulls wrapped client leases off the renewedList and logs
      * them to disk
      */
-    private RenewLogThread renewLogger;
+    final private RenewLogThread renewLogger;
 
     /** Object used to generate new event types */
-    private EventTypeGenerator generator;
+    volatile private EventTypeGenerator generator;
 
     /**
      * Object that transfers events from the renewal manager to
      * us so we can remove dead leases and send events
      */
-    private LRMEventListener lrmEventListener;
+    final private LRMEventListener lrmEventListener;
 
     /** Log file must contain this many records before snapshot allowed */
-    private int logToSnapshotThresh;
+    final private int logToSnapshotThresh;
 
     /** Weight factor applied to snapshotSize when deciding to take snapshot */
-    private float snapshotWt;
+    final private float snapshotWt;
 
     /** Inner server proxy */
-    NormServer serverProxy = null;
+    volatile NormServer serverProxy = null;
 
     /** Outer service proxy */
-    LeaseRenewalService normProxy = null;
+    volatile LeaseRenewalService normProxy = null;
 
     /** Admin proxy */
-    private AdminProxy adminProxy;
+    volatile private AdminProxy adminProxy;
 
     /** Thread that performs snapshots when signaled */
-    private SnapshotThread snapshotter;
+    volatile private SnapshotThread snapshotter;
 
     /** Lock protecting startup and shutdown */
     private final ReadyState ready = new ReadyState();
 
     /** Keep track of the number of leases. */
     private final CountLeases countLeases = new CountLeases();
+    
+    /** Fields access only by thread that called constructor, then called start()
+     *  set to null at completion of start() */
+    private AccessControlContext context;
+    private Configuration config;
 
     ////////////////////////////////
     // Methods defined in NormServer
@@ -973,17 +981,31 @@ abstract class NormServerBaseImpl
 
     //////////////////////////////////////////
     // Thread to persist client lease renewals
-    private class RenewLogThread extends InterruptedStatusThread {
+    static class RenewLogThread extends InterruptedStatusThread {
+        private PersistentStore store;
+        private final List renewedList;
 	/** Create a daemon thread */
-	private RenewLogThread() {
+	RenewLogThread(List renewedList) {
 	    super("log renewals thread");
 	    setDaemon(true);
+            this.renewedList = renewedList;
+            
 	}
+        
+        private void setStore(PersistentStore store){
+            synchronized (this){
+                if (this.store == null) this.store = store;
+            }
+        }
 
 	public void run() {
 	    while (!hasBeenInterrupted()) {
 		try {
 		    ClientLeaseWrapper clw;
+                    PersistentStore store;
+                    synchronized (this){
+                        store = this.store;
+                    }
 		    synchronized (renewedList) {
 			// If there is an item on the list pull it off for
 			// processing, otherwise wait and try again
@@ -1319,7 +1341,7 @@ abstract class NormServerBaseImpl
 	    serverUuid = (Uuid) oistream.readObject();
 	    generator = (EventTypeGenerator) oistream.readObject();
 	    final int size = oistream.readInt();
-	    setTable = Collections.synchronizedMap(new HashMap(size));
+	    setTable.clear();
 	    for (int i = 0; i < size; i++) {
 		final LeaseSet set = (LeaseSet) oistream.readObject();
 		setTable.put(set.getUuid(), set);
@@ -1345,11 +1367,13 @@ abstract class NormServerBaseImpl
      * Thread that performs the actual snapshots, done in a separate thread
      * so it will not hang up in-progress remote calls
      */
-    private class SnapshotThread extends InterruptedStatusThread {
+    class SnapshotThread extends InterruptedStatusThread {
+        private final PersistentStore store;
 	/** Create a daemon thread */
-	private SnapshotThread() {
+	SnapshotThread(PersistentStore store) {
 	    super("snapshot thread");
 	    setDaemon(true);
+            this.store = store;
 	}
 
 	/** Signal this thread that is should take a snapshot */
@@ -1716,37 +1740,36 @@ abstract class NormServerBaseImpl
      * Simple container for an alternative return a value so we
      * can provide more detailed diagnostics.
      */
-    class InitException extends Exception {
+    static class InitException extends Exception {
 	private static final long serialVersionUID = 1;
 	private InitException(String message, Throwable nested) {
 	    super(message, nested);
 	}
     }
-
+    
     /**
      * Portion of construction that is common between the activatable and not
      * activatable cases.  This method performs the minimum number of
      * operations before establishing the Subject, and logs errors.
      */
-    void init(String[] configOptions, LifeCycle lifeCycle)
+    static NormServerInitializer init(String[] configOptions, final NormServerInitializer init)
 	throws Exception
     {
 	try {
 	    final Configuration config = ConfigurationProvider.getInstance(
-		configOptions, getClass().getClassLoader());
-	    this.lifeCycle = lifeCycle;
-	    loginContext = (LoginContext) config.getEntry(
+		configOptions, NormServerBaseImpl.class.getClassLoader());
+	    init.loginContext = (LoginContext) config.getEntry(
 		NORM, "loginContext", LoginContext.class, null);
-	    if (loginContext == null) {
-		initAsSubject(config);
+	    if (init.loginContext == null) {
+		init.initAsSubject(config);
 	    } else {
-		loginContext.login();
+		init.loginContext.login();
 		try {
 		    Subject.doAsPrivileged(
-			loginContext.getSubject(),
+			init.loginContext.getSubject(),
 			new PrivilegedExceptionAction() {
 			    public Object run() throws Exception {
-				initAsSubject(config);
+				init.initAsSubject(config);
 				return null;
 			    }
 			},
@@ -1755,11 +1778,10 @@ abstract class NormServerBaseImpl
 		    throw e.getCause();
 		}
 	    }
-	    ready.ready();
-	    logger.log(Level.INFO, "Norm service started: {0}", this);
 	} catch (Throwable e) {
 	    initFailed(e);
 	}
+        return init;
     }
 
     /**
@@ -1788,10 +1810,7 @@ abstract class NormServerBaseImpl
 	} else if (e instanceof Error) {
 	    throw (Error) e;
 	} else {
-	    IllegalStateException ise =
-		new IllegalStateException(e.getMessage());
-	    ise.initCause(e);
-	    throw ise;
+	    throw new IllegalStateException(e);
 	}
     }
 
@@ -1807,167 +1826,142 @@ abstract class NormServerBaseImpl
 	r.setThrown(t);
 	logger.log(r);
     }
+    
+    public void start() throws Exception {
+        try {
+            AccessController.doPrivileged(new PrivilegedExceptionAction(){
+
+                @Override
+                public Object run() throws Exception {
+                    serverProxy = (NormServer) exporter.export(NormServerBaseImpl.this);
 
-    /**
-     * Common construction for activatable and non-activatable cases, run
-     * under the proper Subject.
-     */
-    void initAsSubject(Configuration config) throws Exception {
-	/* Get configuration entries first */
-	if (persistent) {
-	    persistenceDirectory = (String) Config.getNonNullEntry(
-		config, NORM, "persistenceDirectory", String.class);
-	    snapshotWt = Config.getFloatEntry(
-		config, NORM, "persistenceSnapshotWeight",
-		10, 0, Float.MAX_VALUE);
-	    logToSnapshotThresh = Config.getIntEntry(
-		config, NORM, "persistenceSnapshotThreshold",
-		200, 0, Integer.MAX_VALUE);
-	}
-	leasePreparer = (ProxyPreparer) Config.getNonNullEntry(
-	    config, NORM, "leasePreparer", ProxyPreparer.class,
-	    new BasicProxyPreparer());
-	listenerPreparer = (ProxyPreparer) Config.getNonNullEntry(
-	    config, NORM, "listenerPreparer", ProxyPreparer.class,
-	    new BasicProxyPreparer());
-	locatorPreparer = (ProxyPreparer) Config.getNonNullEntry(
-	    config, NORM, "locatorPreparer", ProxyPreparer.class,
-	    new BasicProxyPreparer());
-	if (persistent) {
-	    recoveredLeasePreparer = (ProxyPreparer) Config.getNonNullEntry(
-		config, NORM, "recoveredLeasePreparer", ProxyPreparer.class,
-		new BasicProxyPreparer());
-	    recoveredListenerPreparer =
-		(ProxyPreparer) Config.getNonNullEntry(
-		    config, NORM, "recoveredListenerPreparer",
-		    ProxyPreparer.class, new BasicProxyPreparer());
-	    recoveredLocatorPreparer = (ProxyPreparer) Config.getNonNullEntry(
-		config, NORM, "recoveredLocatorPreparer", ProxyPreparer.class,
-		new BasicProxyPreparer());
-	}
-	setLeasePolicy = (LeasePeriodPolicy) Config.getNonNullEntry(
-	    config, NORM, "leasePolicy", LeasePeriodPolicy.class,
-	    new FixedLeasePeriodPolicy(
-		2 * 60 * 60 * 1000 /* max */, 60 * 60 * 1000 /* default */));
-	isolateSets = ((Boolean) config.getEntry(
-	    NORM, "isolateSets", boolean.class, Boolean.FALSE)).booleanValue();
-	try {
-	    lrm = (LeaseRenewalManager) Config.getNonNullEntry(
-		config, NORM, "leaseManager", LeaseRenewalManager.class);
-	} catch (NoSuchEntryException e) {
-	    lrm = new LeaseRenewalManager(config);
-	}
-	exporter = getExporter(config);
+                    boolean done = false;
+                    try {
+                        // We use some of these during the recovery process
+                        expMgr.setServer(NormServerBaseImpl.this);
+                        lrmEventListener.setServer(NormServerBaseImpl.this);
 
-	serverProxy = (NormServer) exporter.export(this);
+                        try {
+                            store = new PersistentStore(
+                                persistenceDirectory, new OurLogHandler(), NormServerBaseImpl.this);
+                            // Creating the store completes the first two stages of 
+                            // log recovery (reading the snapshot and the updates)
+                            // Perform the last stage here of restoring transient state
+                            restoreTransientState();
+                            if (logger.isLoggable(Level.FINER)) {
+                                logger.log(Level.FINER, "Log recovered: {0}",
+                                           inventory());
+                            }
+
+                        } catch (CorruptedStoreException e) {
+                            throw new InitException("Log corrupted, can't recover ", e);
+                        } catch (StoreException e) {
+                            throw new InitException("Can't recover log", e);
+                        }
+                        
+                        renewLogger.setStore(store);
+                        snapshotter = new SnapshotThread(store);
 
-	boolean done = false;
-	try {
-	    // We use some of these during the recovery process
-	    expMgr = new LeaseExpirationMgr(this);
-	    generator = new EventTypeGenerator();
-	    lrmEventListener = new LRMEventListener(this);
-	    renewLogger = new RenewLogThread();
-	    snapshotter = new SnapshotThread();
+                        if (serverUuid == null) {
+                            serverUuid = UuidFactory.generate();
+                        }
+                        normProxy = NormProxy.create(serverProxy, serverUuid);
+                        adminProxy = AdminProxy.create(serverProxy, serverUuid);
 
-	    try {
-		store = new PersistentStore(
-		    persistenceDirectory, new OurLogHandler(), this);
-		// Creating the store completes the first two stages of 
-		// log recovery (reading the snapshot and the updates)
-		// Perform the last stage here of restoring transient state
-		restoreTransientState();
-		if (logger.isLoggable(Level.FINER)) {
-		    logger.log(Level.FINER, "Log recovered: {0}",
-			       inventory());
-		}
-
-	    } catch (CorruptedStoreException e) {
-		throw new InitException("Log corrupted, can't recover ", e);
-	    } catch (StoreException e) {
-		throw new InitException("Can't recover log", e);
-	    }
+                        // Create new baseline snapshot
+                        try {
+                            store.snapshot();
+                            if (logger.isLoggable(Level.FINER)) {
+                                logger.log(
+                                    Level.FINER, "Completed new baseline snapshot: {0}",
+                                    inventory());
+                            }
+                        } catch (IOException e) {
+                            throw new InitException(
+                                "Can't create new baseline snapshot", e);
+                        }
 
-	    if (serverUuid == null) {
-		serverUuid = UuidFactory.generate();
-	    }
-	    normProxy = NormProxy.create(serverProxy, serverUuid);
-	    adminProxy = AdminProxy.create(serverProxy, serverUuid);
+                        Entry[] serviceAttributes = {
+                            new ServiceInfo(
+                                "Lease Renewal Service",		// name
+                                "Sun Microsystems, Inc.",		// manufacturer
+                                "Sun Microsystems, Inc.",		// vender
+                                VersionConstants.SERVER_VERSION,	// version
+                                "",					// model
+                                ""),				// serialNumber
+                            new BasicServiceType("Lease Renewal Service")
+                        };
+                        try {
+                            JoinState joinState = new JoinState(
+                                normProxy, lrm, config, serviceAttributes,
+                                recoveredLocatorPreparer,
+                                new ServiceID(serverUuid.getMostSignificantBits(),
+                                              serverUuid.getLeastSignificantBits()));
+                            store.addSubStore(joinState);
+                            // joinState is mutated when added to store, makes
+                            // sure that's published after mutation.
+                            NormServerBaseImpl.this.joinState = joinState;
+                        } catch (StoreException e) {
+                            throw new InitException("Can't create JoinState", e);
+                        }
 
-	    // Create new baseline snapshot
-	    try {
-		store.snapshot();
-		if (logger.isLoggable(Level.FINER)) {
-		    logger.log(
-			Level.FINER, "Completed new baseline snapshot: {0}",
-			inventory());
-		}
-	    } catch (IOException e) {
-		throw new InitException(
-		    "Can't create new baseline snapshot", e);
-	    }
-
-	    Entry[] serviceAttributes = {
-		new ServiceInfo(
-		    "Lease Renewal Service",		// name
-		    "Sun Microsystems, Inc.",		// manufacturer
-		    "Sun Microsystems, Inc.",		// vender
-		    VersionConstants.SERVER_VERSION,	// version
-		    "",					// model
-		    ""),				// serialNumber
-		new BasicServiceType("Lease Renewal Service")
-	    };
-	    try {
-		joinState = new JoinState(
-		    normProxy, lrm, config, serviceAttributes,
-		    recoveredLocatorPreparer,
-		    new ServiceID(serverUuid.getMostSignificantBits(),
-				  serverUuid.getLeastSignificantBits()));
-		store.addSubStore(joinState);
-	    } catch (StoreException e) {
-		throw new InitException("Can't create JoinState", e);
-	    }
-
-	    leaseFactory = new LeaseFactory(serverProxy, serverUuid);
-
-	    // $$$ By rights this code should be in
-	    // restoreTransientState(), however we can't have an independent
-	    // thread running around changing persistant state util we get
-	    // to this point (I think the only real issue is the baseline
-	    // snapshot) and once we place a set in the expMgr it the
-	    // underlying wakeup queue will start running which can cause
-	    // calls to expireIfTime() (and sendWarningEvent() though those
-	    // should not be a problem since they don't log anything).
-	    //
-	    // I would prefer to ether modify WakeupQueue() to have a "start
-	    // now" method (equivalent to how we create lrmEventListener above
-	    // but call start() bellow) or be able to hold an exclusive
-	    // snapshot lock until the initial snapshot is done.  Ether should
-	    // allow this code to be moved into restoreTransientState
+                        leaseFactory = new LeaseFactory(serverProxy, serverUuid);
 
-	    for (Iterator i = setTable.values().iterator(); i.hasNext(); ) {
-		final LeaseSet set = (LeaseSet) i.next();
-		synchronized (set) {
-		    expMgr.schedule(set);
-		}
-	    }
+                        // $$$ By rights this code should be in
+                        // restoreTransientState(), however we can't have an independent
+                        // thread running around changing persistant state util we get
+                        // to this point (I think the only real issue is the baseline
+                        // snapshot) and once we place a set in the expMgr it the
+                        // underlying wakeup queue will start running which can cause
+                        // calls to expireIfTime() (and sendWarningEvent() though those
+                        // should not be a problem since they don't log anything).
+                        //
+                        // I would prefer to ether modify WakeupQueue() to have a "start
+                        // now" method (equivalent to how we create lrmEventListener above
+                        // but call start() bellow) or be able to hold an exclusive
+                        // snapshot lock until the initial snapshot is done.  Ether should
+                        // allow this code to be moved into restoreTransientState
+
+                        // Move to Starter method, is WakeupQueue() above 
+                        // actually WakeupManager() renamed?  I suspect so.
+                        expMgr.start();
+                        for (Iterator i = setTable.values().iterator(); i.hasNext(); ) {
+                            final LeaseSet set = (LeaseSet) i.next();
+                            synchronized (set) {
+                                expMgr.schedule(set);
+                            }
+                        }
+
+                        lrmEventListener.start();
+                        renewLogger.start();
+                        snapshotter.start();
+                        done = true;
+                    } finally {
+                        if (!done) {
+                            try {
+                                unexport(true);
+                            } catch (Exception e) {
+                                logger.log(
+                                    Level.INFO,
+                                    "Unable to unexport after failure during startup",
+                                    e);
+                            }
+                        }
+                    }
+                    return null;
+                }
 
-	    lrmEventListener.start();
-	    renewLogger.start();
-	    snapshotter.start();
-	    done = true;
+            }, context);
+	    ready.ready();
+	    logger.log(Level.INFO, "Norm service started: {0}", this);
+        } catch (PrivilegedActionException e){
+            initFailed(e.getException());
+        } catch (Throwable e) {
+	    initFailed(e);
 	} finally {
-	    if (!done) {
-		try {
-		    unexport(true);
-		} catch (Exception e) {
-		    logger.log(
-			Level.INFO,
-			"Unable to unexport after failure during startup",
-			e);
-		}
-	    }
-	}
+            context = null;
+            config = null;
+        }
     }
 
     /** Returns whether to isolate renewal sets or batch lease across sets. */
@@ -1977,27 +1971,30 @@ abstract class NormServerBaseImpl
 
     /**
      * Creates an instance of this class.
-     *
-     * @param persistent whether this server is persistent
      */
-    NormServerBaseImpl(boolean persistent) {
-	this.persistent = persistent;
-    }
-
-    /**
-     * Returns the exporter to use to export this server.
-     *
-     * @param config the configuration to use for supplying the exporter
-     * @return the exporter to use to export this server
-     * @throws ConfigurationException if a problem occurs retrieving entries
-     *	       from the configuration
-     */
-    Exporter getExporter(Configuration config)
-	throws ConfigurationException
-    {
-	return (Exporter) Config.getNonNullEntry(
-	    config, NORM, "serverExporter", Exporter.class,
-	    new BasicJeriExporter(
-		TcpServerEndpoint.getInstance(0), new BasicILFactory()));
+    NormServerBaseImpl(NormServerInitializer init){
+        persistent = init.persistent;
+        lifeCycle = init.lifeCycle;
+        loginContext = init.loginContext;
+        persistenceDirectory = init.persistenceDirectory;
+        renewedList = init.renewedList;
+        snapshotWt = init.snapshotWt;
+        logToSnapshotThresh = init.logToSnapshotThresh;
+        leasePreparer = init.leasePreparer;
+        listenerPreparer = init.listenerPreparer;
+        locatorPreparer = init.locatorPreparer;
+        recoveredLeasePreparer = init.recoveredLeasePreparer;
+        recoveredListenerPreparer = init.recoveredListenerPreparer;
+        recoveredLocatorPreparer = init.recoveredLocatorPreparer;
+        setLeasePolicy = init.setLeasePolicy;
+        isolateSets = init.isolateSets;
+        lrm = init.lrm;
+        exporter = init.exporter;
+        expMgr = init.expMgr;
+        generator = init.generator;
+        lrmEventListener = init.lrmEventListener;
+        renewLogger = init.renewLogger;
+        context = init.context;
+        config = init.config;
     }
 }

Added: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerInitializer.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerInitializer.java?rev=1482594&view=auto
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerInitializer.java (added)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/NormServerInitializer.java Tue May 14 21:19:38 2013
@@ -0,0 +1,133 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ * 
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.sun.jini.norm;
+
+import com.sun.jini.config.Config;
+import com.sun.jini.landlord.FixedLeasePeriodPolicy;
+import com.sun.jini.landlord.LeasePeriodPolicy;
+import com.sun.jini.norm.event.EventTypeGenerator;
+import com.sun.jini.start.LifeCycle;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.util.LinkedList;
+import java.util.List;
+import javax.security.auth.login.LoginContext;
+import net.jini.config.Configuration;
+import net.jini.config.ConfigurationException;
+import net.jini.config.NoSuchEntryException;
+import net.jini.export.Exporter;
+import net.jini.jeri.BasicILFactory;
+import net.jini.jeri.BasicJeriExporter;
+import net.jini.jeri.tcp.TcpServerEndpoint;
+import net.jini.lease.LeaseRenewalManager;
+import net.jini.security.BasicProxyPreparer;
+import net.jini.security.ProxyPreparer;
+
+/**
+ * NormServerInitializer creates the internal state of NormServerBaseImpl allowing
+ * many fields to be final after construction.  This simplifies auditing of
+ * synchronization by reducing scope to mutable fields and references 
+ * to mutable objects.
+ */
+class NormServerInitializer {
+    boolean persistent;
+    LifeCycle lifeCycle;
+    LoginContext loginContext;
+    String persistenceDirectory;
+    List renewedList = new LinkedList();
+    float snapshotWt;
+    int logToSnapshotThresh;
+    ProxyPreparer leasePreparer;
+    ProxyPreparer listenerPreparer;
+    ProxyPreparer locatorPreparer;
+    ProxyPreparer recoveredLeasePreparer;
+    ProxyPreparer recoveredListenerPreparer;
+    ProxyPreparer recoveredLocatorPreparer;
+    LeasePeriodPolicy setLeasePolicy;
+    boolean isolateSets;
+    LeaseRenewalManager lrm;
+    Exporter exporter;
+    LeaseExpirationMgr expMgr;
+    EventTypeGenerator generator;
+    LRMEventListener lrmEventListener;
+    NormServerBaseImpl.RenewLogThread renewLogger;
+    AccessControlContext context;
+    Configuration config;
+
+    /**
+     * Initializer object for NormServer implementations.  Can be overridden by
+     * subclasses of NormServerBaseImpl
+     * 
+     * @param persistent true if implementation is persistent
+     * @param lifeCycle object to notify when NormServer is destroyed.
+     */
+    NormServerInitializer(boolean persistent, LifeCycle lifeCycle) {
+        this.persistent = persistent;
+        this.lifeCycle = lifeCycle;
+    }
+
+    /**
+     * Common construction for activatable and non-activatable cases, run
+     * under the proper Subject.
+     */
+    void initAsSubject(Configuration config) throws Exception {
+        this.config = config;
+        /* Get configuration entries first */
+        if (persistent) {
+            persistenceDirectory = (String) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "persistenceDirectory", String.class);
+            snapshotWt = Config.getFloatEntry(config, NormServerBaseImpl.NORM, "persistenceSnapshotWeight", 10, 0, Float.MAX_VALUE);
+            logToSnapshotThresh = Config.getIntEntry(config, NormServerBaseImpl.NORM, "persistenceSnapshotThreshold", 200, 0, Integer.MAX_VALUE);
+        }
+        leasePreparer = (ProxyPreparer) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "leasePreparer", ProxyPreparer.class, new BasicProxyPreparer());
+        listenerPreparer = (ProxyPreparer) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "listenerPreparer", ProxyPreparer.class, new BasicProxyPreparer());
+        locatorPreparer = (ProxyPreparer) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "locatorPreparer", ProxyPreparer.class, new BasicProxyPreparer());
+        if (persistent) {
+            recoveredLeasePreparer = (ProxyPreparer) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "recoveredLeasePreparer", ProxyPreparer.class, new BasicProxyPreparer());
+            recoveredListenerPreparer = (ProxyPreparer) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "recoveredListenerPreparer", ProxyPreparer.class, new BasicProxyPreparer());
+            recoveredLocatorPreparer = (ProxyPreparer) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "recoveredLocatorPreparer", ProxyPreparer.class, new BasicProxyPreparer());
+        }
+        setLeasePolicy = (LeasePeriodPolicy) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "leasePolicy", LeasePeriodPolicy.class, new FixedLeasePeriodPolicy(2 * 60 * 60 * 1000, 60 * 60 * 1000));
+        isolateSets = ((Boolean) config.getEntry(NormServerBaseImpl.NORM, "isolateSets", boolean.class, Boolean.FALSE)).booleanValue();
+        try {
+            lrm = (LeaseRenewalManager) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "leaseManager", LeaseRenewalManager.class);
+        } catch (NoSuchEntryException e) {
+            lrm = new LeaseRenewalManager(config);
+        }
+        exporter = getExporter(config);
+        // We use some of these during the recovery process
+        expMgr = new LeaseExpirationMgr();
+        generator = new EventTypeGenerator();
+        lrmEventListener = new LRMEventListener();
+        renewLogger = new NormServerBaseImpl.RenewLogThread(renewedList);
+        context = AccessController.getContext();
+    }
+
+    /**
+     * Returns the exporter to use to export this server.
+     *
+     * @param config the configuration to use for supplying the exporter
+     * @return the exporter to use to export this server
+     * @throws ConfigurationException if a problem occurs retrieving entries
+     *	       from the configuration
+     */
+    Exporter getExporter(Configuration config) throws ConfigurationException {
+        return (Exporter) Config.getNonNullEntry(config, NormServerBaseImpl.NORM, "serverExporter", Exporter.class, new BasicJeriExporter(TcpServerEndpoint.getInstance(0), new BasicILFactory()));
+    }
+    
+}

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentNormServerImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentNormServerImpl.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentNormServerImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentNormServerImpl.java Tue May 14 21:19:38 2013
@@ -41,7 +41,6 @@ class PersistentNormServerImpl extends N
     PersistentNormServerImpl(String[] configOptions, LifeCycle lifeCycle)
 	throws Exception
     {
-	super(true /* persistent */);
-	init(configOptions, lifeCycle);
+        super(init( configOptions, new NormServerInitializer(true /* persistent */, lifeCycle)));
     }
 }

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/PersistentStore.java Tue May 14 21:19:38 2013
@@ -75,7 +75,7 @@ class PersistentStore {
     final private LogHandler logHandler;
 
     /** The NormServer we are part of */
-    final private NormServerBaseImpl server;
+    private NormServerBaseImpl server;
 
     /** Number of updates since last snapshot */
     private int updateCount;
@@ -122,6 +122,16 @@ class PersistentStore {
 	    }
 	}
     }
+    
+    /**
+     * Can only be called once after construction.
+     * @param server 
+     */
+    void setServer(NormServerBaseImpl server){
+        synchronized (this){
+            if (this.server == null) this.server = server;
+        }
+    }
 
     /**
      * Destroy the store.
@@ -130,10 +140,12 @@ class PersistentStore {
      */
     void destroy() throws IOException {
 	// Prep all the sub-stores to be destroyed
-	for (Iterator i = subStores.iterator(); i.hasNext(); ) {
-	    SubStore subStore = (SubStore) i.next();
-	    subStore.prepareDestroy();
-	}
+        synchronized (subStores){
+            for (Iterator i = subStores.iterator(); i.hasNext(); ) {
+                SubStore subStore = (SubStore) i.next();
+                subStore.prepareDestroy();
+            }
+        }
 	if (log != null) {
 	    log.deletePersistentStore();
 	    FileSystem.destroy(storeLocation, true);
@@ -156,8 +168,9 @@ class PersistentStore {
 		    subStore.setDirectory(new File(storeLocation, subDir));
 		}
 	    }
-	    
-	    subStores.add(subStore);
+	    synchronized (subStores){
+                subStores.add(subStore);
+            }
 	} catch (IOException e) {
 	    throw new StoreException("Failure adding substore " + subStore,
 				     e);
@@ -273,7 +286,9 @@ class PersistentStore {
 	try {
 	    // Using write lock because we want an exclusive lock
 	    mutatorLock.writeLock();
-	    updateCount = 0;
+            synchronized (this){
+                updateCount = 0;
+            }
 
 	    // Don't need to sync on this because
 	    // mutatorLock.writeLock() gives us an exclusive lock

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/TransientNormServerImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/TransientNormServerImpl.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/TransientNormServerImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/TransientNormServerImpl.java Tue May 14 21:19:38 2013
@@ -41,7 +41,6 @@ class TransientNormServerImpl extends No
     TransientNormServerImpl(String[] configOptions, LifeCycle lifeCycle)
 	throws Exception
     {
-	super(false /* persistent */);
-	init(configOptions, lifeCycle);
+        super(init( configOptions, new NormServerInitializer(false /* persistent */, lifeCycle)));
     }
 }

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/UIDGenerator.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/UIDGenerator.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/UIDGenerator.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/UIDGenerator.java Tue May 14 21:19:38 2013
@@ -17,6 +17,8 @@
  */
 package com.sun.jini.norm;
 
+import java.util.concurrent.atomic.AtomicLong;
+
 /**
  * Utility class for generating locally unique IDs.
  *
@@ -26,14 +28,13 @@ class UIDGenerator {
     /**
      * Value of the next ID
      */
-    private long nextID = 0;
+    private final AtomicLong nextID = new AtomicLong();
 
     /**
-     * Generate ID, this method performs appropriate locking to
-     * ensure the returned ID is unique.
+     * Generate ID, the returned ID is unique.
      */
-    synchronized long newID() {
-        return nextID++;
+    long newID() {
+        return nextID.getAndIncrement();
     }
 
     /**
@@ -42,7 +43,11 @@ class UIDGenerator {
      * @param ID ID that is in use
      */
     void inUse(long ID) {
-        if (ID >= nextID)
-	    nextID = ID + 1;
+        long nID = nextID.get();
+        while (ID >= nID){
+            boolean success = nextID.compareAndSet(nID, ID + 1);
+            if (success) break;
+	    nID = nextID.get();
+        }
     }
 }

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventType.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventType.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventType.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventType.java Tue May 14 21:19:38 2013
@@ -101,7 +101,7 @@ public class EventType implements Serial
      * Our event ID
      * @serial
      */
-    private long evID;
+    private final long evID;
 
     /** 
      * Object we check with to ensure leases have not expired and notify
@@ -186,7 +186,7 @@ public class EventType implements Serial
      * Returns <code>true</code> if there is a listener registered for this 
      * event type.
      */
-    public boolean haveListener() {
+    public synchronized boolean haveListener() {
 	return marshalledListener != null;
     }
 
@@ -194,11 +194,12 @@ public class EventType implements Serial
      * Convince method to get the listener.
      * @return the listener, or <code>null</code> if the listener can't be
      *	       unpacked or prepared, or there is no listener
+     * synchronized externally
      */
     private RemoteEventListener getListener() {
 	if (!haveListener()) 
 	    return null;
-
+            
 	if (listener != null) 
 	    return listener;
 
@@ -269,10 +270,9 @@ public class EventType implements Serial
      * scheduled to be sent will have a sequence number one greater than
      * the value past to this call.
      * <p>
-     * Note: this method is not synchronized.
      * @param seqNum value for the last sequence number
      */
-    public void setLastSequenceNumber(long seqNum) {
+    public synchronized void setLastSequenceNumber(long seqNum) {
 	lastSeqNum = seqNum;
     }
 
@@ -372,10 +372,13 @@ public class EventType implements Serial
 	    throw new NullPointerException("EventType.restoreTransientState:" +
 	        "Must call with a non-null recoveredListenerPreparer");
 	}
-	this.generator = generator;
-	this.monitor = monitor;
-	this.recoveredListenerPreparer = recoveredListenerPreparer;
-	generator.recoverEventID(evID);
+        synchronized (this){
+            this.generator = generator;
+            this.monitor = monitor;
+            this.recoveredListenerPreparer = recoveredListenerPreparer;
+        }
+            generator.recoverEventID(evID);
+        
     }
 
     /**

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventTypeGenerator.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventTypeGenerator.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventTypeGenerator.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/event/EventTypeGenerator.java Tue May 14 21:19:38 2013
@@ -102,7 +102,7 @@ public class EventTypeGenerator implemen
      * Note: this method is not synchronized.
      * @param evID event ID of recovered <code>EventType</code> object
      */
-    void recoverEventID(long evID) {
+    synchronized void recoverEventID(long evID) {
 	if (evID >= nextEvID)
 	    nextEvID = evID + 1;
     }

Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/lookup/JoinState.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/lookup/JoinState.java?rev=1482594&r1=1482593&r2=1482594&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/lookup/JoinState.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/lookup/JoinState.java Tue May 14 21:19:38 2013
@@ -148,7 +148,7 @@ public class JoinState extends LogHandle
 	this.service = service;
 	this.lrm = lrm;
 	this.config = config;
-	this.serviceAttributes = serviceAttributes;
+	this.serviceAttributes = serviceAttributes.clone();
 	this.recoveredLookupLocatorPreparer = recoveredLookupLocatorPreparer;
 	this.serviceID = serviceID;
     }
@@ -165,73 +165,75 @@ public class JoinState extends LogHandle
     public void setDirectory(File dir)
 	throws IOException, ConfigurationException
     {
-	if (dir != null) {
-	    try {
-		log = new ReliableLog(dir.getCanonicalPath(), this);
-		log.recover();
-	    } catch (IOException e) {
-		IOException e2 = new IOException(
-		    "Log is corrupted: " + e.getMessage());
-		e2.initCause(e);
-		throw e2;
-	    }
-	}
-	if (!recoveredData) {
-	    /*
-	     * Get initial attributes, groups, and locators, if not retrieved
-	     * from persistent storage.
-	     */
-	    getInitialEntries();
-	} else {
-	    /*
-	     * Prepare recovered lookup locators, dropping ones for which
-	     * preparation fails.
-	     */
-	    List prepared = new LinkedList();
-	    for (int i = locators.length; --i >= 0; ) {
-		try {
-		    prepared.add(
-			recoveredLookupLocatorPreparer.prepareProxy(
-			    locators[i]));
-		} catch (Throwable t) {
-		    if (logger.isLoggable(Level.INFO)) {
-			logThrow(Level.INFO, "setDirectory",
-				 "Problem preparing lookup locator {0} -- " +
-				 "discarding",
-				 new Object[] { locators[i] },
-				 t);
-		    }
-		}
-	    }
-	    locators = (LookupLocator[]) prepared.toArray(
-		new LookupLocator[prepared.size()]);
-	}
-
-	// Create DiscoveryManager
-	createDiscoveryManager();
-
-	// Create JoinManager
-	try {
-	    joinMgr = new JoinManager(service, attributes, serviceID, dm, lrm,
-				      config);
-	} catch (IOException e) {
-	    IOException e2 = new IOException(
-		"Problem starting JoinManager: " + e.getMessage());
-	    e2.initCause(e2);
-	    throw e2;
-	}
-
-	// For now we are treating the state of the
-	// JoinManager/LookupDiscoveryManager as truth for our
-	// log, now that we have a lookup manager, force it into
-	// sync with our log
-	try {
-	    takeSnapshot();
-	} catch (IOException e) {
-	    logger.log(Level.WARNING,
-		       "Ignoring problem creating initial snapshot",
-		       e);
-	}
+        synchronized (this){
+            if (dir != null) {
+                try {
+                    log = new ReliableLog(dir.getCanonicalPath(), this);
+                    log.recover();
+                } catch (IOException e) {
+                    IOException e2 = new IOException(
+                        "Log is corrupted: " + e.getMessage());
+                    e2.initCause(e);
+                    throw e2;
+                }
+            }
+            if (!recoveredData) {
+                /*
+                 * Get initial attributes, groups, and locators, if not retrieved
+                 * from persistent storage.
+                 */
+                getInitialEntries();
+            } else {
+                /*
+                 * Prepare recovered lookup locators, dropping ones for which
+                 * preparation fails.
+                 */
+                List prepared = new LinkedList();
+                for (int i = locators.length; --i >= 0; ) {
+                    try {
+                        prepared.add(
+                            recoveredLookupLocatorPreparer.prepareProxy(
+                                locators[i]));
+                    } catch (Throwable t) {
+                        if (logger.isLoggable(Level.INFO)) {
+                            logThrow(Level.INFO, "setDirectory",
+                                     "Problem preparing lookup locator {0} -- " +
+                                     "discarding",
+                                     new Object[] { locators[i] },
+                                     t);
+                        }
+                    }
+                }
+                locators = (LookupLocator[]) prepared.toArray(
+                    new LookupLocator[prepared.size()]);
+            }
+
+            // Create DiscoveryManager
+            createDiscoveryManager();
+
+            // Create JoinManager
+            try {
+                joinMgr = new JoinManager(service, attributes, serviceID, dm, lrm,
+                                          config);
+            } catch (IOException e) {
+                IOException e2 = new IOException(
+                    "Problem starting JoinManager: " + e.getMessage());
+                e2.initCause(e2);
+                throw e2;
+            }
+        
+            // For now we are treating the state of the
+            // JoinManager/LookupDiscoveryManager as truth for our
+            // log, now that we have a lookup manager, force it into
+            // sync with our log
+            try {
+                takeSnapshot();
+            } catch (IOException e) {
+                logger.log(Level.WARNING,
+                           "Ignoring problem creating initial snapshot",
+                           e);
+            }
+        }
     }
 
     /** Logs a throw */
@@ -337,7 +339,7 @@ public class JoinState extends LogHandle
     }
 
     // Inherit JavaDoc from super-type
-    public void prepareDestroy() {
+    public synchronized void prepareDestroy() {
 	try {
 	    if (log != null)
 		log.close();
@@ -351,7 +353,7 @@ public class JoinState extends LogHandle
      * Terminate our participation in the Join and discovery
      * Protocols.  Note, this method leaves the logs intact.    
      */
-    public void terminateJoin() {
+    public synchronized void terminateJoin() {
 	// Terminate the JoinManager first so it will not call
 	// into the dm after it has been terminated.
 	if (joinMgr != null)
@@ -365,7 +367,7 @@ public class JoinState extends LogHandle
     // Methods needed to meet the LogHandler interface
 	
     // Inherit doc comment from super interface
-    public void snapshot(OutputStream out) throws IOException {
+    public synchronized void snapshot(OutputStream out) throws IOException {
 	ObjectOutputStream oostream = new ObjectOutputStream(out);
 	writeAttributes(joinMgr.getAttributes(), oostream);
 	oostream.writeObject(((DiscoveryGroupManagement) dm).getGroups());
@@ -374,7 +376,7 @@ public class JoinState extends LogHandle
     }
 
     // Inherit doc comment from super interface
-    public void recover(InputStream in) throws Exception {
+    public synchronized void recover(InputStream in) throws Exception {
 	ObjectInputStream oistream = new ObjectInputStream(in);
 	attributes = readAttributes(oistream);
 	groups     = (String[]) oistream.readObject();
@@ -450,13 +452,11 @@ public class JoinState extends LogHandle
      * Used by all the methods that change persistent state to
      * commit the change to disk
      */
-    private void takeSnapshot() throws IOException {
+    private synchronized void takeSnapshot() throws IOException {
 	if (log == null) {
 	    return;
 	}
-	synchronized (log) {
-	    log.snapshot();
-	}
+        log.snapshot();
     }
 
     /////////////////////////////////////////////////////////////////
@@ -471,7 +471,11 @@ public class JoinState extends LogHandle
      *         joins no groups (as opposed to "all" groups).
      */
     public String[] getGroups() {
-	return ((DiscoveryGroupManagement) dm).getGroups();
+        DiscoveryGroupManagement dgm;
+        synchronized (this){
+            dgm = (DiscoveryGroupManagement) dm;
+        }
+	return dgm.getGroups();
     }
 
     /**
@@ -482,7 +486,11 @@ public class JoinState extends LogHandle
      */
     public void addGroups(String[] groups) {
  	try {
-	    ((DiscoveryGroupManagement) dm).addGroups(groups);
+            DiscoveryGroupManagement dgm;
+            synchronized (this){
+                dgm = (DiscoveryGroupManagement) dm;
+            }
+	    dgm.addGroups(groups);
 	} catch (IOException e) {
 	    throw new RuntimeException(
 		"Could not change groups: " + e.getMessage(), e);
@@ -503,7 +511,11 @@ public class JoinState extends LogHandle
      * @param groups groups to leave
      */
     public void removeGroups(String[] groups) {
-	((DiscoveryGroupManagement) dm).removeGroups(groups);
+        DiscoveryGroupManagement dgm;
+        synchronized (this){
+            dgm = (DiscoveryGroupManagement) dm;
+        }
+	dgm.removeGroups(groups);
 
 	try {
 	    takeSnapshot();
@@ -523,7 +535,11 @@ public class JoinState extends LogHandle
      */
     public void setGroups(String[] groups) {
 	try {
-	    ((DiscoveryGroupManagement) dm).setGroups(groups);
+            DiscoveryGroupManagement dgm;
+            synchronized (this){
+                dgm = (DiscoveryGroupManagement) dm;
+            }
+	    dgm.setGroups(groups);
 	} catch (IOException e) {
 	    throw new RuntimeException(
 		"Could not change groups: " + e.getMessage(), e);
@@ -543,7 +559,11 @@ public class JoinState extends LogHandle
      * @return the list of locators of specific lookup services to join
      */    
     public LookupLocator[] getLocators() {
-	return ((DiscoveryLocatorManagement) dm).getLocators();
+        DiscoveryLocatorManagement dlm;
+        synchronized (this){
+            dlm = (DiscoveryLocatorManagement) dm;
+        }
+	return dlm.getLocators();
     }
 
     /**
@@ -553,7 +573,11 @@ public class JoinState extends LogHandle
      * @param locators locators of specific lookup services to join
      */
     public void addLocators(LookupLocator[] locators) {
-	((DiscoveryLocatorManagement) dm).addLocators(locators);
+        DiscoveryLocatorManagement dlm;
+        synchronized (this){
+            dlm = (DiscoveryLocatorManagement) dm;
+        }
+	dlm.addLocators(locators);
 	try {
 	    takeSnapshot();
 	} catch (IOException e) {
@@ -569,7 +593,11 @@ public class JoinState extends LogHandle
      * @param locators locators of specific lookup services to leave
      */   
     public void removeLocators(LookupLocator[] locators) {
-	((DiscoveryLocatorManagement) dm).removeLocators(locators);
+        DiscoveryLocatorManagement dlm;
+        synchronized (this){
+            dlm = (DiscoveryLocatorManagement) dm;
+        }
+	dlm.removeLocators(locators);
 	try {
 	    takeSnapshot();
 	} catch (IOException e) {
@@ -587,7 +615,11 @@ public class JoinState extends LogHandle
      * @param locators locators of specific lookup services to join
      */
     public void setLocators(LookupLocator[] locators) {
-	((DiscoveryLocatorManagement) dm).setLocators(locators);
+        DiscoveryLocatorManagement dlm;
+        synchronized (this){
+            dlm = (DiscoveryLocatorManagement) dm;
+        }
+	dlm.setLocators(locators);
 	try {
 	    takeSnapshot();
 	} catch (IOException e) {
@@ -602,7 +634,11 @@ public class JoinState extends LogHandle
      * @return the current attribute sets for the service
      */
     public Entry[] getAttributes() {
-	return joinMgr.getAttributes();
+        JoinManager jm;
+        synchronized (this){
+            jm = joinMgr;
+        }
+	return jm.getAttributes();
     }
 
 
@@ -621,7 +657,11 @@ public class JoinState extends LogHandle
      *         marker interface
      */
     public void addAttributes(Entry[] attrSets, boolean checkSC) {
-	joinMgr.addAttributes(attrSets, checkSC);
+        JoinManager jm;
+        synchronized (this){
+            jm = joinMgr;
+        }
+	jm.addAttributes(attrSets, checkSC);
 	try {
 	    takeSnapshot();
 	} catch (IOException e) {
@@ -651,7 +691,11 @@ public class JoinState extends LogHandle
 				 Entry[] attrSets,
 				 boolean checkSC)
     {
-	joinMgr.modifyAttributes(attrSetTemplates, attrSets, checkSC);
+        JoinManager jm;
+        synchronized (this){
+            jm = joinMgr;
+        }
+	jm.modifyAttributes(attrSetTemplates, attrSets, checkSC);
 
 	try {
 	    takeSnapshot();



Mime
View raw message