You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@river.apache.org by pe...@apache.org on 2013/04/26 09:06:31 UTC
svn commit: r1476080 - in /river/jtsk/skunk/qa_refactor/trunk:
qa/src/com/sun/jini/test/impl/outrigger/ src/com/sun/jini/constants/
src/com/sun/jini/jeri/internal/mux/ src/com/sun/jini/landlord/
src/com/sun/jini/lease/ src/com/sun/jini/mahalo/ src/com/...
Author: peter_firmstone
Date: Fri Apr 26 07:06:20 2013
New Revision: 1476080
URL: http://svn.apache.org/r1476080
Log:
Fixed random test failures in com/sun/jini/test/impl/outrigger/leasing/UseTxnMgrSpaceLeaseTestRenewCancel.td
Fixed inconsistent synchronization in JoinManager
Fixed one synchronization issue in LookupLocatorDiscovery
Made LeaseMap implementations thread safe.
Fixed TxnConstants
Simplified EventRegistrationWatcher
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/outrigger.properties
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/constants/TxnConstants.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/StreamConnectionIO.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/landlord/Landlord.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/lease/AbstractLeaseMap.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/AbortJob.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/CommitJob.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/Job.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/LeaseExpirationMgr.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/SettlerTask.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImpl.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/log/MultiLogManager.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/ServiceRegistration.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/StreamKey.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/TransientEventLog.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/DeformedClientLeaseMapWrapper.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/AvailabilityRegistrationWatcher.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHandle.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHolder.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventRegistrationWatcher.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventSender.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/Notifier.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OperationJournal.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OutriggerServerImpl.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/SpaceProxy2.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TakeMultipleWatcher.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnMonitorTask.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnTable.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/BackEnd.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/snaplogstore/ByteArrayWrapper.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java
river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/Lease.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/LeaseMap.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/JoinManager.java
Modified: river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/outrigger.properties
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/outrigger.properties?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/outrigger.properties (original)
+++ river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/outrigger.properties Fri Apr 26 07:06:20 2013
@@ -16,7 +16,7 @@ com.sun.jini.test.spec.javaspace.conform
# general round trip time expected to non-blocking operations.
# should be set to checkTime / 2.
-com.sun.jini.test.spec.javaspace.conformance.instantTime = 5000
+com.sun.jini.test.spec.javaspace.conformance.instantTime=5000
# test defaults
testConfiguration=<url:com/sun/jini/test/impl/outrigger/configs/<config>/default.config>
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/constants/TxnConstants.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/constants/TxnConstants.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/constants/TxnConstants.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/constants/TxnConstants.java Fri Apr 26 07:06:20 2013
@@ -40,16 +40,14 @@ public class TxnConstants implements Tra
* @see net.jini.core.transaction.server.TransactionConstants
*/
public static String getName(int state) {
- String name = "UNKNOWN";
switch (state) {
- case ACTIVE:
- case VOTING:
- case PREPARED:
- case NOTCHANGED:
- case COMMITTED:
- case ABORTED:
- name = stateNames[state];
+ case ACTIVE: return "ACTIVE";
+ case VOTING: return "VOTING";
+ case PREPARED: return "PREPARED";
+ case NOTCHANGED: return "NOTCHANGED";
+ case COMMITTED: return "COMMITTED";
+ case ABORTED: return "ABORTED";
+ default: return "UNKNOWN";
}
- return name;
}
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/StreamConnectionIO.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/StreamConnectionIO.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/StreamConnectionIO.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/jeri/internal/mux/StreamConnectionIO.java Fri Apr 26 07:06:20 2013
@@ -72,10 +72,7 @@ final class StreamConnectionIO extends C
*/
private final LinkedList sendQueue;
- /** buffer for reading incoming data from connection */
- private final ByteBuffer inputBuffer =
- ByteBuffer.allocate(RECEIVE_BUFFER_SIZE); // ready for reading
-
+
/**
* Creates a new StreamConnectionIO for the connection represented by
* the supplied OutputStream and InputStream pair.
@@ -257,6 +254,10 @@ final class StreamConnectionIO extends C
}
private class Reader implements Runnable {
+ /** buffer for reading incoming data from connection */
+ private final ByteBuffer inputBuffer =
+ ByteBuffer.allocate(RECEIVE_BUFFER_SIZE); // ready for reading
+
Reader() { }
public void run() {
@@ -340,9 +341,10 @@ final class StreamConnectionIO extends C
public static ReadableByteChannel newChannel(final InputStream in) {
return new ReadableByteChannel() {
- private boolean open = true;
+ private volatile boolean open = true;
- public int read(ByteBuffer dst) throws IOException {
+ // must be synchronized as per ReadableByteChannel contract
+ public synchronized int read(ByteBuffer dst) throws IOException {
assert dst.hasArray();
byte[] array = dst.array();
int arrayOffset = dst.arrayOffset();
@@ -373,8 +375,9 @@ final class StreamConnectionIO extends C
public boolean isOpen() {
return open;
}
-
- public void close() throws IOException {
+
+ // Blocking as per Channel contract
+ public synchronized void close() throws IOException {
in.close();
open = false;
}
@@ -383,9 +386,10 @@ final class StreamConnectionIO extends C
public static WritableByteChannel newChannel(final OutputStream out) {
return new WritableByteChannel() {
- private boolean open = true;
-
- public int write(ByteBuffer src) throws IOException {
+ private volatile boolean open = true;
+
+ // This method must block while writing as per WritableByteChannel contract.
+ public synchronized int write(ByteBuffer src) throws IOException {
assert src.hasArray();
int len = src.remaining();
@@ -401,7 +405,8 @@ final class StreamConnectionIO extends C
return open;
}
- public void close() throws IOException {
+ // This method must block as per the Channel contract
+ public synchronized void close() throws IOException {
out.close();
open = false;
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/landlord/Landlord.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/landlord/Landlord.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/landlord/Landlord.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/landlord/Landlord.java Fri Apr 26 07:06:20 2013
@@ -124,7 +124,7 @@ public interface Landlord extends Remote
* @see #denied
* @serial
*/
- public long[] granted;
+ public final long[] granted;
/**
* The <code>i</code><sup><i>th</i></sup> -1 in <code>granted</code>
@@ -133,7 +133,7 @@ public interface Landlord extends Remote
*
* @serial
*/
- public Exception[] denied;
+ public final Exception[] denied;
/**
* Create a <code>RenewResults</code> object setting the field
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/lease/AbstractLeaseMap.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/lease/AbstractLeaseMap.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/lease/AbstractLeaseMap.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/lease/AbstractLeaseMap.java Fri Apr 26 07:06:20 2013
@@ -17,13 +17,18 @@
*/
package com.sun.jini.lease;
+import java.rmi.RemoteException;
import java.util.Map;
import java.util.Set;
import java.util.AbstractSet;
import java.util.Collection;
+import java.util.Collections;
import java.util.Iterator;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
import net.jini.core.lease.Lease;
import net.jini.core.lease.LeaseMap;
+import net.jini.core.lease.LeaseMapException;
/**
* A base class for implementing LeaseMaps. This class implements all
@@ -35,43 +40,61 @@ import net.jini.core.lease.LeaseMap;
* @author Sun Microsystems, Inc.
*
*/
-public abstract class AbstractLeaseMap implements LeaseMap {
+public abstract class AbstractLeaseMap implements LeaseMap<Lease, Long>, ConcurrentMap<Lease, Long> {
/**
* Map from Lease to Long(duration), where all leases have the same
* destination.
*
* @serial
*/
- protected final Map map;
+ protected final Map<Lease, Long> map;
+
+ protected final Object mapLock;
/**
* Default to using a small HashMap. It is assumed that
* canContainKey(lease) is true.
+ * @param lease
+ * @param duration
*/
protected AbstractLeaseMap(Lease lease, long duration) {
- this(new java.util.HashMap(13), lease, duration);
+ this(new ConcurrentHashMap<Lease, Long>(13), lease, duration);
}
/**
* Provide a map of your choice. It is assumed that
* canContainKey(lease) is true.
+ * @deprecated to get peoples attention that map may require synchronized access.
*/
- protected AbstractLeaseMap(Map map, Lease lease, long duration) {
- this.map = map;
+ @Deprecated
+ protected AbstractLeaseMap(Map<Lease, Long> map, Lease lease, long duration) {
+ if (map instanceof ConcurrentMap) {
+ this.map = map;
+ mapLock = null;
+ } else {
+ this.map = Collections.synchronizedMap(map);
+ mapLock = map;
+ }
map.put(lease, Long.valueOf(duration));
}
- /** Check that the key is valid for this map */
+ /** Check that the key is valid for this map
+ * @param key
+ */
protected void checkKey(Object key) {
- if (!canContainKey(key))
- throw new IllegalArgumentException(
- "key is not valid for this LeaseMap");
+ if (!canContainKey(key)) {
+ throw new IllegalArgumentException(
+ "key is not valid for this LeaseMap");
+ }
}
- /** Check that the value is a Long */
+ /** Check that the value is a Long
+ * @param value
+ */
protected static void checkValue(Object value) {
- if (!(value instanceof Long))
- throw new IllegalArgumentException("value is not a Long");
+ if (!(value instanceof Long)) {
+ throw new IllegalArgumentException("value is not a Long");
+ }
}
// inherit javadoc
@@ -97,20 +120,20 @@ public abstract class AbstractLeaseMap i
}
// inherit javadoc
- public Object get(Object key) {
+ public Long get(Object key) {
checkKey(key);
return map.get(key);
}
// inherit javadoc
- public Object put(Object key, Object value) {
+ public Long put(Lease key, Long value) {
checkKey(key);
checkValue(value);
return map.put(key, value);
}
// inherit javadoc
- public Object remove(Object key) {
+ public Long remove(Object key) {
checkKey(key);
return map.remove(key);
}
@@ -119,10 +142,11 @@ public abstract class AbstractLeaseMap i
* of the keys and values.
*/
// inherit javadoc
- public void putAll(Map m) {
+ public void putAll(Map<? extends Lease, ? extends Long> m) {
Iterator iter = m.entrySet().iterator();
while (iter.hasNext()) {
- Map.Entry e = (Map.Entry)iter.next();
+ @SuppressWarnings("unchecked")
+ Map.Entry<? extends Lease, ? extends Long> e = (Map.Entry<? extends Lease, ? extends Long>) iter.next();
put(e.getKey(), e.getValue());
}
}
@@ -133,12 +157,12 @@ public abstract class AbstractLeaseMap i
}
// inherit javadoc
- public Set keySet() {
+ public Set<Lease> keySet() {
return map.keySet();
}
// inherit javadoc
- public Collection values() {
+ public Collection<Long> values() {
return map.values();
}
@@ -146,7 +170,7 @@ public abstract class AbstractLeaseMap i
* Map.Entry.setValue.
*/
// inherit javadoc
- public Set entrySet() {
+ public Set<Map.Entry<Lease, Long>> entrySet() {
return new EntrySet(map.entrySet());
}
@@ -160,6 +184,155 @@ public abstract class AbstractLeaseMap i
return map.hashCode();
}
+ @Override
+ public Long putIfAbsent(final Lease key, final Long value) {
+ if (map instanceof ConcurrentMap){
+ ConcurrentMap<Lease, Long> m = (ConcurrentMap<Lease, Long>) map;
+ return m.putIfAbsent(key, value);
+ } else {
+ synchronized (mapLock){
+ Set<Map.Entry<Lease, Long>> entries;
+ entries = map.entrySet();
+ Map.Entry<Lease, Long> entry = new Map.Entry<Lease, Long>(){
+
+ @Override
+ public Lease getKey() {
+ return key;
+ }
+
+ @Override
+ public Long getValue() {
+ return value;
+ }
+
+ @Override
+ public Long setValue(Long value) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ };
+ if (entries.contains(entry)){
+ // Not absent return long.
+ return value;
+ } else if ( map.containsKey(key)) {
+ // Might contain null value;
+ Long result = map.get(key);
+ if (result == null) map.put(key, value);
+ // If result is not null it is returned and no put was made
+ // or if it is null, the key value pair was added and null value
+ // is retruned.
+ return result;
+ } else {
+ map.put(key, value);
+ return null;
+ }
+
+ }
+ }
+ }
+
+ @Override
+ public boolean remove(final Object key, final Object value) {
+ if (map instanceof ConcurrentMap){
+ return ((ConcurrentMap) map).remove(key, value);
+ } else {
+ Set<Map.Entry<Lease,Long>> entries;
+ entries = map.entrySet();
+ Map.Entry entry = new Map.Entry(){
+
+ @Override
+ public Object getKey() {
+ return key;
+ }
+
+ @Override
+ public Object getValue() {
+ return value;
+ }
+
+ @Override
+ public Object setValue(Object value) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ };
+ return entries.remove(entry);
+ }
+ }
+
+ @Override
+ public boolean replace(final Lease key, final Long oldValue, Long newValue) {
+ if (map instanceof ConcurrentMap){
+ return ((ConcurrentMap)map).replace(key, oldValue, newValue);
+ } else {
+ synchronized (mapLock){
+ Set<Map.Entry<Lease,Long>> entries;
+ entries = map.entrySet();
+ Map.Entry<Lease, Long> entry = new Map.Entry<Lease, Long>(){
+
+ @Override
+ public Lease getKey() {
+ return key;
+ }
+
+ @Override
+ public Long getValue() {
+ return oldValue;
+ }
+
+ @Override
+ public Long setValue(Long value) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ };
+ if (entries.contains(entry)){
+ Long result = map.put(key, newValue);
+ assert result.equals(oldValue);
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
+ }
+
+ @Override
+ public Long replace(final Lease key, final Long value) {
+ if (map instanceof ConcurrentMap){
+ return ((ConcurrentMap<Lease, Long>)map).replace(key, value);
+ } else {
+ synchronized (mapLock){
+ Set<Map.Entry<Lease,Long>> entries;
+ entries = map.entrySet();
+ Map.Entry<Lease, Long> entry = new Map.Entry<Lease, Long>(){
+
+ @Override
+ public Lease getKey() {
+ return key;
+ }
+
+ @Override
+ public Long getValue() {
+ return value;
+ }
+
+ @Override
+ public Long setValue(Long value) {
+ throw new UnsupportedOperationException("Not supported.");
+ }
+
+ };
+ if (entries.contains(entry)){
+ Long result = map.put(key, value);
+ return result;
+ } else {
+ return null;
+ }
+ }
+ }
+ }
+
/**
* We use an AbstractSet to minimize the number of places where
* we have to wrap objects inside new classes. This could be
@@ -167,15 +340,15 @@ public abstract class AbstractLeaseMap i
* also use an AbstractSet for this set, so we're really not
* making things that much worse.
*/
- private static final class EntrySet extends AbstractSet {
- private final Set set;
+ private final static class EntrySet extends AbstractSet<Map.Entry<Lease,Long>> {
+ private final Set<Map.Entry<Lease, Long>> set;
- public EntrySet(Set set) {
+ public EntrySet(Set<Map.Entry<Lease, Long>> set) {
this.set = set;
}
/** Wrap so we can do type checking on Map.Entry.setValue. */
- public Iterator iterator() {
+ public Iterator<Map.Entry<Lease, Long>> iterator() {
return new EntryIterator(set.iterator());
}
@@ -197,10 +370,10 @@ public abstract class AbstractLeaseMap i
}
/** A wrapper so that we can wrap each Entry returned. */
- private static final class EntryIterator implements Iterator {
- private final Iterator iter;
+ private static final class EntryIterator implements Iterator<Map.Entry<Lease,Long>> {
+ private final Iterator<Map.Entry<Lease,Long>> iter;
- public EntryIterator(Iterator iter) {
+ public EntryIterator(Iterator<Map.Entry<Lease,Long>> iter) {
this.iter = iter;
}
@@ -208,8 +381,8 @@ public abstract class AbstractLeaseMap i
return iter.hasNext();
}
- public Object next() {
- return new Entry((Map.Entry)iter.next());
+ public Map.Entry<Lease,Long> next() {
+ return new Entry(iter.next());
}
public void remove() {
@@ -218,22 +391,22 @@ public abstract class AbstractLeaseMap i
}
/** Pass through, except for type checking on setValue */
- private static final class Entry implements Map.Entry {
- private final Map.Entry e;
+ private static final class Entry implements Map.Entry<Lease, Long> {
+ private final Map.Entry<Lease, Long> e;
- public Entry(Map.Entry e) {
+ public Entry(Map.Entry<Lease, Long> e) {
this.e = e;
}
- public Object getKey() {
+ public Lease getKey() {
return e.getKey();
}
- public Object getValue() {
+ public Long getValue() {
return e.getValue();
}
- public Object setValue(Object value) {
+ public Long setValue(Long value) {
checkValue(value);
return e.setValue(value);
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/AbortJob.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/AbortJob.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/AbortJob.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/AbortJob.java Fri Apr 26 07:06:20 2013
@@ -58,7 +58,7 @@ class AbortJob extends Job implements Tr
final ServerTransaction tr;
final ClientLog log;
final ParticipantHandle[] handles;
- final int maxtries = 5;
+ static final int maxtries = 5;
static final Logger logger = TxnManagerImpl.participantLogger;
/**
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/CommitJob.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/CommitJob.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/CommitJob.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/CommitJob.java Fri Apr 26 07:06:20 2013
@@ -55,7 +55,7 @@ class CommitJob extends Job implements T
final ServerTransaction tr;
final ClientLog log;
final ParticipantHandle[] handles;
- final int maxtries = Integer.MAX_VALUE;
+ static final int maxtries = Integer.MAX_VALUE;
static final Logger logger = TxnManagerImpl.participantLogger;
/**
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/Job.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/Job.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/Job.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/Job.java Fri Apr 26 07:06:20 2013
@@ -147,8 +147,8 @@ abstract class Job {
*/
public void scheduleTasks() {
TaskManager.Task[] tmp = createTasks();
- int length = tmp.length;
if (tmp != null) {
+ int length = tmp.length;
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST,
"Job:scheduleTasks with {0} tasks",
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/LeaseExpirationMgr.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/LeaseExpirationMgr.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/LeaseExpirationMgr.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/LeaseExpirationMgr.java Fri Apr 26 07:06:20 2013
@@ -25,6 +25,8 @@ import net.jini.id.Uuid;
import com.sun.jini.thread.WakeupManager;
import com.sun.jini.collection.WeakTable;
import com.sun.jini.landlord.LeasedResource;
+import java.util.logging.Level;
+import java.util.logging.Logger;
/**
@@ -137,9 +139,9 @@ class LeaseExpirationMgr implements Leas
public void run() {
final LeasedResource resource = (LeasedResource)resourceRef.get();
if (resource == null)
- // Already gone
+ // Already gone
return;
-
+
synchronized (resource) {
if (resource.getExpiration() <= System.currentTimeMillis()) {
try {
@@ -147,6 +149,7 @@ class LeaseExpirationMgr implements Leas
landlord.cancel(resource.getCookie());
} catch (UnknownLeaseException e) {
// Don't care, probably already gone
+ Logger.getLogger(LeaseExpirationMgr.class.getName()).log(Level.SEVERE, null, e);
}
}
// else Someone must have just renewed the resource,
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/SettlerTask.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/SettlerTask.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/SettlerTask.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/SettlerTask.java Fri Apr 26 07:06:20 2013
@@ -122,14 +122,14 @@ public class SettlerTask extends RetryTa
transactionsLogger.log(Level.WARNING,
"Unable to settle recovered transaction", nsoe);
}
- nsoe.printStackTrace(System.err);
+// nsoe.printStackTrace(System.err);
//TODO -ignore?
} catch (TransactionException te) {
if(transactionsLogger.isLoggable(Levels.HANDLED)) {
transactionsLogger.log(Levels.HANDLED,
"Unable to settle recovered transaction", te);
}
- te.printStackTrace(System.err);
+// te.printStackTrace(System.err);
//TODO -ignore?
} catch (RemoteException re) {
//try again
@@ -137,7 +137,7 @@ public class SettlerTask extends RetryTa
operationsLogger.exiting(SettlerTask.class.getName(),
"tryOnce", Boolean.valueOf(false));
}
- re.printStackTrace(System.err);
+// re.printStackTrace(System.err);
return false;
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImpl.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/TxnManagerImpl.java Fri Apr 26 07:06:20 2013
@@ -805,7 +805,7 @@ class TxnManagerImpl /*extends RemoteSer
try {
txntr.abort(waitFor);
} catch (Throwable t){
- t.printStackTrace(System.err);
+// t.printStackTrace(System.err);
if (t instanceof Error) throw (Error) t;
if (t instanceof RuntimeException) throw (RuntimeException) t;
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/log/MultiLogManager.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/log/MultiLogManager.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/log/MultiLogManager.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mahalo/log/MultiLogManager.java Fri Apr 26 07:06:20 2013
@@ -359,7 +359,7 @@ public class MultiLogManager
else {
if (persistenceLogger.isLoggable(Level.FINEST)) {
persistenceLogger.log(Level.FINEST,
- "Observed a null log file entry for: {0}", slf);
+ "Observed a null log file entry at: {0}", i);
}
}
} catch (LogException le) {
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/ServiceRegistration.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/ServiceRegistration.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/ServiceRegistration.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/ServiceRegistration.java Fri Apr 26 07:06:20 2013
@@ -33,6 +33,7 @@ import java.util.HashMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
import net.jini.core.event.RemoteEventListener;
@@ -55,7 +56,7 @@ class ServiceRegistration implements Lea
private final Uuid cookie;
/** The current expiration for this registration */
- private long expiration = 0;
+ private volatile long expiration = 0;
/** The prepared, client-provided notification target. */
// This field is transient in order to allow readObject/writeObject
@@ -95,7 +96,7 @@ class ServiceRegistration implements Lea
* active (re)set will provide a new/better target listener that might
* be able to handle these events.
*/
- private Map unknownEvents = new HashMap();
+ private final Map unknownEvents = new ConcurrentHashMap();
/**
* Unique identifier object for the currently enabled
@@ -106,8 +107,11 @@ class ServiceRegistration implements Lea
/**
* Lock object used to coordinate event delivery via the iterator.
* Has to be a serializable object versus just a plain Object.
+ *
+ * WTF? Never use a String lock!!!
+ *
*/
- private final String iteratorNotifier = new String();
+ private final Object iteratorNotifier = new Lock();
/** Convenience constructor */
@@ -146,13 +150,13 @@ class ServiceRegistration implements Lea
* Get the reference to the prepared,
* client-supplied notification target
*/
- public RemoteEventListener getEventTarget() {
+ public synchronized RemoteEventListener getEventTarget() {
return preparedEventTarget;
}
/** Set the reference to the client-supplied notification target */
- public void setEventTarget(RemoteEventListener preparedTarget)
+ public synchronized void setEventTarget(RemoteEventListener preparedTarget)
throws IOException
{
if (preparedTarget == null) {
@@ -165,7 +169,7 @@ class ServiceRegistration implements Lea
}
/** Get the remote iterator id */
- public Uuid getRemoteEventIteratorID() {
+ public synchronized Uuid getRemoteEventIteratorID() {
return remoteEventIteratorID;
}
@@ -179,7 +183,7 @@ class ServiceRegistration implements Lea
}
/** Set the remote iterator id */
- public void setRemoteEventIteratorID(Uuid id) {
+ public synchronized void setRemoteEventIteratorID(Uuid id) {
remoteEventIteratorID = id;
}
@@ -188,7 +192,7 @@ class ServiceRegistration implements Lea
* Returns <code>true</code> if an event target is currently set and
* false otherwise.
*/
- public boolean hasEventTarget() {
+ public synchronized boolean hasEventTarget() {
return (marshalledEventTarget != null);
}
@@ -206,11 +210,13 @@ class ServiceRegistration implements Lea
throw new NullPointerException(
"targetPreparer cannot be null");
}
- if (marshalledEventTarget != null) {
- RemoteEventListener unprepared =
- (RemoteEventListener)marshalledEventTarget.get();
- preparedEventTarget = (RemoteEventListener)
- targetPreparer.prepareProxy(unprepared);
+ synchronized (this){
+ if (marshalledEventTarget != null) {
+ RemoteEventListener unprepared =
+ (RemoteEventListener)marshalledEventTarget.get();
+ preparedEventTarget = (RemoteEventListener)
+ targetPreparer.prepareProxy(unprepared);
+ }
}
/*
* Note: Would like to defer preparation until listener
@@ -225,7 +231,7 @@ class ServiceRegistration implements Lea
* Get the reference to the registration's associated
* <tt>EventLogIterator</tt>
*/
- public EventLogIterator iterator() {
+ public synchronized EventLogIterator iterator() {
return eventIterator;
}
@@ -233,7 +239,7 @@ class ServiceRegistration implements Lea
* Set the reference for this registration's
* <tt>EventLogIterator</tt>
*/
- public void setIterator(EventLogIterator iter) {
+ public synchronized void setIterator(EventLogIterator iter) {
eventIterator = iter;
}
@@ -242,7 +248,7 @@ class ServiceRegistration implements Lea
* secondary sort is immaterial, except to ensure a total order
* (required by TreeMap).
*/
- public int compareTo(Object obj) {
+ public synchronized int compareTo(Object obj) {
ServiceRegistration reg = (ServiceRegistration)obj;
if (this == reg)
return 0;
@@ -267,7 +273,7 @@ class ServiceRegistration implements Lea
* Utility method to display debugging information to the
* provided <tt>Logger</tt>
*/
- void dumpInfo(Logger logger) {
+ synchronized void dumpInfo(Logger logger) {
logger.log(Level.FINEST, "{0}", this.toString());
logger.log(Level.FINEST, "Expires at: {0}", new Date(expiration));
logger.log(Level.FINEST, "Prepared target is: {0}", preparedEventTarget);
@@ -285,4 +291,9 @@ class ServiceRegistration implements Lea
}
}
}
+
+ /* Stateless serializable lock */
+ private static final class Lock implements Serializable {
+ private static final long serialVersionUID = 1L;
+ }
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/StreamKey.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/StreamKey.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/StreamKey.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/StreamKey.java Fri Apr 26 07:06:20 2013
@@ -30,13 +30,13 @@ import java.io.File;
class StreamKey {
/** Holds the <tt>File</tt> attribute for the associated stream. */
- private /*final*/ File file;
+ private final /*final*/ File file;
/** Holds the "enumeration" type for the associated stream. */
- private /*final*/ StreamType type;
+ private final /*final*/ StreamType type;
/** Holds the cached value of the <tt>file</tt> field's hashCode. */
- private /*final*/ int hash;
+ private final /*final*/ int hash;
/**
* Simple constructor that accepts <tt>File</tt> and <tt>StreamType</tt>
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/TransientEventLog.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/TransientEventLog.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/TransientEventLog.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/mercury/TransientEventLog.java Fri Apr 26 07:06:20 2013
@@ -31,6 +31,7 @@ import java.util.ListIterator;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.NoSuchElementException;
+import java.util.concurrent.atomic.AtomicLong;
/**
* Class that implements the interface for an <tt>EventLog</tt>.
@@ -66,22 +67,22 @@ class TransientEventLog implements Event
//
/** The associated <tt>Uuid</tt> for this <tt>EventLog</tt>. */
- private Uuid uuid = null;
+ private final Uuid uuid;
/** The associated, non-persistent storage for events */
- private List entries = null;
+ private final List entries;
/**
* Flag that is used to determine whether or not this object
* has been closed.
*/
- private boolean closed = false;
+ private volatile boolean closed = false;
/**
* Flag that is used to determine whether or not this object
* has been initialized.
*/
- private boolean initialized = false;
+ private volatile boolean initialized = false;
/**
* Helper class used to hold a remote event and a sequence id.
@@ -100,7 +101,7 @@ class TransientEventLog implements Event
/**
* Counter used to produce event ids.
*/
- private long eventCounter = 1L;
+ private AtomicLong eventCounter = new AtomicLong(1);
/**
* Simple constructor that takes a <tt>Uuid</tt> argument.
@@ -145,7 +146,7 @@ class TransientEventLog implements Event
// Inherit documentation from supertype
public void add(RemoteEvent event) throws IOException {
stateCheck();
- long id = eventCounter++;
+ long id = eventCounter.getAndIncrement();
RemoteEventHolder data = new RemoteEventHolder(id, event);
entries.add(data);
printControlData(persistenceLogger, "TransientEventLog::add");
@@ -220,7 +221,7 @@ class TransientEventLog implements Event
// TODO - trap ClassCastException and throw?
long lastID = ((Long)cookie).longValue();
- if (lastID >= eventCounter) {
+ if (lastID >= eventCounter.get()) {
throw new NoSuchElementException();
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/DeformedClientLeaseMapWrapper.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/DeformedClientLeaseMapWrapper.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/DeformedClientLeaseMapWrapper.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/norm/DeformedClientLeaseMapWrapper.java Fri Apr 26 07:06:20 2013
@@ -25,6 +25,8 @@ import net.jini.core.lease.LeaseExceptio
import net.jini.core.lease.LeaseMapException;
import com.sun.jini.lease.AbstractLeaseMap;
+import java.util.concurrent.ConcurrentMap;
+import net.jini.core.lease.Lease;
/**
* An implementation of LeaseMap that holds exactly one lease. Used when
@@ -51,7 +53,7 @@ class DeformedClientLeaseMapWrapper exte
* @param duration the duration to associate with lease
*/
DeformedClientLeaseMapWrapper(ClientLeaseWrapper lease, long duration) {
- super(new HashMap(1), lease, duration);
+ super(new HashMap<Lease, Long>(1), lease, duration);
}
// inherit javadoc
@@ -63,13 +65,23 @@ class DeformedClientLeaseMapWrapper exte
// inherit javadoc
public void renewAll() throws LeaseMapException, RemoteException {
- ClientLeaseWrapper l =
+ if (map instanceof ConcurrentMap){
+ renewAl();
+ } else {
+ synchronized (mapLock){
+ renewAl();
+ }
+ }
+ }
+
+ private void renewAl() throws LeaseMapException, RemoteException {
+ ClientLeaseWrapper l =
(ClientLeaseWrapper) (map.keySet().iterator().next());
- long d = ((Integer) (map.get(l))).longValue();
+ long d = ( (map.get(l))).longValue();
try {
l.renew(d);
} catch (LeaseException e) {
- final Map m = new HashMap(1);
+ final Map<ClientLeaseWrapper, LeaseException> m = new HashMap<ClientLeaseWrapper, LeaseException>(1);
m.put(l, e);
throw new LeaseMapException(e.getMessage(), m);
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/AvailabilityRegistrationWatcher.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/AvailabilityRegistrationWatcher.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/AvailabilityRegistrationWatcher.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/AvailabilityRegistrationWatcher.java Fri Apr 26 07:06:20 2013
@@ -375,12 +375,12 @@ abstract class AvailabilityRegistrationW
cancel();
}
- /**
- * Since we try to send every event that occurs, don't
- * care which order they run.
- */
- public boolean runAfter(EventSender other) {
- return false;
- }
+// /**
+// * Since we try to send every event that occurs, don't
+// * care which order they run.
+// */
+// public boolean runAfter(EventSender other) {
+// return false;
+// }
}
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHandle.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHandle.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHandle.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHandle.java Fri Apr 26 07:06:20 2013
@@ -110,7 +110,7 @@ import com.sun.jini.landlord.LeasedResou
class EntryHandle extends BaseHandle implements LeaseDesc, Transactable {
/** the content hash for the rep */
- private long hash;
+ private final long hash; // Made final for toString() and hash().
/**
* If this entry is locked by one or more transaction the info
@@ -266,10 +266,12 @@ class EntryHandle extends BaseHandle imp
// EntryHolder.SimpleRepEnum.nextRep(). Working it through
// it seems to work in that particular case, but it seems fragile.
boolean canPerform(TransactableMgr mgr, int op) {
- if (txnState == null)
- return true; // all operations are legal on a non-transacted entry
+ synchronized (this){ // Audit revealed calling thread didn't always own lock.
+ if (txnState == null)
+ return true; // all operations are legal on a non-transacted entry
- return txnState.canPerform(mgr, op);
+ return txnState.canPerform(mgr, op);
+ }
}
/**
@@ -278,10 +280,12 @@ class EntryHandle extends BaseHandle imp
* thread calling this method should own this object's lock.
*/
boolean knownMgr(TransactableMgr mgr) {
- if (txnState == null)
- return (mgr == null); // The only mgr we know about is the null mgr
+ synchronized (this){ // Audit revealed caller methods didn't always hold lock.
+ if (txnState == null)
+ return (mgr == null); // The only mgr we know about is the null mgr
- return txnState.knownMgr(mgr);
+ return txnState.knownMgr(mgr);
+ }
}
/**
@@ -290,7 +294,7 @@ class EntryHandle extends BaseHandle imp
* method should own this object's lock.
*/
boolean onlyMgr(TransactableMgr mgr) {
- if (txnState == null)
+ if (txnState == null) // Audit revealed caller always held lock.
return false;
return txnState.onlyMgr(mgr);
@@ -302,7 +306,9 @@ class EntryHandle extends BaseHandle imp
* method should own this object's lock.
*/
boolean managed() {
- return txnState != null;
+ synchronized (this){ // Audit revealed caller didn't always have lock.
+ return txnState != null;
+ }
}
/**
@@ -311,7 +317,7 @@ class EntryHandle extends BaseHandle imp
* lock.
*/
void addTxns(java.util.Collection collection) {
- if (txnState == null)
+ if (txnState == null) // Confirmed that calling method owns lock.
return; // nothing to add
txnState.addTxns(collection);
@@ -326,11 +332,13 @@ class EntryHandle extends BaseHandle imp
* <code>EntryHolder</code> holding this handle.
*/
void add(TransactableMgr mgr, int op, EntryHolder holder) {
- if (txnState == null) {
- txnState = new TxnState(mgr, op, holder);
- } else {
- txnState.add(mgr, op);
- }
+ synchronized (this){
+ if (txnState == null) {
+ txnState = new TxnState(mgr, op, holder);
+ } else {
+ txnState.add(mgr, op);
+ }
+ }
}
/**
@@ -340,7 +348,9 @@ class EntryHandle extends BaseHandle imp
* transaction that owns a lock on the entry.
*/
boolean promoteToTakeIfNeeded() {
- return txnState.promoteToTakeIfNeeded();
+ synchronized (this){
+ return txnState.promoteToTakeIfNeeded();
+ }
}
/**
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHolder.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHolder.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHolder.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EntryHolder.java Fri Apr 26 07:06:20 2013
@@ -307,7 +307,7 @@ class EntryHolder implements Transaction
matchingLogger.log(Level.FINER, "match, but can''t " +
"perform {0}; handle.knownMgr(txn) == {1}",
new Object[] {Integer.valueOf(op),
- new Boolean(handle.knownMgr(txn))});
+ Boolean.valueOf(handle.knownMgr(txn))});
}
if (conflictSet != null) {
@@ -747,7 +747,7 @@ class EntryHolder implements Transaction
* but the transaction is no longer active.
*/
EntryHandle next(Set conflictSet, Set lockedEntrySet,
- WeakHashMap provisionallyRemovedEntrySet)
+ Map provisionallyRemovedEntrySet)
throws CannotJoinException
{
matchingLogger.entering("ContinuingQuery", "next");
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventRegistrationWatcher.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventRegistrationWatcher.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventRegistrationWatcher.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventRegistrationWatcher.java Fri Apr 26 07:06:20 2013
@@ -46,32 +46,32 @@ abstract class EventRegistrationWatcher
* Protected, but only for use by subclasses.
* Should not be changed.
*/
- volatile Uuid cookie;
+ Uuid cookie;
/**
* The handback associated with this registration.
* Protected, but only for use by subclasses.
* Should not be changed.
*/
- volatile MarshalledObject handback;
+ MarshalledObject handback;
/**
* The event ID associated with this registration
* Protected, but only for use by subclasses.
* Should not be changed.
*/
- volatile long eventID;
+ long eventID;
/**
* The current sequence number.
*/
private long currentSeqNum = 0;
- /**
- * The sequence number of the last event successfully
- * delivered. Protected, but only for use by subclasses.
- */
- volatile long lastSeqNumDelivered = -1;
+// /**
+// * The sequence number of the last event successfully
+// * delivered. Protected, but only for use by subclasses.
+// */
+// volatile long lastSeqNumDelivered = -1;
/**
* The <code>TemplateHandle</code> associated with this
@@ -102,6 +102,9 @@ abstract class EventRegistrationWatcher
{
super(timestamp, startOrdinal);
this.currentSeqNum = currentSeqNum;
+ handback = null;
+ cookie = null;
+ eventID = 0;
}
/**
@@ -165,7 +168,7 @@ abstract class EventRegistrationWatcher
doneFor = true;
} else {
currentSeqNum++;
- owner.getServer().enqueueDelivery(new BasicEventSender());
+ owner.getServer().enqueueDelivery(new BasicEventSender(currentSeqNum, eventID, handback));
}
}
@@ -225,7 +228,7 @@ abstract class EventRegistrationWatcher
* Assumes locking is handled by the caller.
* @param newExpiration The expiration time.
*/
- public void setExpiration(long newExpiration) {
+ public synchronized void setExpiration(long newExpiration) {
expiration = newExpiration;
}
@@ -300,44 +303,56 @@ abstract class EventRegistrationWatcher
* Common implementation of <code>EventSender</code>.
*/
private class BasicEventSender implements EventSender {
+
+ private final long seqNum;
+ private final long eventID;
+ private final MarshalledObject handback;
+
+ BasicEventSender(long seqNum, long eventID, MarshalledObject handback){
+ this.seqNum = seqNum;
+ this.eventID = eventID;
+ this.handback = handback;
+ }
+
public void sendEvent(JavaSpace source, long now, ProxyPreparer preparer)
throws UnknownEventException, IOException, ClassNotFoundException
{
- boolean doneFor = false;
- long seqNum = -1;
-
- synchronized (EventRegistrationWatcher.this) {
- if (owner == null)
- return; // Our watcher must have been removed, we're done
-
- if (getExpiration() < now) {
- doneFor = true; // Our watcher is expired, remove it
- } else if (currentSeqNum <= lastSeqNumDelivered) {
- return; // Someone already sent our event, we're done
- } else {
- // We need to send an event!
- seqNum = currentSeqNum;
- }
-
-
- // cancel is a synchronized method with the same lock.
- if (doneFor) {
- cancel();
- return;
- }
-
- /* The only way to get here is through a path that sets
- * seqNum to the non-initial values
- */
- assert seqNum != -1;
-
-
-
- // success!, update lastSeqNumDelivered, but don't go backward
-
- if (seqNum > lastSeqNumDelivered)
- lastSeqNumDelivered = seqNum;
- }
+ // Forget all the tricky crap, just send it.
+// boolean doneFor = false;
+// long seqNum = -1;
+//
+// synchronized (EventRegistrationWatcher.this) {
+// if (owner == null)
+// return; // Our watcher must have been removed, we're done
+//
+// if (getExpiration() < now) {
+// doneFor = true; // Our watcher is expired, remove it
+// } else if (currentSeqNum <= lastSeqNumDelivered) {
+// return; // Someone already sent our event, we're done
+// } else {
+// // We need to send an event!
+// seqNum = currentSeqNum;
+// }
+//
+//
+// // cancel is a synchronized method with the same lock.
+// if (doneFor) {
+// cancel();
+// return;
+// }
+//
+// /* The only way to get here is through a path that sets
+// * seqNum to the non-initial values
+// */
+// assert seqNum != -1;
+//
+//
+//
+// // success!, update lastSeqNumDelivered, but don't go backward
+//
+// if (seqNum > lastSeqNumDelivered)
+// lastSeqNumDelivered = seqNum;
+// }
/* If we are here then we need to send an event (probably
* someone could have sent our event between the time
@@ -352,15 +367,15 @@ abstract class EventRegistrationWatcher
cancel();
}
- /**
- * Return the <code>EventRegistrationWatcher</code> this
- * object is part of (exits because
- * <code>(BasicEventSender)other).EventRegistrationWatcher.
- * this</code> does not work.
- */
- private EventRegistrationWatcher getOwner() {
- return EventRegistrationWatcher.this;
- }
+// /**
+// * Return the <code>EventRegistrationWatcher</code> this
+// * object is part of (exits because
+// * <code>(BasicEventSender)other).EventRegistrationWatcher.
+// * this</code> does not work.
+// */
+// private EventRegistrationWatcher getOwner() {
+// return EventRegistrationWatcher.this;
+// }
/**
* Run after another event sender if it is for the same
@@ -369,12 +384,12 @@ abstract class EventRegistrationWatcher
* run since <code>lastSeqNumDelivered</code> will probably
* equal <code>currentSeqNum</code> when it runs).
*/
- public boolean runAfter(EventSender other) {
- if (!(other instanceof BasicEventSender))
- return false;
-
- return EventRegistrationWatcher.this ==
- ((BasicEventSender)other).getOwner();
- }
+// public boolean runAfter(EventSender other) {
+// if (!(other instanceof BasicEventSender))
+// return false;
+//
+// return EventRegistrationWatcher.this ==
+// ((BasicEventSender)other).getOwner();
+// }
}
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventSender.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventSender.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventSender.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/EventSender.java Fri Apr 26 07:06:20 2013
@@ -71,12 +71,12 @@ interface EventSender {
*/
public void cancelRegistration();
- /**
- * Return <code>true</code> if the passed <code>EventSender</code>
- * should run before this one, otherwise return <code>false</code>.
- * @param other the sender this object should compare itself too.
- * @return <code>true</code> if this object should run after
- * <code>other</code>.
- */
- public boolean runAfter(EventSender other);
+// /**
+// * Return <code>true</code> if the passed <code>EventSender</code>
+// * should run before this one, otherwise return <code>false</code>.
+// * @param other the sender this object should compare itself too.
+// * @return <code>true</code> if this object should run after
+// * <code>other</code>.
+// */
+// public boolean runAfter(EventSender other);
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/Notifier.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/Notifier.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/Notifier.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/Notifier.java Fri Apr 26 07:06:20 2013
@@ -244,14 +244,14 @@ class Notifier implements com.sun.jini.c
}
public boolean runAfter(java.util.List list, int max) {
- for (int i = 0; i < max; i++) {
- Object task = list.get(i);
- if (task instanceof NotifyTask) {
- NotifyTask nt = (NotifyTask)task;
- if (sender.runAfter(nt.sender))
- return true;
- }
- }
+// for (int i = 0; i < max; i++) {
+// Object task = list.get(i);
+// if (task instanceof NotifyTask) {
+// NotifyTask nt = (NotifyTask)task;
+// if (sender.runAfter(nt.sender))
+// return true;
+// }
+// }
return false;
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OperationJournal.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OperationJournal.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OperationJournal.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OperationJournal.java Fri Apr 26 07:06:20 2013
@@ -130,7 +130,7 @@ class OperationJournal extends Thread {
* <code>JournalNode</code> payload value used for
* caught up markers.
*/
- private class CaughtUpMarker {
+ private static class CaughtUpMarker {
/** The watcher to notify */
private final IfExistsWatcher watcher;
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OutriggerServerImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OutriggerServerImpl.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OutriggerServerImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/OutriggerServerImpl.java Fri Apr 26 07:06:20 2013
@@ -17,6 +17,8 @@
*/
package com.sun.jini.outrigger;
+import au.net.zeus.collection.RC;
+import au.net.zeus.collection.Ref;
import com.sun.jini.config.Config;
import com.sun.jini.constants.TimeConstants;
import com.sun.jini.landlord.Landlord;
@@ -591,7 +593,6 @@ public class OutriggerServerImpl
recoveredTransactionManagerPreparer = h.recoveredTransactionManagerPreparer;
recoveredListenerPreparer = h.recoveredListenerPreparer;
txnTable = h.txnTable;
- leaseFactory = h.leaseFactory;
entryLeasePolicy = h.entryLeasePolicy;
eventLeasePolicy = h.eventLeasePolicy;
contentsLeasePolicy = h.contentsLeasePolicy;
@@ -599,7 +600,6 @@ public class OutriggerServerImpl
takeLimit = h.takeLimit;
maxUnexportDelay = h.maxUnexportDelay;
unexportRetryDelay = h.unexportRetryDelay;
- notifier = h.notifier;
templateReaperThread = h.templateReaperThread;
entryReaperThread = h.entryReaperThread;
contentsQueryReaperThread = h.contentsQueryReaperThread;
@@ -806,7 +806,6 @@ public class OutriggerServerImpl
ProxyPreparer recoveredTransactionManagerPreparer;
ProxyPreparer recoveredListenerPreparer;
TxnTable txnTable;
- LeaseFactory leaseFactory;
LeasePeriodPolicy entryLeasePolicy;
LeasePeriodPolicy eventLeasePolicy;
LeasePeriodPolicy contentsLeasePolicy;
@@ -814,7 +813,6 @@ public class OutriggerServerImpl
int takeLimit;
long maxUnexportDelay;
long unexportRetryDelay;
- Notifier notifier;
TemplateReaper templateReaperThread;
EntryReaper entryReaperThread;
ContentsQueryReaper contentsQueryReaperThread;
@@ -1898,7 +1896,8 @@ public class OutriggerServerImpl
EntryHandle[] handles = new EntryHandle[limit];
int found = 0;
final Set conflictSet = new java.util.HashSet();
- final WeakHashMap provisionallyRemovedEntrySet = new WeakHashMap();
+ final Map provisionallyRemovedEntrySet =
+ RC.map(new ConcurrentHashMap(), Ref.WEAK_IDENTITY, Ref.STRONG, 1000L, 1000L);
for (Iterator i=classes.iterator();
i.hasNext() && found < handles.length;)
@@ -2261,8 +2260,10 @@ public class OutriggerServerImpl
// Shared by multiple new objects.
final Set lockedEntrySet =
(ifExists? Collections.newSetFromMap( new ConcurrentHashMap()):null);
+
+ // Changed to concurrent map, because unsynchronized iteration occurs.
final Map provisionallyRemovedEntrySet =
- Collections.synchronizedMap(new java.util.WeakHashMap());
+ RC.map(new ConcurrentHashMap(), Ref.WEAK_IDENTITY, Ref.STRONG, 1000L, 1000L);
/*
* First we do the straight search
@@ -2639,7 +2640,7 @@ public class OutriggerServerImpl
final private Uuid uuid;
/** The <code>Set</code> of classes we need to search */
- final private Set classes = new java.util.HashSet();
+// final private Set classes = new java.util.HashSet();
/** An iteration into <code>classes</code> */
final private Iterator classesIterator;
@@ -2654,7 +2655,7 @@ public class OutriggerServerImpl
final private Object lock = new Object();
/** The current expiration time */
- private long expiration;
+ private volatile long expiration;
/** The current <code>ContinuingQuery</code> */
private EntryHolder.ContinuingQuery currentQuery;
@@ -2675,15 +2676,15 @@ public class OutriggerServerImpl
* Set of entries that we have encountered that have been
* provisionally removed
*/
- final private WeakHashMap provisionallyRemovedEntrySet
- = new WeakHashMap();
+ final private Map provisionallyRemovedEntrySet
+ = RC.map(new ConcurrentHashMap(), Ref.WEAK_IDENTITY, Ref.STRONG, 1000L, 1000L) ;
private ContentsQuery(Uuid uuid, EntryRep[] tmpls, Txn txn, long limit) {
this.uuid = uuid;
this.tmpls = tmpls;
this.txn = txn;
remaining = limit;
-
+ Set classes = new java.util.HashSet(128);
for (int i=0; i<tmpls.length; i++) {
final String whichClass = tmpls[i].classFor();
final Iterator subtypes = types.subTypes(whichClass);
@@ -3215,8 +3216,8 @@ public class OutriggerServerImpl
*/
private class AllReps implements RepEnum {
RepEnum curEnum; // current unexhausted enum (or null)
- Stack toDo; // classes left to do
- Txn txn; // txn under which this is done
+ final Stack toDo; // classes left to do
+ final Txn txn; // txn under which this is done
/** Create a new <code>AllReps</code> object for the given class. */
AllReps(String classFor, Txn txn) {
@@ -3231,7 +3232,7 @@ public class OutriggerServerImpl
* are added -- the rest will be picked up when the subclasses are
* set up.
*/
- private void setup(String classFor) {
+ private synchronized void setup(String classFor) {
if (classFor == null)
return;
@@ -3258,7 +3259,7 @@ public class OutriggerServerImpl
}
// purposefully inherit doc comment
- public EntryRep nextRep() {
+ public synchronized EntryRep nextRep() {
/*
* We loop to handle the case where the list of elements for
* a type is empty, which means we have to proceed immediately
@@ -3330,7 +3331,7 @@ public class OutriggerServerImpl
}
// inherit doc comment
- public EntryRep[] nextReps(int max, Uuid id) {
+ public synchronized EntryRep[] nextReps(int max, Uuid id) {
if (closed && id != null && lastId == null)
// They never got the null
return null;
@@ -3399,7 +3400,7 @@ public class OutriggerServerImpl
* Delete the entry of the given class and id. We use class
* to get us to the proper <code>EntryHolder</code> efficiently.
*/
- public void delete(Uuid id) {
+ public synchronized void delete(Uuid id) {
assertOpen();
try {
boolean found = false;
@@ -3427,7 +3428,7 @@ public class OutriggerServerImpl
/**
* Close operations on this iterator.
*/
- public void close() {
+ public synchronized void close() {
closed = true;
repEnum = null;
rememberLast(null);
@@ -3513,9 +3514,8 @@ public class OutriggerServerImpl
if (txnId == null)
return null;
- Txn txn;
- if((recoveredTxns.isEmpty()) ||
- ((txn = (Txn)recoveredTxns.get(txnId)) == null))
+ Txn txn = recoveredTxns.get(txnId);
+ if (txn == null)
throw new InternalSpaceException("recover of write/take with " +
"unknown txnId" );
return txn;
@@ -3914,7 +3914,7 @@ public class OutriggerServerImpl
*/
private static abstract class Reaper extends Thread {
final private long interval;
- private boolean dead = false;
+ private volatile boolean dead = false;
private Reaper(String name, long interval) {
super(name);
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/SpaceProxy2.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/SpaceProxy2.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/SpaceProxy2.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/SpaceProxy2.java Fri Apr 26 07:06:20 2013
@@ -297,7 +297,7 @@ class SpaceProxy2 implements JavaSpace05
if (leaseData == null || leaseData.length != 3){
StringBuilder sb = new StringBuilder(180);
sb.append("space.write returned malformed data \n");
- int l = leaseData.length;
+ int l = leaseData == null? 0 : leaseData.length;
for (int i =0; i < l; i++){
sb.append(leaseData[i]).append("\n");
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TakeMultipleWatcher.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TakeMultipleWatcher.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TakeMultipleWatcher.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TakeMultipleWatcher.java Fri Apr 26 07:06:20 2013
@@ -19,6 +19,7 @@ package com.sun.jini.outrigger;
import java.util.Set;
import java.util.Iterator;
+import java.util.Map;
import java.util.WeakHashMap;
import net.jini.core.transaction.TransactionException;
@@ -45,7 +46,7 @@ class TakeMultipleWatcher extends QueryW
* we would have liked to return, but have been provisionally
* removed.
*/
- private final WeakHashMap provisionallyRemovedEntrySet;
+ private final Map provisionallyRemovedEntrySet;
/**
* If non-null the transaction this query is
@@ -106,7 +107,7 @@ class TakeMultipleWatcher extends QueryW
* a transaction the <code>Txn</code> object
* associated with that transaction. */
TakeMultipleWatcher(int limit, long expiration, long timestamp,
- long startOrdinal, WeakHashMap provisionallyRemovedEntrySet, Txn txn)
+ long startOrdinal, Map provisionallyRemovedEntrySet, Txn txn)
{
super(expiration, timestamp, startOrdinal);
this.limit = limit;
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnMonitorTask.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnMonitorTask.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnMonitorTask.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnMonitorTask.java Fri Apr 26 07:06:20 2013
@@ -266,7 +266,7 @@ class TxnMonitorTask extends RetryTask
if (logger.isLoggable(Level.FINEST)) {
logger.log(Level.FINEST, "{0} attempt {1} mustQuery:{2}",
new Object[]{this, Integer.valueOf(attempt()),
- new Boolean(mustQuery) });
+ Boolean.valueOf(mustQuery) });
}
/*
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnTable.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnTable.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnTable.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/outrigger/TxnTable.java Fri Apr 26 07:06:20 2013
@@ -48,7 +48,7 @@ class TxnTable {
* so we can make sure we don't call <code>equals</code> on unprepared
* managers.
*/
- private class Key {
+ private static class Key {
/** The manager for the transaction */
private final TransactionManager manager;
@@ -187,7 +187,7 @@ class TxnTable {
if (r != null) return r;
// Check broken txns
- if (brokenTxns.isEmpty()) return null;// No broken Txns so txns is definitive
+// if (brokenTxns.isEmpty()) return null;// No broken Txns so txns is definitive
idAsLong = Long.valueOf(id);
final List txnsForId = (List) brokenTxns.get(idAsLong);
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=1476080&r1=1476079&r2=1476080&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 Fri Apr 26 07:06:20 2013
@@ -74,7 +74,7 @@ class BackEnd implements Observer {
private volatile SnapshotFile snapshotFile;
/** Keep logs and snapshot tied, though not necessary */
- private final int SNAPSHOT_VERSION = LogFile.LOG_VERSION;
+ private static final int SNAPSHOT_VERSION = LogFile.LOG_VERSION;
/**
* The base name for the log files.
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=1476080&r1=1476079&r2=1476080&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 Fri Apr 26 07:06:20 2013
@@ -55,12 +55,7 @@ class ByteArrayWrapper implements Serial
}
public boolean equals(Object o) {
- if (!(o instanceof ByteArrayWrapper))
- return false;
-
- if (o == null)
- return false;
-
+ if (!(o instanceof ByteArrayWrapper)) return false;
final byte[] ouuid = ((ByteArrayWrapper)o).uuid;
return Arrays.equals(uuid, ouuid);
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/reggie/RegistrarImpl.java Fri Apr 26 07:06:20 2013
@@ -4784,10 +4784,10 @@ class RegistrarImpl implements Registrar
config, COMPONENT, "taskManager", TaskManager.class,
new TaskManager(50, 1000 * 15, 1.0F));
this.unexportTimeout = Config.getLongEntry(
- config, COMPONENT, "unexportTimeout", unexportTimeout,
+ config, COMPONENT, "unexportTimeout", 20000L,
0, Long.MAX_VALUE);
this.unexportWait = Config.getLongEntry(
- config, COMPONENT, "unexportWait", unexportWait,
+ config, COMPONENT, "unexportWait", 10000L,
0, Long.MAX_VALUE);
try {
unicastDiscoveryHost = (String) Config.getNonNullEntry(
Modified: river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/com/sun/jini/thread/ThreadPool.java Fri Apr 26 07:06:20 2013
@@ -21,8 +21,11 @@ package com.sun.jini.thread;
import com.sun.jini.action.GetLongAction;
import java.security.AccessController;
import java.util.Queue;
+import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ConcurrentLinkedQueue;
+import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@@ -75,49 +78,78 @@ final class ThreadPool implements Execut
/** thread group that this pool's threads execute in */
private final ThreadGroup threadGroup;
- /** Lock used to wake idle threads and synchronize writes to idleThreads */
- private final Lock lock;
- private final Condition wakeup;
-
- /** threads definitely available to take new tasks */
- private volatile int idleThreads;
-
/** queues of tasks to execute */
- private final Queue<Runnable> queue;
+ private final BlockingQueue<Runnable> queue;
+
+ /**
+ * This Executor is used by JERI (and other Jini implementation classes)
+ * to delegate tasks to, the intent is to hand off to a new thread
+ * immediately, however:
+ *
+ * 1. When ThreadPool creates threads too aggressively, stress tests in the
+ * qa suite create too many threads and hangs because tasks that need to
+ * respond within a required time cannot.
+ *
+ * 2. Conversely when thread creation takes too long, Javaspace tests that
+ * rely on event propagation to cancel a LeasedResource find that lease still
+ * available after lease expiry.
+ *
+ * ThreadPool must degrade gracefully when a system is under significant
+ * load, but it must also execute tasks as soon as possible.
+ *
+ * To address these issues, a SynchronousQueue has been selected, it has
+ * no storage capacity, it hands tasks directly from the calling thread to
+ * the task thread. Consider TransferBlockingQueue when Java 6 is no
+ * longer supported.
+ *
+ * Pool threads block waiting until a task is available or idleTimeout
+ * occurs after which the pool thread dies, client threads block waiting
+ * until a task thread is available, or after an computed timeout elapses,
+ * creates a new thread to execute the task.
+ *
+ * ThreadGroup is a construct originally intended for applet isolation,
+ * however it was never really successful, AccessControlContext
+ * is a much more effective way of controlling privilege.
+ *
+ * We should change this to ensure that each task is executed in the
+ * AccessControlContext of the calling thread, to avoid privilege escalation.
+ */
+ private final AtomicInteger threadCount;
+ private final int delayFactor;
+ private static final int numberOfCores = Runtime.getRuntime().availableProcessors();
+
+ ThreadPool(ThreadGroup threadGroup){
+ this(threadGroup, 10);
+ }
/**
* Creates a new thread group that executes tasks in threads of
* the given thread group.
*/
- ThreadPool(ThreadGroup threadGroup) {
+ ThreadPool(ThreadGroup threadGroup, int delayFactor) {
this.threadGroup = threadGroup;
- idleThreads = 0;
- queue = new ConcurrentLinkedQueue<Runnable>(); //Non blocking queue.
- lock = new ReentrantLock();
- wakeup = lock.newCondition();
+ queue = new SynchronousQueue<Runnable>(); //Non blocking queue.
+ threadCount = new AtomicInteger();
+ this.delayFactor = delayFactor;
}
// This method must not block - Executor
public void execute(Runnable runnable, String name) {
Runnable task = new Task(runnable, name);
- if (idleThreads < 3){ // create a new thread, non blocking approximate
- Thread t = AccessController.doPrivileged(
- new NewThreadAction(threadGroup, new Worker(task), name, true));
- t.start();
- } else {
- boolean accepted = queue.offer(task); //non blocking.
- if (accepted) {
- lock.lock(); // blocking.
- try {
- wakeup.signal();
- } finally {
- lock.unlock();
- }
- } else { // Should never happen.
+ boolean accepted = false;
+ try {
+ accepted = queue.offer(task, 1000 * delayFactor* (threadCount.get()/ numberOfCores), TimeUnit.MICROSECONDS);
+ } catch (InterruptedException ex) {
+ Logger.getLogger(ThreadPool.class.getName()).log(Level.SEVERE, "Calling thread interrupted", ex);
+ // restore interrupt.
+ Thread.currentThread().interrupt();
+ } finally {
+ if (!accepted){
Thread t = AccessController.doPrivileged(
- new NewThreadAction(threadGroup, new Worker(task), name, true));
- t.start();
- }
+ new NewThreadAction(threadGroup, new Worker(task), name, true));
+ t.start();
+ threadCount.incrementAndGet();
+ }
}
}
@@ -146,10 +178,14 @@ final class ThreadPool implements Execut
if (t instanceof RuntimeException){
if (t instanceof SecurityException){
// ignore it will be logged.
+ } else if (t instanceof InterruptedException) {
+ // If we've caught an interrupt, we need to make sure it's
+ // set so the while loop stops.
+ Thread.currentThread().interrupt();
} else {
// Ignorance of RuntimeException is generally bad, bail out.
throw (RuntimeException) t;
- }
+ }
}
}
}
@@ -172,36 +208,31 @@ final class ThreadPool implements Execut
}
public void run() {
- Runnable task = first;
- first = null; // For garbage collection.
- task.run();
- Thread thread = Thread.currentThread();
- while (!thread.isInterrupted()) {
- /*
- * REMIND: What if the task changed this thread's
- * priority? or context class loader?
- */
- for ( task = queue.poll(); task != null; task = queue.poll()){
- // Keep executing while tasks are available.
- thread.setName(NewThreadAction.NAME_PREFIX + task);
- task.run();
+ try {
+ Runnable task = first;
+ first = null; // For garbage collection.
+ task.run();
+ Thread thread = Thread.currentThread();
+ while (!thread.isInterrupted()) {
+ /*
+ * REMIND: What if the task changed this thread's
+ * priority? or context class loader?
+ *
+ * thread.setName is not thread safe.
+ */
+ try {
+ task = queue.poll(idleTimeout, TimeUnit.MILLISECONDS);
+// thread.setName(NewThreadAction.NAME_PREFIX + task);
+ task.run();
+// thread.setName(NewThreadAction.NAME_PREFIX + "Idle");
+ } catch (InterruptedException e){
+ thread.interrupt();
+ break;
+ }
}
- // queue is empty;
- thread.setName(NewThreadAction.NAME_PREFIX + "Idle");
- lock.lock();
- try {
- idleThreads++;
- wakeup.await(idleTimeout, TimeUnit.MILLISECONDS);// releases lock and obtains when woken.
- // Allow thread to expire if queue empty after waking.
- if (queue.peek() == null) thread.interrupt();
- } catch (InterruptedException ex) {
- // Interrupt thread, another thread can pick up tasks.
- thread.interrupt();
- } finally {
- idleThreads--;
- lock.unlock();
- }
- }
- }
- }
- }
+ } finally {
+ threadCount.decrementAndGet();
+ }
+ }
+ }
+}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/Lease.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/Lease.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/Lease.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/Lease.java Fri Apr 26 07:06:20 2013
@@ -40,14 +40,14 @@ public interface Lease {
/**
* Used to request a lease that never expires.
*/
- long FOREVER = Long.MAX_VALUE;
+ final long FOREVER = Long.MAX_VALUE;
/**
* Used by the requestor to indicate that there is no particular lease
* time desired, and that the grantor of the lease should supply a time
* that is most convenient for the grantor.
*/
- long ANY = -1;
+ final long ANY = -1;
/**
* The serialized form of the lease will convert the time of lease
@@ -138,7 +138,7 @@ public interface Lease {
*
* @return the created <tt>LeaseMap</tt> object
*/
- LeaseMap createLeaseMap(long duration);
+ LeaseMap<Lease, Long> createLeaseMap(long duration);
/**
* Returns a boolean indicating whether or not the lease given as a
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/LeaseMap.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/LeaseMap.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/LeaseMap.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/core/lease/LeaseMap.java Fri Apr 26 07:06:20 2013
@@ -30,7 +30,7 @@ import java.rmi.RemoteException;
*
* @since 1.0
*/
-public interface LeaseMap extends java.util.Map {
+public interface LeaseMap<Lease, Long> extends java.util.Map<Lease, Long> {
/**
* Returns true if the given object is a Lease which can be renewed
* and cancelled in a batch with other leases in the map. Whether
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/LookupLocatorDiscovery.java Fri Apr 26 07:06:20 2013
@@ -1572,7 +1572,9 @@ public class LookupLocatorDiscovery impl
}
);
} else {
- discoverLocators(locators);
+ synchronized (LookupLocatorDiscovery.this){
+ discoverLocators(locators);
+ }
}
}
}
Modified: river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/JoinManager.java
URL: http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/JoinManager.java?rev=1476080&r1=1476079&r2=1476080&view=diff
==============================================================================
--- river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/JoinManager.java (original)
+++ river/jtsk/skunk/qa_refactor/trunk/src/net/jini/lookup/JoinManager.java Fri Apr 26 07:06:20 2013
@@ -1339,7 +1339,7 @@ public class JoinManager {
* For more information, refer to Bug 4490355.
*/
public void fail(Throwable e) {
- synchronized(this) {
+ synchronized(JoinManager.this) {
if(bTerminated) {
return;
} else {
@@ -1355,7 +1355,7 @@ public class JoinManager {
e1);
}
}//endif
- }//end sync(this)
+ }//end sync(JoinManager.this)
}//end ProxyReg.fail
/** Returns true if the both objects' associated proxies are equal. */