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();
