Author: peter_firmstone
Date: Mon Dec 23 11:52:40 2013
New Revision: 1553097
URL: http://svn.apache.org/r1553097
Log:
After considerable testing using a multi threaded Executor and Runnable tasks
to CAS an AtomicLong to generate 100% cpu load, no data races were found, it is
suspected that Object.wait is subject to spurious wake-up's on some platforms
when they are not contained within a loop that checks the present condition and
this is causing the test failures:
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/qa/harness/QAConfig.java
Mon Dec 23 11:52:40 2013
@@ -2213,7 +2213,7 @@ public class QAConfig implements Seriali
if (fqHostName.contains(nxdomain)) return hostName;
return fqHostName;
} catch (UnknownHostException ignore) {
- logger.severe("InetAddress threw unknown host exception: " +
hostName);
+ logger.info("InetAddress threw unknown host exception: " +
hostName);
}
return hostName;
}
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/norm/LeaseExpirationTest.java
Mon Dec 23 11:52:40 2013
@@ -360,12 +360,13 @@ public class LeaseExpirationTest extends
if (count != 0)
return false;
- final long now = System.currentTimeMillis();
+ long now = System.currentTimeMillis();
synchronized (this) {
- if (setExpiration> now) {
+ while (setExpiration> now) {
logger.log(Level.INFO, "Waiting for " + (setExpiration -
now)
+ " ms for set lease to expire");
wait(setExpiration - now);
+ now = System.currentTimeMillis();
}
}
return true;
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/impl/outrigger/notify/ThrowRuntimeException.java
Mon Dec 23 11:52:40 2013
@@ -196,14 +196,16 @@ public class ThrowRuntimeException exten
*/
long listener1Rcvd;
synchronized (listener1) {
-
+ long duration = wait;
+ long finish = System.currentTimeMillis() + duration;
+
// Did it already happen?
listener1Rcvd = listener1.lastEvent();
- if (listener1Rcvd< ev1) {
+ while (listener1Rcvd< ev1) {
// No, wait
- listener1.wait(wait);
+ listener1.wait(duration);
listener1Rcvd = listener1.lastEvent();
if (listener1Rcvd< 0) {
@@ -214,6 +216,8 @@ public class ThrowRuntimeException exten
"First listener received too many events");
}
logger.log(Level.INFO, "Received correct event");
+ duration = finish - System.currentTimeMillis();
+ if (duration<= 0) break;
}
}
@@ -254,12 +258,14 @@ public class ThrowRuntimeException exten
// Wait for event and check to see if it is the right one
synchronized (listener2) {
-
+ long duration = wait;
+ long finish = System.currentTimeMillis() + duration;
+
// Did it already happen?
- if (listener2.lastEvent()< ev1) {
+ while (listener2.lastEvent()< ev1) {
// No wait
- listener2.wait(wait);
+ listener2.wait(duration);
if (listener2.lastEvent()< 0) {
throw new TestException(
@@ -268,6 +274,8 @@ public class ThrowRuntimeException exten
throw new TestException(
"Second listener received too many events");
}
+ duration = finish - System.currentTimeMillis();
+ if (duration<= 0) break;
}
}
logger.log(Level.INFO, "2nd handler received correct event");
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/share/BaseQATest.java
Mon Dec 23 11:52:40 2013
@@ -1638,7 +1638,13 @@ abstract public class BaseQATest extends
}//endif
}//endif(nEventsReceived == nEventsExpected)
try {
- listener.wait(1000); // Wait for discovery for up to 1000
ms.
+ long startTime = System.currentTimeMillis();
+ long finishTime = startTime + 1000;
+ long remain = 1000;
+ do {
+ listener.wait(remain); // Wait for discovery for 1000
ms.
+ remain = finishTime - System.currentTimeMillis();
+ } while (remain> 0); //To avoid spurious wakeup
} catch (InterruptedException ex) {
throw new TestException("Interrupted while waiting for
discovery", ex);
}
@@ -1794,7 +1800,13 @@ abstract public class BaseQATest extends
}//endif
}//endif(nEventsReceived == nEventsExpected)
try {
- listener.wait(1000);
+ long startTime = System.currentTimeMillis();
+ long finishTime = startTime + 1000;
+ long remain = 1000;
+ do {
+ listener.wait(remain); // Wait for discovery for 1000
ms.
+ remain = finishTime - System.currentTimeMillis();
+ } while (remain> 0); //To avoid spurious wakeup
} catch (InterruptedException ex) {
throw new TestException("Test interrupted while waiting for
discard", ex);
}
@@ -1948,10 +1960,17 @@ abstract public class BaseQATest extends
}//endif
}//endif(nEventsReceived == nEventsExpected)
try {
- listener.wait(1000);
+ long startTime = System.currentTimeMillis();
+ long finishTime = startTime + 1000;
+ long remain = 1000;
+ do {
+ listener.wait(remain); // Wait for discovery for 1000
ms.
+ remain = finishTime - System.currentTimeMillis();
+ } while (remain> 0); //To avoid spurious wakeup
} catch (InterruptedException ex) {
throw new TestException("Test interrupted while waiting for
change event", ex);
}
+ // can't do this anymore because we need to release sync first.
//DiscoveryServiceUtil.delayMS(1000);
showCompInfo = false;//display comparison info only when i = 0
}//end loop(iLoop)
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/ClientFlowControlTest.java
Mon Dec 23 11:52:40 2013
@@ -171,7 +171,12 @@ public class ClientFlowControlTest exten
private Socket getConnection() throws InterruptedException {
if (s==null) {
synchronized (lock) {
- lock.wait(2 * getTimeout());
+ long duration = 2 * getTimeout();
+ long finish = System.currentTimeMillis() + duration;
+ do {
+ lock.wait(duration);
+ duration = finish - System.currentTimeMillis();
+ } while ( s == null&& duration> 0);
}
}
Socket temp = s;
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/CloseTest.java
Mon Dec 23 11:52:40 2013
@@ -158,7 +158,12 @@ public class CloseTest extends AbstractM
private Socket getConnection() throws InterruptedException {
if (s==null) {
synchronized (lock) {
- lock.wait(2 * getTimeout());
+ long duration = 2 * getTimeout();
+ long finish = System.currentTimeMillis() + duration;
+ do {
+ lock.wait(duration);
+ duration = finish - System.currentTimeMillis();
+ } while ( s == null&& duration> 0);
}
}
Socket temp = s;
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/jeri/mux/MuxClientTest.java
Mon Dec 23 11:52:40 2013
@@ -218,7 +218,12 @@ public class MuxClientTest extends Abstr
private Socket getConnection() throws InterruptedException {
if (s==null) {
synchronized (lock) {
- lock.wait(2 * getTimeout());
+ long duration = 2 * getTimeout();
+ long finish = System.currentTimeMillis() + duration;
+ do {
+ lock.wait(duration);
+ duration = finish - System.currentTimeMillis();
+ } while ( s == null&& duration> 0);
}
}
Socket temp = s;
Modified:
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/qa/src/com/sun/jini/test/spec/renewalmanager/EventTest.java
Mon Dec 23 11:52:40 2013
@@ -356,7 +356,11 @@ public class EventTest extends QATestEnv
synchronized (this) {
if (null == (failedComponet = hadEarlyFailure(leases))) {
// let run() propogate InterruptedException
- wait(waitUntil - System.currentTimeMillis());
+ long duration = waitUntil - System.currentTimeMillis();
+ do {
+ wait(duration);
+ duration = waitUntil - System.currentTimeMillis();
+ } while (duration> 0);
failedComponet = hadEarlyFailure(leases);
}
}
Modified:
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
URL:
http://svn.apache.org/viewvc/river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java?rev=1553097&r1=1553096&r2=1553097&view=diff
==============================================================================
---
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
(original)
+++
river/jtsk/skunk/qa_refactor/trunk/src/net/jini/discovery/AbstractLookupDiscovery.java
Mon Dec 23 11:52:40 2013
@@ -816,11 +816,12 @@ abstract class AbstractLookupDiscovery i
sleep(multicastAnnouncementInterval);
long curTime = System.currentTimeMillis();
synchronized (registrars) {
- /* can't modify regInfo while iterating over it,
- * so clone it
+ /* Previously regInfo was cloned to avoid synchronizing
+ * this was changed to a simple synchronized block
during code
+ * auditing as it appeared like an unnecessary
+ * performance optimisation that risked atomicity.
*/
- HashMap<ServiceID,AnnouncementInfo> regInfoClone =
(HashMap<ServiceID,AnnouncementInfo>) regInfo.clone();
- Set<Map.Entry<ServiceID,AnnouncementInfo>> eSet =
regInfoClone.entrySet();
+ Set<Map.Entry<ServiceID,AnnouncementInfo>> eSet =
regInfo.entrySet();
for(Iterator<Map.Entry<ServiceID,AnnouncementInfo>>
itr = eSet.iterator(); itr.hasNext(); ) {
Map.Entry<ServiceID,AnnouncementInfo> pair =
itr.next();
ServiceID srvcID = pair.getKey();