Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TypeTree.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TypeTree.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TypeTree.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TypeTree.java Sun Apr 21 07:53:23 2013 @@ -66,9 +66,14 @@ class TypeTree { * An iterator that will walk through a list of known types. */ // @see #RandomizedIterator - private abstract class TypeTreeIterator implements Iterator { + private static abstract class TypeTreeIterator implements Iterator { protected int cursor; // the current position in the list - protected Object[] typearray; // the list of types as an array + protected final Object[] typearray; // the list of types as an array + + protected TypeTreeIterator (Object [] types){ + cursor = 0; + typearray = types; + } // inherit doc comment public boolean hasNext() { @@ -112,14 +117,13 @@ class TypeTree { * maintains a randomized list of subtypes for the given * <code>className</code>, including the class itself. */ - class RandomizedIterator extends TypeTreeIterator { + static class RandomizedIterator extends TypeTreeIterator { /** * Create a new <code>RandomizedIterator</code> for the given * class. */ - RandomizedIterator(String className) { - super(); - init(className); + RandomizedIterator(String className, TypeTree tree) { + super(init(className, tree)); } @@ -127,12 +131,12 @@ class TypeTree { * Traverse the given type tree and add to the list all the * subtypes encountered within. */ - private void walkTree(Collection children, Collection list) { + private static void walkTree(Collection children, Collection list, TypeTree tree) { if (children != null) { list.addAll(children); Object[] kids = children.toArray(); for (int i = 0; i< kids.length; i++) { - walkTree(classVector((String)kids[i]), list); + walkTree(tree.classVector((String)kids[i]), list, tree); } } } @@ -141,9 +145,9 @@ class TypeTree { * Set up this iterator to walk over the subtypes of this class, * including the class itself. It then randomizes the list. */ - private void init(String className) { - Collection types = new ArrayList(); - + private static Object [] init(String className, TypeTree tree) { + Collection<String> types = new ArrayList<String>(); + Object [] typearray; if (className.equals(EntryRep.matchAnyClassName())) { // handle "match any" specially" -- search from ROOT // Simplification suggested by @@ -155,7 +159,7 @@ class TypeTree { } // add all subclasses - walkTree(classVector(className), types); + walkTree(tree.classVector(className), types, tree); // Convert it to an array and then randomize typearray = types.toArray(); @@ -168,6 +172,7 @@ class TypeTree { typearray[i] = typearray[randnum]; typearray[randnum] = tmpobj; } + return typearray; } } @@ -179,7 +184,7 @@ class TypeTree { * instances of the class that named, in a random ordering. */ Iterator subTypes(String className) { - return new RandomizedIterator(className); + return new RandomizedIterator(className, this); } /**
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/WrittenEntry.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/WrittenEntry.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/WrittenEntry.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/WrittenEntry.java Sun Apr 21 07:53:23 2013 @@ -40,13 +40,13 @@ package com.sun.jini.outrigger; // @see OutriggerServerImpl#getMatch(EntryRep,Transaction,long,boolean,boolean,RemoteEventListener,long) class WrittenEntry { /** The time at which this entry was written. */ - private long timestamp; + private final long timestamp; /** The next node in the list. */ - private WrittenEntry next; + private volatile WrittenEntry next; /** The EntryRep this node refers to. */ - private EntryRep rep; + private final EntryRep rep; /** * Create a new time-stamped entry for the given EntryRep. The comment Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BackEnd.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BackEnd.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BackEnd.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BackEnd.java Sun Apr 21 07:53:23 2013 @@ -39,6 +39,9 @@ import java.util.HashMap; import java.util.Map; import java.util.Observable; import java.util.Observer; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; import java.util.logging.Level; import java.util.logging.Logger; @@ -59,19 +62,16 @@ class BackEnd implements Observer { // The following data represent the persistent // state. - private Long sessionId; - private StoredObject joinState; - private Map entries; - private Map registrations; - private Map pendingTxns; - private byte topUuid[]; - private LastLog lastLog; - - /** Number of times to attempt to restart the consumer thread. */ - private int retry = 3; + private final AtomicLong sessionId; + private volatile StoredObject joinState; + private final Map<ByteArrayWrapper,Resource> entries; + private final Map<ByteArrayWrapper,Registration> registrations; + private final Map<Long,PendingTxn> pendingTxns; + private volatile byte topUuid[]; + private volatile LastLog lastLog; /** Snapshot object */ - private SnapshotFile snapshotFile; + private volatile SnapshotFile snapshotFile; /** Keep logs and snapshot tied, though not necessary */ private final int SNAPSHOT_VERSION = LogFile.LOG_VERSION; @@ -79,17 +79,17 @@ class BackEnd implements Observer { /** * The base name for the log files. */ - private String logFileBase; + private final String logFileBase; /** * The base name for the snapshot files */ - private String snapshotFileBase; + private final String snapshotFileBase; /** * Log file consumer thread. */ - private ConsumerThread consumer; + private final ConsumerThread consumer; /** Max time to wait for the consumer thread to die on destroy */ private final static long WAIT_FOR_THREAD = 1 * TimeConstants.MINUTES; @@ -104,6 +104,11 @@ class BackEnd implements Observer { BackEnd(String path) { logFileBase = new File(path, LogFile.LOG_TYPE).getAbsolutePath(); snapshotFileBase = new File(path, "Snapshot.").getAbsolutePath(); + consumer = new ConsumerThread(); + entries = new ConcurrentHashMap<ByteArrayWrapper,Resource>(); + registrations = new ConcurrentHashMap<ByteArrayWrapper,Registration>(); + pendingTxns = new ConcurrentHashMap<Long,PendingTxn>(); + sessionId = new AtomicLong(); } /** @@ -206,10 +211,7 @@ class BackEnd implements Observer { if (snapshot[0] == null) { // no snapshot, initialize fields and return - sessionId = null; - entries = new HashMap(); - registrations = new HashMap(); - pendingTxns = new HashMap(); + topUuid = null; lastLog = null; return; @@ -225,11 +227,14 @@ class BackEnd implements Observer { "Wrong file version:" + version, null); } - sessionId = (Long)in.readObject(); + sessionId.set(((Long)in.readObject()).longValue()); joinState = (StoredObject)in.readObject(); - entries = (Map)in.readObject(); - registrations = (Map)in.readObject(); - pendingTxns = (Map)in.readObject(); + entries.clear(); + entries.putAll((Map<ByteArrayWrapper,Resource>)in.readObject()); + registrations.clear(); + registrations.putAll((Map<ByteArrayWrapper,Registration>)in.readObject()); + pendingTxns.clear(); + pendingTxns.putAll((Map)in.readObject()); topUuid = (byte[])in.readObject(); lastLog = (LastLog)in.readObject(); in.close(); @@ -244,7 +249,7 @@ class BackEnd implements Observer { // Create and start the log consumer thread // - consumer = new ConsumerThread(); + consumer.start(); } @@ -255,7 +260,6 @@ class BackEnd implements Observer { */ private class ConsumerThread extends Thread { - private boolean more = false; volatile private boolean interrupted = false; ConsumerThread() {} @@ -269,23 +273,21 @@ class BackEnd implements Observer { // to process. LogOutputFile is created after // setup returns. // - synchronized(this) { - while (!more) - wait(); - more = false; - } - - // There is a small window between the wait and - // the consumeLogs where update can be called, - // setting more to true and yet consumeLogs - // actually consumes the log file that caused the - // update. This unlikely situation is ok since - // consumeLogs does the right thing if there are - // no logs to process We could sync around - // consumeLogs but we don't want LogOutputFile to - // wait. - // - consumeLogs(false); + synchronized(this) { + wait(); + } + + // There is a small window between the wait and + // the consumeLogs where update can be called, + // setting more to true and yet consumeLogs + // actually consumes the log file that caused the + // update. This unlikely situation is ok since + // consumeLogs does the right thing if there are + // no logs to process We could sync around + // consumeLogs but we don't want LogOutputFile to + // wait. + // + consumeLogs(false); } } catch (InterruptedException exit) {} } @@ -293,7 +295,7 @@ class BackEnd implements Observer { // Cause the thread to consume a log file. // synchronized private void update() { - more = true; // For the case it is processing log files + // For the case it is processing log files notify(); // For the case is it waiting } @@ -313,16 +315,8 @@ class BackEnd implements Observer { public void update(Observable source, Object arg) { if (!consumer.isAlive()) { - if (retry > 0) { - logger.log(Level.INFO, - "Consumer thread died, attempting restart"); - retry--; - startConsumer(); - } else { - logger.log(Level.SEVERE, - "Consumer thread no longer running"); - return; - } + logger.log(Level.SEVERE, "Consumer thread no longer running"); + return; } consumer.update(); } @@ -410,7 +404,7 @@ class BackEnd implements Observer { * only used during recovery after a restart. */ void bootOp(long time, long session) { - sessionId = Long.valueOf(session); + sessionId.set(session); if (logger.isLoggable(Level.FINE)) logger.log(Level.FINE, "bootOp({0})", new Date(time)); } @@ -602,11 +596,12 @@ class BackEnd implements Observer { ObjectOutputStream out = snapshotFile.next(); out.writeInt(SNAPSHOT_VERSION); - out.writeObject(sessionId); + out.writeObject(sessionId.get()); out.writeObject(joinState); - out.writeObject(entries); - out.writeObject(registrations); - out.writeObject(pendingTxns); + // Serial form of maps is HashMap, cannot be changed. + out.writeObject(new HashMap(entries)); + out.writeObject(new HashMap(registrations)); + out.writeObject(new HashMap(pendingTxns)); out.writeObject(topUuid); out.writeObject(lastLog); snapshotFile.commit(); @@ -629,8 +624,8 @@ class BackEnd implements Observer { * before the file was unlinked. */ private static class LastLog implements Serializable { - private String logFile; - private long timeStamp; + private final String logFile; + private final long timeStamp; LastLog(String path) { logFile = path; Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BaseObject.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BaseObject.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BaseObject.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BaseObject.java Sun Apr 21 07:53:23 2013 @@ -37,7 +37,7 @@ import net.jini.space.InternalSpaceExcep class BaseObject implements StoredObject, Serializable { static final long serialVersionUID = -400804064969360164L; - private byte[] blob; + private final byte[] blob; BaseObject(StorableObject object) { try { Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/ByteArrayWrapper.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/ByteArrayWrapper.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/ByteArrayWrapper.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/ByteArrayWrapper.java Sun Apr 21 07:53:23 2013 @@ -36,10 +36,10 @@ import net.jini.id.UuidFactory; */ class ByteArrayWrapper implements Serializable { /** The 16 bytes being wrapped */ - private byte[] uuid; + private final byte[] uuid; /** A 32 bit hash of uuid */ - private int hash; + private final int hash; /** * Create a new <code>ByteArrayWrapper</code> that Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogFile.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogFile.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogFile.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogFile.java Sun Apr 21 07:53:23 2013 @@ -46,13 +46,13 @@ class LogFile { /** * The directory in which the log files live. */ - protected File baseDir; + protected volatile File baseDir; /** * The base part of the file name (e.g., <code>"log."</code> for * <code>"log.0"</code>, <code>"log.1"</code>, ...) */ - protected String baseFile; + protected volatile String baseFile; /** * The type of log stream Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogInputFile.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogInputFile.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogInputFile.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogInputFile.java Sun Apr 21 07:53:23 2013 @@ -42,7 +42,7 @@ import net.jini.space.InternalSpaceExcep * @see LogOutputFile */ class LogInputFile extends LogFile { - private File file; // the current log file + private final File file; // the current log file private static final long intBytes = 4; @@ -86,8 +86,8 @@ class LogInputFile extends LogFile { * @see LogInputFileIterator#next */ private static class LogInputFileIterator implements Iterator { - private LogFile baseLogFile; - private Iterator fileList; + private final LogFile baseLogFile; + private final Iterator fileList; /** * Create a new <code>LogInputFileIterator</code> object Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputFile.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputFile.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputFile.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputFile.java Sun Apr 21 07:53:23 2013 @@ -54,20 +54,20 @@ import net.jini.space.InternalSpaceExcep * @see java.util.Observable */ class LogOutputFile extends LogFile implements LogOps { - private RandomAccessFile logFile = null;// the current output log file - private FileDescriptor logFD; // the current log file descriptor - private ObjectOutputStream out; // objects written - private int suffix; // the current suffix number - private int opCnt; // number of ops on current file - private int maxOps; // max ops to allow in file - private Observable observable;// handle Observer/Observable + private volatile RandomAccessFile logFile = null;// the current output log file + private volatile FileDescriptor logFD; // the current log file descriptor + private volatile ObjectOutputStream out; // objects written + private volatile int suffix; // the current suffix number + private volatile int opCnt; // number of ops on current file + private volatile int maxOps; // max ops to allow in file + private volatile Observable observable;// handle Observer/Observable - private long logBytes = 0; + private volatile long logBytes = 0; private final byte[] intBuf = new byte[4]; private final byte[] zeroBuf = new byte[4]; - private long deferedUpdateLength = 0; - private long deferedPosition = 0; + private volatile long deferedUpdateLength = 0; + private volatile long deferedPosition = 0; private static final long intBytes = 4; Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputStream.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputStream.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputStream.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogOutputStream.java Sun Apr 21 07:53:23 2013 @@ -34,7 +34,7 @@ import java.io.RandomAccessFile; */ public class LogOutputStream extends OutputStream { - private RandomAccessFile raf; + private final RandomAccessFile raf; /** * Creates an output file with the specified <code>RandomAccessFile</code> Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogStore.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogStore.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogStore.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/LogStore.java Sun Apr 21 07:53:23 2013 @@ -39,10 +39,10 @@ import net.jini.space.InternalSpaceExcep * @see com.sun.jini.outrigger.OutriggerServerImpl */ public class LogStore implements Store { - private LogOutputFile log; + private volatile LogOutputFile log; private final String path; - private BackEnd be; - private int maxOps; + private final BackEnd be; + private final int maxOps; /** Logger for logging persistent store related information */ private static final Logger logger = Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/PendingTxn.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/PendingTxn.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/PendingTxn.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/PendingTxn.java Sun Apr 21 07:53:23 2013 @@ -51,7 +51,7 @@ class PendingTxn implements Serializable /** An object that represents a pending write. */ static class WriteOp extends PendingOp implements Serializable { - Resource entry; + final Resource entry; WriteOp(Resource entry) { this.entry = entry; @@ -64,7 +64,7 @@ class PendingTxn implements Serializable /** An object that represents a pending take. */ static class TakeOp extends PendingOp implements Serializable { - byte cookie[]; + final byte cookie[]; TakeOp(byte cookie[]) { this.cookie = cookie; @@ -75,10 +75,10 @@ class PendingTxn implements Serializable } } - private long id; // the transaction ID - private int state; // current state - private Hashtable ops; // list of pending operations - private StoredObject transaction; // the transaction object + private final long id; // the transaction ID + private volatile int state; // current state + private final Hashtable ops; // list of pending operations + private volatile StoredObject transaction; // the transaction object // itself /** * Create a new <code>PendingTxn</code> for the given <code>id</code>. Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Registration.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Registration.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Registration.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Registration.java Sun Apr 21 07:53:23 2013 @@ -27,9 +27,9 @@ import com.sun.jini.outrigger.StorableRe class Registration extends Resource { static final long serialVersionUID = 2L; - private BaseObject[] templates; + private final BaseObject[] templates; - private String type; + private final String type; Registration(StorableResource chit, String type, StorableObject[] ts) { super(chit); Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Resource.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Resource.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Resource.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/Resource.java Sun Apr 21 07:53:23 2013 @@ -34,8 +34,8 @@ import java.util.Arrays; class Resource extends BaseObject implements StoredResource { static final long serialVersionUID = -4248052947306243840L; - private byte[] cookie; - private long expiration; + private final byte[] cookie; + private volatile long expiration; Resource(StorableResource resource) { super(resource); Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/SnapshotFile.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/SnapshotFile.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/SnapshotFile.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/SnapshotFile.java Sun Apr 21 07:53:23 2013 @@ -35,11 +35,11 @@ import net.jini.space.InternalSpaceExcep * @author Sun Microsystems, Inc. */ class SnapshotFile extends LogFile { - private RandomAccessFile snapshotFile = null;// current snapshot file - private String fileName = null; // current snapshot file name - private String previousFilename = null; // previous snapshot - private ObjectOutputStream out; // current snapshot stream - private int suffix; // the current suffix number + private volatile RandomAccessFile snapshotFile = null;// current snapshot file + private volatile String fileName = null; // current snapshot file name + private volatile String previousFilename = null; // previous snapshot + private volatile ObjectOutputStream out; // current snapshot stream + private volatile int suffix; // the current suffix number /** Logger for logging persistent store related information */ private static final Logger logger = Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/RetryTask.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/RetryTask.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/RetryTask.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/RetryTask.java Sun Apr 21 07:53:23 2013 @@ -62,16 +62,17 @@ import com.sun.jini.constants.TimeConsta * @see WakeupManager */ import com.sun.jini.thread.WakeupManager.Ticket; +import java.util.concurrent.atomic.AtomicInteger; public abstract class RetryTask implements TaskManager.Task, TimeConstants { private final TaskManager manager; // the TaskManager for this task - private RetryTime retry; // the retry object for this task - private boolean cancelled; // have we been cancelled? - private boolean complete; // have we completed successfully? - private Ticket ticket; // the WakeupManager ticket - private long startTime; // the time when we were created or + private volatile RetryTime retry; // the retry object for this task + private volatile boolean cancelled; // have we been cancelled? + private volatile boolean complete; // have we completed successfully? + private volatile Ticket ticket; // the WakeupManager ticket + private volatile long startTime; // the time when we were created or // last reset - private int attempt; // the current attempt number + private final AtomicInteger attempt; // the current attempt number private final WakeupManager wakeup; // WakeupManager for retry scheduling /** @@ -102,6 +103,7 @@ public abstract class RetryTask implemen public RetryTask(TaskManager manager, WakeupManager wakeupManager) { this.manager = manager; this.wakeup = wakeupManager; + attempt = new AtomicInteger(); reset(); } @@ -122,11 +124,9 @@ public abstract class RetryTask implemen * @see #tryOnce * @see #startTime */ - public void run() { - synchronized (this) { // avoid retry if cancelled - if (cancelled) // if they cancelled - return; // do nothing - } + public void run() { // avoid retry if cancelled + if (cancelled) return; // do nothing + boolean success = false; try { @@ -136,26 +136,29 @@ public abstract class RetryTask implemen if (t instanceof Error) throw (Error) t; if (t instanceof RuntimeException) throw (RuntimeException) t; } - - synchronized (this) { - if (!success) { // if at first we don't succeed ... - attempt++; - long at = retryTime(); // ... try, try again - - if (logger.isLoggable(Level.FINEST)) { - logger.log(Level.FINEST, "retry of {0} in {1} ms", - new Object[]{this, - Long.valueOf(at - System.currentTimeMillis())}); - } - - if (retry == null) // only create it if we need to - retry = new RetryTime(); - ticket = wakeup.schedule(at, retry); - } else { - complete = true; - notifyAll(); // see waitFor() - } - } + if (!success) { // if at first we don't succeed ... + attempt.incrementAndGet(); + long at = retryTime(); // ... try, try again + + if (logger.isLoggable(Level.FINEST)) { + logger.log(Level.FINEST, "retry of {0} in {1} ms", + new Object[]{this, + Long.valueOf(at - System.currentTimeMillis())}); + } + + if (retry == null) // only create it if we need to + retry = new RetryTime(); + ticket = wakeup.schedule(at, retry); + } else { + complete = true; + // Notify was here, however I noticed that during some tests, + // the wakeup manager task was scheduled after cancelling. + synchronized (this){ + notifyAll(); + } // see waitFor() + } + + } /** @@ -173,7 +176,8 @@ public abstract class RetryTask implemen * not own the lock the result is undefined and could result in an * exception. */ - public synchronized long retryTime() { + public long retryTime() { + int attempt = this.attempt.get(); int index = (attempt < delays.length ? attempt : delays.length - 1); return delays[index] + System.currentTimeMillis(); } @@ -182,15 +186,15 @@ public abstract class RetryTask implemen * Return the time this task was created, or the last * time {@link #reset reset} was called. */ - public synchronized long startTime() { + public long startTime() { return startTime; } /** * Return the attempt number, starting with zero. */ - public synchronized int attempt() { - return attempt; + public int attempt() { + return attempt.get(); } /** @@ -200,17 +204,19 @@ public abstract class RetryTask implemen * unless a subclass overrides this to do so. Any override of this * method should invoke <code>super.cancel()</code>. */ - public synchronized void cancel() { + public void cancel() { cancelled = true; - if (ticket != null) - wakeup.cancel(ticket); - notifyAll(); // see waitFor() + Ticket ticket = this.ticket; + if (ticket != null) wakeup.cancel(ticket); + synchronized (this) { + notifyAll(); // see waitFor() + } } /** * Return <code>true</code> if <code>cancel</code> has been invoked. */ - public synchronized boolean cancelled() { + public boolean cancelled() { return cancelled; } @@ -218,26 +224,30 @@ public abstract class RetryTask implemen * Return <code>true</code> if <code>tryOnce</code> has returned * successfully. */ - public synchronized boolean complete() { + public boolean complete() { return complete; } - public synchronized boolean waitFor() throws InterruptedException { - while (!cancelled && !complete) - wait(); - return complete; + public boolean waitFor() throws InterruptedException { + + while (!cancelled && !complete) + synchronized (this){ + wait(); + } + return complete; + } /** * Reset values for a new use of this task. */ - public synchronized void reset() { + public void reset() { cancel(); // remove from the wakeup queue startTime = System.currentTimeMillis(); cancelled = false; complete = false; ticket = null; - attempt = 0; + attempt.set(0); } /** @@ -251,9 +261,7 @@ public abstract class RetryTask implemen * Time to retry the task. */ public void run() { - synchronized (RetryTask.this) { - ticket = null; - } + ticket = null; manager.add(RetryTask.this); } }; Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/TransactionException.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/TransactionException.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/TransactionException.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/TransactionException.java Sun Apr 21 07:53:23 2013 @@ -41,4 +41,8 @@ public class TransactionException extend public TransactionException() { super(); } + + public TransactionException(String desc, Throwable cause){ + super(desc, cause); + } } Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/UnknownTransactionException.java URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/UnknownTransactionException.java?rev=1470272&r1=1470271&r2=1470272&view=diff ============================================================================== --- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/UnknownTransactionException.java (original) +++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/transaction/UnknownTransactionException.java Sun Apr 21 07:53:23 2013 @@ -45,4 +45,8 @@ public class UnknownTransactionException public UnknownTransactionException() { super(); } + + public UnknownTransactionException(String desc, Throwable cause){ + super(desc, cause); + } }
